[
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://aquila.network\">\n    <img\n      src=\"https://user-images.githubusercontent.com/19545678/133918727-5a37c6be-676f-427b-8c86-dd50f58d1287.png\"\n      alt=\"Aquila Network Logo\"\n      height=\"64\"\n    />\n  </a>\n  <br />\n  <p>\n    <h3>\n      <b>\n        Aquila DB\n      </b>\n    </h3>\n  </p>\n  <p>\n    <b>\n      Easy to use Neural Search Engine\n    </b>\n  </p>\n  <br/>\n</div>\n\n**[Aquila DB](https://github.com/Aquila-Network/AquilaDB)** is a Neural search engine. In other words, it is a database to index **Latent Vectors** generated by ML models along with **JSON Metadata** to perform **k-NN** retrieval. It is dead simple to set up, language-agnostic, and drop in addition to your Machine Learning Applications. Aquila DB, as of current features is a ready solution for Machine Learning engineers and Data scientists to build **[Neural Information Retrieval](https://www.microsoft.com/en-us/research/uploads/prod/2017/06/INR-061-Mitra-neuralir-intro.pdf)** applications out of the box with minimal dependencies.\n\n> This project is still in alpha version & we're already using it in production to power semantic search at https://aquila.network. \n\n\nWanna support this project? Yes, we love getting a **star** ⭐ and **shout-out** 🗣️ 🤗\n\nJoin [Community chat and get support: ![discord chatroom for discussions](https://www.freeiconspng.com/minicovers/flat-discord-material-like-icon--2.png)](https://discord.gg/5YP7zHS)\n\n\n# Who is this for\n\n* If you are working on a data science project and need to store a hell of a lot of data and retrieve similar data based on some feature vector, this will be a useful tool to you, with extra benefits a real world web application needs.\n* Are you dealing with a lot of images and related metadata? Want to find similar ones? You are at the right place.\n* If you are looking for a document database, this is not the right place for you.\n\n# Technology\nAquila DB powers search features of Aquila Network. Here is where Aquila DB fits in the entire ecosystem:\n<div align=\"center\">\n  <img\n    src=\"https://user-images.githubusercontent.com/19545678/133918438-997af8ec-67ef-4f7c-95ab-16d2f28e79e3.png\"\n    alt=\"Aquila DB Architecture\"\n    height=\"400\"\n  />\n <br/>\n</div>\n\n\n\nIf you are serious and wanna dive down the rabbit hole, read our **[whitepapers](https://github.com/Aquila-Network/whitepaper)** and **[technical specifications](https://github.com/Aquila-Network/specs)** (being actively worked on). \n\n\n\n**As a side note**, everything in **[Aquila Network](https://github.com/Aquila-Network)** is defined by the specifications and a large chunk of our efforts goes into it. We also maintain quality implementations of those specifications with non-technical users in mind. This is to make sure that - Aquila Network is fully open, decentralized by design, and Fair. You can follow those specifications to implement your alternative software and still interact with the network without any restrictions.\n\n# Install\n### Debian\n\nRun `curl -s -L https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/install.sh | /bin/bash -s -- -d 1 `.\n\n### Docker\n\n**You need docker installed in your system**\n\nBuild image (lite): `docker build https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/Dockerfile -t aquiladb:local`\n\nBuild image (big data): `docker build https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/DockerfileBig -t aquiladb:localbg`\n\nRun image (to deploy Aquila DB lite): `docker run -p 5001:5001 -d aquiladb:local`\n\nRun image (to deploy Aquila DB big): `docker run -p 5001:5001 -d aquiladb:localbg`\n\n# Client SDKs\nWe currently have multiple client libraries in progress to abstract the communication between deployed Aquila DB and your applications.\n\n[Python](https://github.com/Aquila-Network/AquilaPy)\n\n[Node JS](https://github.com/Aquila-Network/AquilaJS)\n\n## Where to get private key (wallet key) for client authentication\nWhen you use a client library to authenticate with AquilaDB, you might need access the same private key (wallet key) used by AquilaDB. This key is located inside `/ossl/` directory within AquilaDB docker container (in your computer if you have installed AquilaDB directly without docker). To access the keys inside your AquilaDB container, follow below steps:\n\n* identify `CONTAINER ID` for the already running `aquiladb` docker instance:\n`docker ps`\n* take a copy of private keys from docker container to your host machine:\n`docker cp CONTAINER_ID:/ossl/ ./`\n* now you will see a new directory named `ossl` at your current location. Use the keys inside it.\n#### tips for advanced users\nIf your pipeline requires the private keys to be generated in advance, you can do it in your host machine and then mount it to the container's `/ossl/` directory. \n\nRun:\n```\nmkdir -p <host>/ossl/\nopenssl genrsa -passout pass:1234 -des3 -out <host>/ossl/private.pem 2048\nopenssl rsa -passin pass:1234 -in <host>/ossl/private.pem -outform PEM -pubout -out <host>/ossl/public.pem\nopenssl rsa -passin pass:1234 -in <host>/ossl/private.pem -out <host>/ossl/private_unencrypted.pem -outform PEM\n```\n\n# Progress\nThis project is still and will be under active development with intermediate production releases. It can either be used as a standalone database or as a participating node in Aquila Network. Please note, [Aquila Port](https://github.com/Aquila-Network/specs/blob/main/README.md#aquila-port) (peer-peer network layer for Aquila DB nodes) is also a work in progress. Currently, you need to deploy your custom models to feed vector embeddings to Aquila DB, until [Aquila Hub](https://github.com/Aquila-Network/specs/blob/main/README.md#aquila-hub) developments get started.\n\n# Contribute\nWe have [prepared a document](https://docs.google.com/document/d/1bT2_9FQIxQpx_rdYbkTukn_DJRi_haVK_ixTf8uTaDE/edit?usp=sharing) to get anyone interested to contribute, immediately started with Aquila DB.\nHere is our high-level [release roadmap](https://user-images.githubusercontent.com/19545678/62313851-5af82880-b4af-11e9-84f6-21e24bf46e8a.png).\n\n# Learn\n\nWe have started meeting developers and do small talks on Aquila DB. Here are the slides that we use on those occasions: http://bit.ly/AquilaDB-slides \n\n**Video:**\n\n[<img alt=\"introduction to Neural Information retrieval with AquilaDB\" src=\"http://img.youtube.com/vi/-VYpjpLXU5Q/0.jpg\" width=\"300\" />](http://www.youtube.com/watch?v=-VYpjpLXU5Q)\n\nAs of current AquilaDB release features, you can build **[Neural Information Retrieval](https://www.microsoft.com/en-us/research/uploads/prod/2017/06/INR-061-Mitra-neuralir-intro.pdf)** applications out of the box without any external dependencies. Here are some useful links to learn more about it and start building:\n\n* Microsoft published a paper and youtube video on this to onboard anyone interested: \n  * paper: https://www.microsoft.com/en-us/research/uploads/prod/2017/06/INR-061-Mitra-neuralir-intro.pdf\n  * video: https://www.youtube.com/watch?v=g1Pgo5yTIKg\n* Embeddings for Everything: Search in the Neural Network Era: https://www.youtube.com/watch?v=JGHVJXP9NHw\n* Autoencoders are one such deep learning algorithms that will help you to build semantic vectors - foundation for Neural Information retrieval. Here are some links to Autoencoders based IR:\n  * go to chapter 15 in this link: https://www.cs.toronto.edu/~hinton/coursera_lectures.html\n  * https://www.coursera.org/lecture/ml-foundations/examples-of-document-retrieval-in-action-CW25H\n  * https://www.coursera.org/lecture/intro-to-deep-learning/autoencoders-101-QqBOa\n* Note that, the idea of information retrieval applies not only to text data but for any data. All you need to do is, encode any source datatype to a dense vector with deep neural networks.\n\n<br/><br/>\n<h1 align=\"center\">Our Sponsors</h1>\n<p align=\"center\"><b></b></p>\n\n<br/>\n\n> email us to sponsor this project [adbadmin@protonmail.ch](mailto:adbadmin@protonmail.ch).\n\n<br/><br/>\n\n# Citing Aquila DB\nIf you use Aquila DB in an academic paper, we would 😍 to be cited. Here are the two ways of citing Aquila DB:\n```\n\\footnote{https://github.com/Aquila-Network/AquilaDB}\n```\n```\n@misc{AquilaNetwork2019AquilaDB,\n  title={AquilaDB: Neural Search Engine},\n  author={Jubin Jose, Nibin Peter},\n  howpublished={\\url{https://github.com/Aquila-Network/AquilaDB}},\n  year={2019}\n}\n```\n\n# License\n\nApache License 2.0 [license file](https://github.com/Aquila-Network/AquilaDB/blob/master/LICENSE)\n\ncreated by ❤️ with a-mma (a_മ്മ)\n"
  },
  {
    "path": "aquila/encoder/CODE_OF_CONDUCT.md",
    "content": "# AquilaDB Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at humans@aquiladb.xyz. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "aquila/encoder/Dockerfile",
    "content": "# start a new build stage\nFROM ubuntu:latest as builder\n\n# set work directory\nENV ROOT_DIR /home/root\nWORKDIR $ROOT_DIR\n\n# preperations\nENV PATH=\"$ROOT_DIR/env/bin:$PATH\"\n\nSHELL [\"/bin/bash\", \"-o\", \"pipefail\", \"-c\"]\n\nRUN apt update && apt install -y git nano python3.8 python3-pip libssl-dev && \\\n    pip3 install virtualenv\n\nRUN cd $ROOT_DIR && \\\n    mkdir -p ahub && \\\n    cd ahub && \\\n    git clone https://github.com/Aquila-Network/AquilaHub.git . && \\\n    virtualenv $ROOT_DIR/env && \\\n    source $ROOT_DIR/env/bin/activate && \\\n    cd src && pip3 install -r requirements.txt\n\nRUN mkdir -p /ossl/ && \\\n    openssl genrsa -passout pass:1234 -des3 -out /ossl/private.pem 2048 && \\\n    openssl rsa -passin pass:1234 -in /ossl/private.pem -outform PEM -pubout -out /ossl/public.pem && \\\n    openssl rsa -passin pass:1234 -in /ossl/private.pem -out /ossl/private_unencrypted.pem -outform PEM\n\n# install and start demon\nRUN mkdir -p /data && \\\n    printf \"#!/bin/bash\\nsource env/bin/activate && cd ahub/src && \\\n    python3 index.py\" > /bin/init.sh && chmod +x /bin/init.sh\n\n# expose port\nEXPOSE 5002\n\nENTRYPOINT [\"init.sh\"]"
  },
  {
    "path": "aquila/encoder/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 percent (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": "aquila/encoder/README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://aquila.network\">\n    <img\n      src=\"https://user-images.githubusercontent.com/19545678/133918727-5a37c6be-676f-427b-8c86-dd50f58d1287.png\"\n      alt=\"Aquila Network Logo\"\n      height=\"64\"\n    />\n  </a>\n  <br />\n  <p>\n    <h3>\n      <b>\n        Aquila Hub\n      </b>\n    </h3>\n  </p>\n  <p>\n    <b>\n      Load and serve Neural Encoder Models\n    </b>\n  </p>\n  <br/>\n</div>\n\nLoad and serve ML models to compress data into latent vectors. To be used with Aquila DB.\n\n# Technology\n\nAquila Hub automates the process of encoding information with the help of ML models. Here is where Aquila Hub fits in the entire ecosystem:\n<div align=\"center\">\n  <img\n    src=\"https://user-images.githubusercontent.com/19545678/133918439-e08f314b-ad15-441e-a605-2fd2ec37a509.png\"\n    alt=\"Aquila Hub Architecture\"\n    height=\"400\"\n  />\n <br/>\n</div>\n\n# Install\n### Debian\n\nRun `curl -s -L https://raw.githubusercontent.com/Aquila-Network/AquilaHub/main/install.sh | /bin/bash -s -- -d 1 `.\n\n### Docker\n\n**You need docker installed in your system**\n\nBuild image (one time process): `docker build https://raw.githubusercontent.com/Aquila-Network/AquilaHub/main/Dockerfile -t aquilahub:local`\n\nRun image (to deploy Aquila DB): `docker run -p 5002:5002 -d aquilahub:local`\n"
  },
  {
    "path": "aquila/encoder/authentication.py",
    "content": "from utils import cryptops\n\nimport os\n\npub_key = cryptops.read_public_key(os.environ[\"AUTH_KEY_FILE\"])\n\ndef check (json_data, signature):\n    return cryptops.verify_signature(json_data, pub_key, signature)"
  },
  {
    "path": "aquila/encoder/config.yml",
    "content": "auth:\n  pubkey: \"/ossl/public.pem\"\nipfs:\n  gateway: \"http://127.0.0.1:8080\"\n"
  },
  {
    "path": "aquila/encoder/encoder.py",
    "content": "import logging\n\nimport fasttext\nfrom utils import downloader\nimport hashlib\nimport base58\nimport json\n\nfrom sentence_transformers import SentenceTransformer\n\nimport os\n\n# define constants\nMODEL_FASTTEXT = \"ftxt\"\nMODEL_S_TRANSFORMER = \"strn\"\nPREDICT_BATCH_SIZE = 1000\n\n# Maintain a model directory\ndata_dir = os.environ[\"DATA_STORE_LOCATION\"]\nmodel_dir = data_dir + \"models/\"\nmodel_dict = {}\n\ndef get_url (schema):\n    \"\"\"\n    Get model url from a schema\n    \"\"\"\n    \n    if schema.get(\"encoder\") != None:\n        return schema[\"encoder\"]\n    else:\n        return None\n\ndef get_url_hash (url):\n    hash_ = hashlib.sha256(url.encode('utf-8'))\n    b58c_ = base58.b58encode(hash_.digest())\n    return b58c_.decode('utf-8')\n\ndef download_model (url, directory, file_name):\n    \"\"\"\n    Download a model from a URL\n    \"\"\"\n\n    # handle fasttext models from url or IPFS\n    if url.split(\":\")[0] == MODEL_FASTTEXT:\n        url = \":\".join(url.split(\":\")[1:])\n        \n        if url.split(\":\")[0] == \"http\" or url.split(\":\")[0] == \"https\":\n            return MODEL_FASTTEXT, downloader.http_download(url, directory, file_name+\".bin\")\n\n        elif url.split(\":\")[0] == \"ipfs\":\n            return MODEL_FASTTEXT, downloader.ipfs_download(url, directory, file_name+\".bin\")\n    elif url.split(\":\")[0] == MODEL_S_TRANSFORMER:\n        url = \":\".join(url.split(\":\")[1:])\n        return MODEL_S_TRANSFORMER, url\n    else:\n        logging.error(\"Invalid encoder specified in schema definition.\")\n        return None, \"\"\n\ndef memload_model (model_type, model_filename):\n    \"\"\"\n    Load a model from disk\n    \"\"\"\n\n    if model_type == MODEL_FASTTEXT:\n        if model_filename:\n            logging.debug(\"loading fasttext model into memory..\")\n            return model_type, fasttext.load_model(model_filename)\n        else:\n            return None, None\n    elif model_type == MODEL_S_TRANSFORMER:\n        if model_filename:\n            logging.debug(\"loading STransformer model into memory..\")\n            return model_type, SentenceTransformer(model_filename)\n        else:\n            return None, None\n    else:\n        return None, None\n\nclass EncodeRequest ():\n    def __init__(self, id_in, text_in):\n        self.id = id_in\n        self.text = text_in\n\nclass Encoder ():\n    def __init__(self, encoder_name_in, request_queue_in):\n        self.encoder_name = get_url_hash(encoder_name_in)\n        # to handle requests\n        self.request_queue = request_queue_in\n        self.request_id_counter = 0\n        self.request_id_counter_max = 10000\n        # to handle responses\n        self.response_queue = [None] * self.request_id_counter_max\n\n    def __del__(self):\n        logging.debug(\"killed encoder for database\")\n\n    def count_request_id (self):\n        ret_ = self.request_id_counter\n        self.request_id_counter = (self.request_id_counter + 1) % self.request_id_counter_max\n        return ret_\n\n    def preload_model (self, json_schema, database_name):\n        \"\"\"\n        Download a model and load it into memory\n        \"\"\"\n\n        # prefill model & hash dictionary\n        global model_dict\n        \n        try:\n            # load model if not done already\n            if not model_dict.get(self.encoder_name):\n                model_type_, model_file_loc_ = download_model(get_url(json_schema), model_dir, self.encoder_name)\n                # download success\n                if model_file_loc_ != None:\n                    model_dict[self.encoder_name] = {}\n                    # load into memory\n                    model_dict[self.encoder_name][\"type\"], model_dict[self.encoder_name][\"model\"] = memload_model(model_type_, model_file_loc_)\n                    # memory loading failed\n                    if model_dict[self.encoder_name][\"type\"] == None:\n                        logging.error(\"Memory loading of model failed\")\n                        return False\n                else:\n                    return False\n\n                if model_dict[self.encoder_name].get(\"model\"):\n                    logging.debug(\"Model loaded for database: \"+database_name)\n                    return True\n                else:\n                    logging.error(\"Model loading failed for database: \"+database_name)\n                    # reset DB - hash map\n                    del model_dict[self.encoder_name]\n                    return False\n            else:\n                return True\n\n        except Exception as e:\n            logging.error(e)\n            return False\n\n    async def enqueue_compress_data (self, texts):\n        \"\"\"\n        Add to request queue for compression \n        \"\"\"\n        request_ = EncodeRequest(self.count_request_id(), texts)\n\n        await self.request_queue.put(request_)\n\n        return request_.id\n\n    async def process_queue (self):\n        \"\"\"\n        Load an already existing model, pop request queue,\n        compress information, push to response queue\n        \"\"\"\n\n        request_data = []\n        request_metadata = []\n        max_batch_len = PREDICT_BATCH_SIZE # model's batching capacity\n        # create batch from req. queue\n        while(not self.request_queue.empty()):\n            # get an item from queue\n            section_ = await self.request_queue.get()\n            request_data += section_.text\n            request_metadata.append( (section_.id, len(section_.text)) )\n            # check max. batch length achieved\n            if len(request_data) > max_batch_len:\n                break\n\n\n        # prefill model & hash dictionary\n        global model_dict\n\n        # model_dict[self.encoder_name]\n        if not model_dict.get(self.encoder_name):\n            # try dynamic loading of model\n            try:\n                model_dict[self.encoder_name] = {}\n                model_dict[self.encoder_name][\"type\"], model_dict[self.encoder_name][\"model\"] = memload_model(MODEL_FASTTEXT, model_dir + self.encoder_name + \".bin\")\n            except Exception as e:\n                logging.error(\"Model not pre-loaded for database.\")\n                logging.error(e)\n                return []\n        \n        result = []\n        try:\n            # fasttext model prediction\n            if model_dict[self.encoder_name][\"type\"] == MODEL_FASTTEXT:\n                result = []\n                # fasttext doesn't take in batch; so, loop it.\n                for line_ in request_data:\n                    result.append(model_dict[self.encoder_name][\"model\"].get_sentence_vector(line_).tolist())\n            # stransformer model prediction\n            if model_dict[self.encoder_name][\"type\"] == MODEL_S_TRANSFORMER:\n                result = model_dict[self.encoder_name][\"model\"].encode(request_data).tolist()\n\n        except Exception as e:\n            logging.error(e)\n            logging.error(\"Model prediction error for database.\")\n        \n        # add results to response queue\n        self.response_queue[request_metadata[0][0]] = result[0:request_metadata[0][1]]\n        old_metadata = request_metadata[0]\n        for metadata_ in request_metadata[1:]:\n            self.response_queue[metadata_[0]] = result[old_metadata[1]:old_metadata[1]+metadata_[1]]\n            old_metadata = metadata_\n"
  },
  {
    "path": "aquila/encoder/index.py",
    "content": "import logging\n\nfrom quart import Quart\nfrom quart import request\n\nfrom functools import wraps\nimport asyncio\n\nfrom utils import config\nimport authentication\nimport manager as man_\n\napp = Quart(__name__, instance_relative_config=True)\n\n# Server starter\ndef quartserver ():\n    \"\"\"\n    start server\n    \"\"\"\n    app.run(host='0.0.0.0', port=5002, debug=False)\n\n# Add authentication\ndef authenticate ():\n    def decorator (f):\n        @wraps(f)\n        async def wrapper (*args, **kwargs):\n            params = await extract_request_params(request)\n\n            if not params or not \"data\" in params or not \"signature\" in params:\n                return \"Unauthorised access\", 401\n\n            if not authentication.check(params[\"data\"], params[\"signature\"]):\n                return \"Unauthorised access\", 401\n\n            return await f(*args, **kwargs)\n\n        return wrapper\n    return decorator\n\nasync def extract_request_params (request):\n    if not request.is_json:\n        logging.error(\"Cannot parse request parameters\")\n\n        # request is invalid\n        return {}\n\n    # Extract JSON data\n    data_ = await request.get_json()\n\n    return data_\n\n@app.route(\"/\", methods=['GET'])\ndef info ():\n    \"\"\"\n    Check server status\n    \"\"\"\n\n    # Build response\n    return {\n            \"success\": True,\n            \"message\": \"AquilaHub is running healthy\"\n        }, 200\n\n@app.route(\"/prepare\", methods=['POST'])\n@authenticate()\nasync def prepare_model ():\n    \"\"\"\n    Preload and prepare model from schema definition\n    \"\"\"\n\n    # get parameters\n    params = (await extract_request_params(request)).get(\"data\")\n\n    if not params:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    if \"schema\" in params:\n        database_name = app.manager.preload_model(params.get(\"schema\"))\n\n        # Build response\n        if database_name:\n            return {\n                    \"success\": True,\n                    \"databaseName\": database_name\n                }, 200\n        else:\n            return {\n                    \"success\": False,\n                    \"message\": \"Invalid schema definition\"\n                }, 400\n    else:\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n@app.route(\"/compress\", methods=['POST'])\nasync def compress_data ():\n    \"\"\"\n    generate embeddings for an input data\n    \"\"\"\n\n    # get parameters\n    params = (await extract_request_params(request)).get(\"data\")\n\n    if not params:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    if \"text\" in params and \"databaseName\" in params:\n        vectors = await app.manager.compress_data(params.get(\"databaseName\"), params.get(\"text\"))\n\n        # Build response\n        if vectors:\n            return {\n                    \"success\": True,\n                    \"vectors\": vectors\n                }, 200\n        else:\n            return {\n                    \"success\": False,\n                    \"message\": \"Database not found\"\n                }, 400\n    else:\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n@app.before_serving\nasync def init_variables():\n    app.manager = man_.Manager()\n    # prepare HUB from backup\n    try:\n        app.manager.prepare_hub()\n    except Exception as e:\n        logging.error(\"Backup restore failed\")\n        logging.error(e)\n    # initialize background task controller\n    app.manager.bg_task_active = True\n\n@app.before_serving\nasync def init_tasks():\n    # initialize background task\n    app.manager.background_task = asyncio.ensure_future(app.manager.background_task())\n    # app.add_background_task(background_task)\n\n@app.after_serving\nasync def shutdown():\n    # shutdown background task\n    app.manager.bg_task_active = False\n    app.manager.background_task.cancel()\n\nif __name__ == \"__main__\":\n    quartserver()"
  },
  {
    "path": "aquila/encoder/ipfs.service",
    "content": "[Unit]\nDescription=IPFS daemon\nAfter=network.target\n\n[Service]\n### custom ipfs datastore location\n# Environment=IPFS_PATH=/path/to/your/ipfs/datastore\nExecStart=/usr/local/bin/ipfs daemon\nRestart=on-failure\n\n[Install]\nWantedBy=default.target\n"
  },
  {
    "path": "aquila/encoder/manager.py",
    "content": "import logging\nlogging.basicConfig()\nlogging.getLogger().setLevel(logging.DEBUG)\n\nimport asyncio\nimport os\nimport json\nimport copy\n\nfrom utils import CID, schema\n\nimport encoder as enc_\n\nSLEEP_PROTECTION = 0.0001\n\ndef get_database_name (schema_in):\n    \"\"\"\n    Get databse name from schema\n    \"\"\"\n\n    database_name = None\n    try:\n        schema_def = schema.generate_schema(schema_in)\n        database_name = CID.doc2CID(schema_def)\n    except Exception as e:\n        logging.error(e)\n\n    return database_name\n\ndef get_encoder_name (schema_in):\n    \"\"\"\n    Get encoder name from schema\n    \"\"\"\n\n    encoder_name = None\n    try:\n        schema_def = schema.generate_schema(schema_in)\n        encoder_name = schema_def[\"encoder\"]\n    except Exception as e:\n        logging.error(e)\n\n    return encoder_name\n\nclass Manager ():\n    def __init__ (self):\n        # to track all database - encoder mappings\n        self.db_to_encoders_map = {}\n        self.encoders_to_obj_map = {}\n\n    def __del__ (self):\n        logging.debug(\"Killed manager\")\n\n    def persist_db (self, json_schema, database_name, persist=True):\n        # do nothing \n        if not persist:\n            logging.debug(\"Skipping schema persist to Disk\")\n            return database_name\n\n        # create backup directory\n        location = os.environ[\"DATA_STORE_LOCATION\"]+\"hub_backup/\"\n        try:\n            if not os.path.exists(location):\n                # create backup directory\n                os.mkdir(location)\n        except Exception as e:\n            logging.error(\"Backup directory creation failed\")\n            logging.error(e)\n            return None\n\n        # store schema, replacing the old one\n        try:\n            with open(location+database_name, \"w\") as f_:\n                json.dump(json_schema, f_)\n        except Exception as e:\n            logging.error(\"Schema JSON writing failed\")\n            logging.error(e)\n            return None\n\n        return database_name\n\n    # initial preperation of Aquila HUB from backup\n    def prepare_hub (self):\n        # load schema files\n        location = os.environ[\"DATA_STORE_LOCATION\"]+\"hub_backup/\"\n        for database_name in os.listdir(location):\n            with open(location+database_name, \"r\") as schema__:\n                schema_ = json.load(schema__)\n                database_name_ = self.preload_model(schema_, persist=False)\n                if database_name_ == None:\n                    logging.debug(\"Model preloading failed for database: \"+database_name)\n                elif database_name_ == database_name:\n                    logging.debug(\"Model preloaded for database: \"+database_name)\n                else:\n                    logging.debug(\"Model missmatch for database \"+database_name+\", schema backup is modified. Hope you know what you're doing.\")\n\n    def preload_model (self, json_schema, persist=True):\n        \"\"\"\n        Download a model and load it into memory\n        \"\"\"\n        # create a schema copy\n        schema_copy = copy.deepcopy(json_schema)\n        # parse schema\n        # NOTE: get_database_name makes modifications to \"json_schema\" variable\n        # so, beware of it's subsequent usage. If you want to use the original schema,\n        # use \"schema_copy\" variable instead\n        database_name = get_database_name(json_schema)\n        encoder_name = get_encoder_name(json_schema)\n        \n        # load model for database\n        if database_name:\n            # database already not created?\n            if not self.db_to_encoders_map.get(database_name):\n                self.db_to_encoders_map[database_name] = encoder_name\n                # encoder already not created?\n                if not self.encoders_to_obj_map.get(encoder_name):\n                    self.encoders_to_obj_map[encoder_name] = enc_.Encoder(encoder_name, asyncio.Queue())\n                    # encoder already loaded?\n                    if self.encoders_to_obj_map[encoder_name].preload_model(json_schema, database_name):\n                        return self.persist_db(schema_copy, database_name, persist)\n                    else:\n                        # reset all, don't create DB & encoder\n                        self.encoders_to_obj_map[encoder_name] = None\n                        self.db_to_encoders_map[database_name] = None\n                        return None\n                else:\n                    return self.persist_db(schema_copy, database_name, persist)\n            else:\n                return self.persist_db(schema_copy, database_name, persist)\n        else:\n            return None\n\n    async def compress_data (self, database_name, texts):\n        \"\"\"\n        Load an already existing database \n        \"\"\"\n        if self.db_to_encoders_map.get(database_name):\n            encoder_name = self.db_to_encoders_map[database_name]\n            if self.encoders_to_obj_map.get(encoder_name):\n                response_ = None\n                # add compression request to queue, get request id\n                req_id = await self.encoders_to_obj_map[encoder_name].enqueue_compress_data(texts)\n                # wait until request id is processed\n                while (True):\n                    # response available yet?\n                    response_ = self.encoders_to_obj_map[encoder_name].response_queue[req_id]\n                    if response_ != None:\n                        # response available; take it, reset queue & break waiting\n                        self.encoders_to_obj_map[encoder_name].response_queue[req_id] = None\n                        break\n                    # sleep for a while\n                    await asyncio.sleep(SLEEP_PROTECTION)\n                return response_\n            else:\n                return None\n        else:\n            return None\n\n    # define background task to process request queue for each database object\n    async def background_task(self):\n        logging.debug(\"===== Background task INIT =====\")\n        while self.bg_task_active:\n            # for each database object\n            for key_ in self.encoders_to_obj_map:\n                # any request available in queue?\n                if self.encoders_to_obj_map[key_].request_queue.empty():\n                    continue\n                # process request\n                await self.encoders_to_obj_map[key_].process_queue()\n\n            await asyncio.sleep(SLEEP_PROTECTION)\n"
  },
  {
    "path": "aquila/encoder/requirements.txt",
    "content": "aiofiles==0.8.0\nbase58==2.1.1\nblinker==1.4\nbson==0.5.10\ncertifi==2021.10.8\nchardet==4.0.0\ncharset-normalizer==2.0.10\nclick==8.0.3\nfastjsonschema==2.15.3\nfasttext==0.9.2\nfilelock==3.4.2\nh11==0.12.0\nh2==4.1.0\nhpack==4.0.0\nhuggingface-hub==0.4.0\nhypercorn==0.13.2\nhyperframe==6.0.1\nidna==3.3\nitsdangerous==2.0.1\nJinja2==3.0.3\njoblib==1.1.0\nMarkupSafe==2.0.1\nnltk==3.6.7\nnumpy==1.22.0\npackaging==21.3\nPillow==9.0.0\npriority==2.0.0\npybind11==2.9.0\npycryptodome==3.12.0\npyparsing==3.0.6\npython-dateutil==2.8.2\nPyYAML==6.0\nquart==0.16.2\nregex==2021.11.10\nrequests==2.27.1\nsacremoses==0.0.47\nscikit-learn==1.0.2\nscipy==1.7.3\nsentence-transformers==2.1.0\nsentencepiece==0.1.96\nsix==1.16.0\nthreadpoolctl==3.0.0\ntokenizers==0.10.3\ntoml==0.10.2\ntorch==1.10.1\ntorchvision==0.11.2\ntqdm==4.62.3\ntransformers==4.15.0\ntyping-extensions==4.0.1\nurllib3==1.26.8\nWerkzeug==2.0.2\nwsproto==1.0.0"
  },
  {
    "path": "aquila/encoder/run_tests.sh",
    "content": "# rm -r /data/*\n\npython3 -m unittest test.apis.hub_fns -v"
  },
  {
    "path": "aquila/encoder/test/__init__.py",
    "content": ""
  },
  {
    "path": "aquila/encoder/test/apis/hub_fns.py",
    "content": "import unittest\n\nfrom utils import CID, schema\n\nfrom Crypto.Hash import SHA384\nfrom Crypto.PublicKey import RSA\nfrom Crypto.Signature import pkcs1_15\nimport base58\n\nimport requests\nfrom requests.structures import CaseInsensitiveDict\nimport json\nimport bson\n\nhost = \"127.0.0.1:5002\"\n\n\n# load private key\nwith open(\"private_unencrypted.pem\", \"r\") as pkf:\n    k = pkf.read()\n    priv_key = RSA.import_key(k)\n\nclass TestAuth (unittest.TestCase):\n\n    # Preload a model\n    def test_1_auth_preload_http (self):\n\n        schema_def_ = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd905\",\n            \"encoder\": \"ftxt:https://ftxt-models.s3.us-east-2.amazonaws.com/ftxt_base_min.bin\",\n            \"codelen\": 25,\n            \"metadata\": {}\n        }\n\n        # generate schema \n        schema_def = schema.generate_schema(schema_def_)\n        database_name = CID.doc2CID(schema_def)\n\n        # 1. test preperation\n        data_ = { \"schema\": schema_def_ }\n        data_bson = bson.dumps(data_)\n        # generate hash\n        hash = SHA384.new()\n        hash.update(data_bson)\n        \n        # Sign with pvt key\n        signer = pkcs1_15.new(priv_key)\n        signature = signer.sign(hash)\n        signature = base58.b58encode(signature).decode(\"utf-8\")\n\n        url = \"http://\"+host+\"/prepare\"\n\n        headers = CaseInsensitiveDict()\n        headers[\"Content-Type\"] = \"application/json\"\n\n        data = {\n            \"data\": data_,\n            \"signature\": signature\n        }\n\n        data = json.dumps(data)\n\n\n        resp = requests.post(url, headers=headers, data=data)\n        \n        database_name_ = resp.json()[\"databaseName\"]\n        # check databases are the same\n        self.assertEqual(database_name, database_name_, \"DB name doesn't match\")\n\n        # 2. test compression\n        data_ = {\"databaseName\": database_name_, \"text\": [\"data one\", \"data two\"]}\n        url = \"http://\"+host+\"/compress\"\n\n        headers = CaseInsensitiveDict()\n        headers[\"Content-Type\"] = \"application/json\"\n\n        data = {\n            \"data\": data_\n        }\n\n        data = json.dumps(data)\n\n\n        resp = requests.post(url, headers=headers, data=data)\n\n        # # check returned array is valid\n        self.assertEqual(len(resp.json()[\"vectors\"]), len(data_[\"text\"]), \"Compressed items doesn't match query\")\n        self.assertEqual(len(resp.json()[\"vectors\"][0]), schema_def_[\"codelen\"], \"Compressed code length doesn't match\")\n\n    # Preload a model\n    def test_2_auth_preload_ipfs (self):\n\n        schema_def_ = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd905\",\n            \"encoder\": \"ftxt:ipfs://QmT9CECrTwUhAPw6VHgxcLciH4EBepkXJmSB9y2rchsVQz\",\n            \"codelen\": 25,\n            \"metadata\": {}\n        }\n\n        # generate schema \n        schema_def = schema.generate_schema(schema_def_)\n        database_name = CID.doc2CID(schema_def)\n\n        # 1. test preperation\n        data_ = { \"schema\": schema_def_ }\n        data_bson = bson.dumps(data_)\n        # generate hash\n        hash = SHA384.new()\n        hash.update(data_bson)\n        \n        # Sign with pvt key\n        signer = pkcs1_15.new(priv_key)\n        signature = signer.sign(hash)\n        signature = base58.b58encode(signature).decode(\"utf-8\")\n\n        url = \"http://\"+host+\"/prepare\"\n\n        headers = CaseInsensitiveDict()\n        headers[\"Content-Type\"] = \"application/json\"\n\n        data = {\n            \"data\": data_,\n            \"signature\": signature\n        }\n\n        data = json.dumps(data)\n\n\n        resp = requests.post(url, headers=headers, data=data)\n        \n        database_name_ = resp.json()[\"databaseName\"]\n        # check databases are the same\n        self.assertEqual(database_name, database_name_, \"DB name doesn't match\")\n\n        # 2. test compression\n        data_ = {\"databaseName\": data_[\"databaseName\"], \"text\": [\"data one\", \"data two\"]}\n        url = \"http://\"+host+\"/compress\"\n\n        headers = CaseInsensitiveDict()\n        headers[\"Content-Type\"] = \"application/json\"\n\n        data = {\n            \"data\": data_\n        }\n\n        data = json.dumps(data)\n\n\n        resp = requests.post(url, headers=headers, data=data)\n\n        # check returned array is valid\n        self.assertEqual(len(resp.json()[\"vectors\"]), len(data_[\"text\"]), \"Compressed items doesn't match query\")\n        self.assertEqual(len(resp.json()[\"vectors\"][0]), schema_def_[\"codelen\"], \"Compressed code length doesn't match\")\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "aquila/encoder/test.py",
    "content": "from aquilapy import Wallet, DB, Hub\nimport numpy as np\nimport time\n\nimport multiprocessing as mp\n\n# Create a wallet instance from private key\nwallet = Wallet(\"/home/iamjbn/aquilax/ossl/private_unencrypted.pem\")\n\nhost = \"http://127.0.0.1\"\n\n# Connect to Aquila Hub instance\nhub = Hub(host, \"5002\", wallet)\n\n# Schema definition to be used\nschema_def = {\n    \"description\": \"AquilaX-CE default user index\",\n    \"unique\": \"user_id1\",\n    \"encoder\": \"ftxt:http://0.0.0.0:2000/cc.en.300.bin\",\n    \"codelen\": 300,\n    \"metadata\": {\n        \"url\": \"string\",\n        \"text\": \"string\"\n    }\n}\n\ndef run_test (index_in):\n    print('index_in:', index_in)\n\n    # Craete a database with the schema definition provided\n    db_name_ = hub.create_database(schema_def)\n\n    # Generate encodings\n    texts = [\"Sure, technically these are processes, and this program should really be called a process spawning manager, but this is only due to the way that BASH works when it forks using the ampersand, it uses the fork() or perhaps clone() system call which clones into a separate memory space, rather than something like pthread_create() which would share memory. If BASH supported the latter, each sequence of execution would operate just the same and could be termed to be traditional threads whilst gaining a more efficient memory footprint.\",\n    \"Sure, technically these are processes, and this program should really be called a process spawning manager, but this is only due to the way that BASH works when it forks using the ampersand, it uses the fork() or perhaps clone() system call which clones into a separate memory space, rather than something like pthread_create() which would share memory. If BASH supported the latter, each sequence of execution would operate just the same and could be termed to be traditional threads whilst gaining a more efficient memory footprint.\",\n    \"Sure, technically these are processes, and this program should really be called a process spawning manager, but this is only due to the way that BASH works when it forks using the ampersand, it uses the fork() or perhaps clone() system call which clones into a separate memory space, rather than something like pthread_create() which would share memory. If BASH supported the latter, each sequence of execution would operate just the same and could be termed to be traditional threads whilst gaining a more efficient memory footprint.\",\n    \"Sure, technically these are processes, and this program should really be called a process spawning manager, but this is only due to the way that BASH works when it forks using the ampersand, it uses the fork() or perhaps clone() system call which clones into a separate memory space, rather than something like pthread_create() which would share memory. If BASH supported the latter, each sequence of execution would operate just the same and could be termed to be traditional threads whilst gaining a more efficient memory footprint.\"]\n    compression = hub.compress_documents(db_name_, texts)\n    print(len(compression)==len(texts))\n\n# test concurrency\ndef test_concurrency_thread (counter_upto):\n    start = time.time()\n    print(\"starting thread\")\n    \n    pool = mp.Pool(500) #mp.cpu_count())\n    pool.map(run_test, range(counter_upto))\n    pool.close()\n    pool.join()\n        \n    end = time.time()\n    print(end-start, counter_upto)\n    start = end\n\ntest_concurrency_thread(10000)\n\n\n# test model downloads from different sources\nschema_def[\"encoder\"] = \"ftxt:http://0.0.0.0:2000/cc.en.300.bin\"\nschema_def[\"codelen\"] = 300\nprint(schema_def)\n\ndb_name_ = hub.create_database(schema_def)\nprint(db_name_)\n\n\n# test model downloads from different sources\nschema_def[\"encoder\"] = \"ftxt:ipfs://QmY2FFRuW4xVeCDkwgwkWcq1aHaKFjfbEHPXjEEuQYax4P\"\nschema_def[\"codelen\"] = 300\n\ndb_name_ = hub.create_database(schema_def)\nprint(db_name_)\n"
  },
  {
    "path": "aquila/encoder/utils/CID.py",
    "content": "import logging\n\nimport bson\nimport hashlib\nimport base58\n\ndef doc2CID (inp):\n    try:\n        # JSON OBJ to BSON encode\n        bson_ = bson.dumps(inp)\n        # SHA-256 Double Hashing\n        hash_ = hashlib.sha256(bson_)\n        hash_ = hashlib.sha256(hash_.digest())\n        # Convert to Base-58 string\n        b58c_ = base58.b58encode(hash_.digest())\n\n        return b58c_.decode('utf-8')\n    except Exception as e:\n        logging.debug(e)\n        return None\n\ndef doc2bson (inp):\n    try:\n        # JSON OBJ to BSON encode\n        bson_ = bson.dumps(inp)\n\n        return bson_\n    except Exception as e:\n        logging.debug(e)\n        return None\n\ndef bson2doc (inp):\n    try:\n        # BSON to JSON OBJ\n        json_ = bson.loads(inp)\n\n        return json_\n    except Exception as e:\n        logging.debug(e)\n        return None"
  },
  {
    "path": "aquila/encoder/utils/config.py",
    "content": "import yaml\nimport os\n\nos.environ[\"DATA_STORE_LOCATION\"] = \"/data/\"\n\nwith open(\"config.yml\", \"r\") as stream:\n    DB_config = yaml.safe_load(stream)\n    \n    if \"AUTH_KEY_FILE\" not in os.environ:\n        os.environ[\"AUTH_KEY_FILE\"] = str(DB_config[\"auth\"][\"pubkey\"])\n    if \"IPFS_GATEWAY\" not in os.environ:\n        os.environ[\"IPFS_GATEWAY\"] = str(DB_config[\"ipfs\"][\"gateway\"])\n"
  },
  {
    "path": "aquila/encoder/utils/cryptops.py",
    "content": "import logging\n\nfrom Crypto.Hash import SHA384\nfrom Crypto.PublicKey import RSA\nfrom Crypto.Signature import pkcs1_15\n\nimport base58\n\nimport chardet\n\nimport bson\n\ndef read_public_key (location):\n    # disk read public key\n    with open(location, \"r\") as pkf:\n        k = pkf.read()\n        pub_key = RSA.import_key(k)\n\n        return pub_key\n\ndef verify_signature (json_data, pub_key, signature):\n    \n    ret = True\n\n    binary_data = bson.dumps(json_data)\n\n    # generate hash\n    hash = SHA384.new()\n    hash.update(binary_data)\n    \n    signature = base58.b58decode(signature)\n\n    # Verify with pub key\n    verifier = pkcs1_15.new(pub_key)\n    \n    try:\n        verifier.verify(hash, signature)\n    except Exception as e:\n        logging.debug(e)\n        ret = False\n\n    return ret"
  },
  {
    "path": "aquila/encoder/utils/downloader.py",
    "content": "import logging\n\nimport os\nimport time\n\nimport requests\nfrom tqdm import tqdm\n\ndef download_large_file (url, location, method=\"get\"):\n    r = None\n    if method == \"get\":\n        r = requests.get(url, stream=True)\n    if method == \"post\":\n        r = requests.post(url, stream=True)\n\n    if r != None:\n        r.raise_for_status()\n        total_size_in_bytes= int(r.headers.get('content-length', 0))\n        block_size = 1024*5\n        progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True)\n        with open(location, 'wb') as f:\n            for chunk in r.iter_content(chunk_size=block_size):\n                progress_bar.update(len(chunk))\n                f.write(chunk)\n\n        r.close()\n        progress_bar.close()\n        if total_size_in_bytes != 0 and progress_bar.n != total_size_in_bytes:\n            logging.error(\"Download failed.\")\n            os.remove(location)\n            return False\n        return True\n\ndef http_download (url, directory, file_name):\n    \"\"\"\n    Download model via http\n    \"\"\"\n    try:\n        # create models dir, if not exists\n        if not os.path.exists(directory):\n            os.makedirs(directory)\n\n        original_bin_file_name = url.split(\"/\")[-1]\n        # check if model already exists\n        if not os.path.exists(directory+original_bin_file_name):\n            # download file\n            logging.debug(\"Downloading model..\")\n            # download from given url\n            status = download_large_file(url, directory+original_bin_file_name)\n            # failed??\n            if not status:\n                return None\n        if not os.path.exists(directory+file_name):\n            # copy and rename model\n            logging.debug(\"Copy model..\")\n            os.symlink(directory+original_bin_file_name, directory+file_name)\n    except Exception as e:\n        logging.error(e)\n        return None\n\n    return directory+file_name\n\ndef ipfs_download (url, directory, file_name):\n    \"\"\"\n    Download model via IPFS\n    \"\"\"\n    try:\n        # create models dir, if not exists\n        if not os.path.exists(directory):\n            os.makedirs(directory)\n\n        IPFS_CID = url.split(\"ipfs://\")[1]\n        original_bin_file_name = IPFS_CID\n        # check if model already exists\n        if not os.path.exists(directory+original_bin_file_name):\n            # download file\n            logging.debug(\"Downloading model..\")\n            logging.debug(\"Connecting to local IPFS demon..\")\n            # download from IPFS local API\n            url_ = os.environ[\"IPFS_GATEWAY\"]+\"/ipfs/\"+IPFS_CID\n            status = download_large_file(url_, directory+original_bin_file_name)\n            # failed??\n            if not status:\n                return None\n        if not os.path.exists(directory+file_name):\n            # copy and rename model\n            logging.debug(\"Copy model..\")\n            os.symlink(directory+original_bin_file_name, directory+file_name)\n    except Exception as e:\n        logging.error(e)\n        return None\n    \n    return directory+file_name\n    "
  },
  {
    "path": "aquila/encoder/utils/schema.py",
    "content": "import logging\n\nimport fastjsonschema\n\ndef generate_schema (template):\n    # get all keys from template schema\n    metadata_templ = template.get(\"metadata\")\n    if metadata_templ:\n        del template[\"metadata\"]\n    else:\n        metadata_templ = {}\n\n    keys_ = list(template.keys())\n\n    # sort keys\n    keys_.sort()\n\n    # validate required keys\n    req_k = [\"description\", \"encoder\", \"unique\"]\n    for r_ in req_k:\n        if r_ not in keys_:\n            # cannot continue, invalid schema\n            return None\n\n    # generate schema in sorted keys\n    generated_schema = { \n        \"$schema\": \"http://json-schema.org/schema#\", \n        \"$id\": \"http://aquilanetwork.com/schema/id/v1\", \n        \"title\": \"Schema\", \n        \"description\": \"\",\n        \"encoder\": \"\",\n        \"unique\": \"\",\n        \"type\": \"object\",\n        \"properties\": {\n            \"code\": {\n                \"description\": \"Encoded data\",\n                \"type\": \"array\",\n                \"items\": {\n                    \"type\": \"number\"\n                }\n            },\n            \"metadata\": {\n                \"$ref\": \"#/definitions/metadata\"\n            }\n        },\n        \"definitions\": {\n            \"metadata\": {\n                \"description\": \"User defined metadata\",\n                \"type\": \"object\",\n                \"properties\": {},\n                \"required\": []\n            }\n        },\n        \"required\": [\"code\", \"metadata\"]\n    }\n\n    metadata = {}\n    metadata_types = [\"number\", \"string\"]\n\n    for key_ in keys_:\n        if key_ in req_k:\n            # fill in root level keys\n            generated_schema[key_] = template[key_]\n        elif key_ == \"codelen\":\n            generated_schema[\"properties\"][\"code\"][\"maxItems\"] = template[key_]\n        else:\n            # fill in root level keys :: extra info that we don't care\n            generated_schema[key_] = template[key_]\n\n    for key_ in metadata_templ.keys():\n        # check type is predefined\n        if metadata_templ[key_] not in metadata_types:\n            return None\n\n        # fill in metadata keys\n        metadata[key_] = {\n            \"type\": metadata_templ[key_]\n        }\n\n    generated_schema[\"definitions\"][\"metadata\"][\"properties\"] = metadata\n    generated_schema[\"definitions\"][\"metadata\"][\"required\"] = list(metadata.keys())\n\n    # validate values\n    if type(generated_schema[\"properties\"][\"code\"].get(\"maxItems\")) != int:\n        return None\n        \n    return generated_schema\n\ndef compile (schema_def):\n    # compile schema\n    validator = fastjsonschema.compile(schema_def)\n\n    return validator\n\ndef validate_json_docs (validator, json_doc):\n    try:\n        # validate doc on schema :: will except on fail\n        validator(json_doc)\n        # validated\n        # logging.debug(\"Schema validation success\")\n        return True\n    except Exception as e:\n        logging.error(e)\n        return False\n"
  },
  {
    "path": "aquila/metricstore/.travis.yml",
    "content": "language: node_js\n\nservices:\n  - docker\n\nnode_js:\n  - \"11\"\n\nbefore_install:\n  - docker build -f Dockerfile_local_build -t ammaorg/aquiladb:travis .\n  - docker run -d -i -p 50051:50051 -t ammaorg/aquiladb:travis\n  - docker ps -a\n  - sudo apt-get install -y make\n  - cd src\n\ninstall:\n  - npm install\n  - cd test\n\nscript:\n  - node test.js\n\nbranches:\n  only:\n  - develop"
  },
  {
    "path": "aquila/metricstore/CODE_OF_CONDUCT.md",
    "content": "# AquilaDB Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at humans@aquiladb.xyz. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "aquila/metricstore/DB_config.yml",
    "content": "docs:\n  cswap: 10101 # minimum data required to start indexing\n  vd: 784 # fixed vector dimension\nfaiss:\n  init:\n    nlist: 1 # number of cells \n    nprobe: 1 # number of cells that are visited to perform a search\n    bpv: 8 # bytes per vector\n    bpsv: 8 # bytes per sub vector\nannoy:\n  init:\n    smetric: \"dot\" # similarity metric to be used\n    ntrees: 500 # no. of trees\n    search_k: -1 # search_k is provided in runtime and affects the search performance. A larger value will give more accurate results, but will take longer time to return.\nqueue:\n  qlen: 100000 # length limit for quesues used\n  sleep: 1 # thread waiting in seconds\nauth:\n  pubkey: \"/ossl/public.pem\"\n"
  },
  {
    "path": "aquila/metricstore/Dockerfile",
    "content": "# start a new build stage\nFROM ubuntu:latest as builder\n\nRUN ls\n\n# set work directory\nENV ROOT_DIR /home/root\nWORKDIR $ROOT_DIR\n\n# install aquiladb\nRUN apt update && apt install -y curl && \\\n    curl -s -L https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/install.sh | /bin/bash\n\n# preperations\nENV PATH=\"$ROOT_DIR/env/bin:$PATH\"\n\nSHELL [\"/bin/bash\", \"-o\", \"pipefail\", \"-c\"]\n\n# install and start demon\nRUN mkdir -p /data && \\\n    printf \"#!/bin/bash\\nsource env/bin/activate && export MINI_AQDB='active' && cd adb/src && \\\n    python3 index.py\" > /bin/init.sh && chmod +x /bin/init.sh\n\n# expose port\nEXPOSE 5001\n\nENTRYPOINT [\"init.sh\"]"
  },
  {
    "path": "aquila/metricstore/DockerfileBig",
    "content": "# start a new build stage\nFROM ubuntu:latest as builder\n\n# set work directory\nENV ROOT_DIR /home/root\nWORKDIR $ROOT_DIR\n\n# install aquiladb\nRUN apt update && apt install -y curl && \\\n    curl -s -L https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/install.sh | /bin/bash -s -- -m 0\n\n\n# start a new runner stage\nFROM ubuntu:latest as runner\n\n# set work directory\nENV ROOT_DIR /home/root\nWORKDIR $ROOT_DIR\n\nRUN echo \"$ROOT_DIR\"\n\n# copy required files from builder stage\nCOPY --from=builder $ROOT_DIR/env $ROOT_DIR/env\nCOPY --from=builder $ROOT_DIR/adb $ROOT_DIR/adb\nCOPY --from=builder /ossl /ossl\n\n# preperations\nENV PATH=\"$ROOT_DIR/env/bin:$PATH\"\nWORKDIR $ROOT_DIR\nSHELL [\"/bin/bash\", \"-o\", \"pipefail\", \"-c\"]\n\n# install and start demon\nRUN export DEBIAN_FRONTEND=noninteractive && mkdir -p /data && apt update && \\\n    apt install -y python3 libgomp1 libblas-dev liblapack-dev && \\\n    printf \"#!/bin/bash\\nsource env/bin/activate && cd adb/src && \\\n    python3 index.py\" > /bin/init.sh && chmod +x /bin/init.sh\n\n# expose port\nEXPOSE 5001\n\nENTRYPOINT [\"init.sh\"]\n"
  },
  {
    "path": "aquila/metricstore/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 percent (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": "aquila/metricstore/README.md",
    "content": "<div align=\"center\">\n  <a href=\"https://aquila.network\">\n    <img\n      src=\"https://user-images.githubusercontent.com/19545678/133918727-5a37c6be-676f-427b-8c86-dd50f58d1287.png\"\n      alt=\"Aquila Network Logo\"\n      height=\"64\"\n    />\n  </a>\n  <br />\n  <p>\n    <h3>\n      <b>\n        Aquila DB\n      </b>\n    </h3>\n  </p>\n  <p>\n    <b>\n      Easy to use Neural Search Engine\n    </b>\n  </p>\n  <br/>\n</div>\n\n**[Aquila DB](https://github.com/Aquila-Network/AquilaDB)** is a Neural search engine. In other words, it is a database to index **Latent Vectors** generated by ML models along with **JSON Metadata** to perform **k-NN** retrieval. It is dead simple to set up, language-agnostic, and drop in addition to your Machine Learning Applications. Aquila DB, as of current features is a ready solution for Machine Learning engineers and Data scientists to build **[Neural Information Retrieval](https://www.microsoft.com/en-us/research/uploads/prod/2017/06/INR-061-Mitra-neuralir-intro.pdf)** applications out of the box with minimal dependencies.\n\n> This project is still in alpha version & we're already using it in production to power semantic search at https://aquila.network. \n\n\nWanna support this project? Yes, we love getting a **star** ⭐ and **shout-out** 🗣️ 🤗\n\nJoin [Community chat and get support: ![discord chatroom for discussions](https://www.freeiconspng.com/minicovers/flat-discord-material-like-icon--2.png)](https://discord.gg/5YP7zHS)\n\n\n# Who is this for\n\n* If you are working on a data science project and need to store a hell of a lot of data and retrieve similar data based on some feature vector, this will be a useful tool to you, with extra benefits a real world web application needs.\n* Are you dealing with a lot of images and related metadata? Want to find similar ones? You are at the right place.\n* If you are looking for a document database, this is not the right place for you.\n\n# Technology\nAquila DB powers search features of Aquila Network. Here is where Aquila DB fits in the entire ecosystem:\n<div align=\"center\">\n  <img\n    src=\"https://user-images.githubusercontent.com/19545678/133918438-997af8ec-67ef-4f7c-95ab-16d2f28e79e3.png\"\n    alt=\"Aquila DB Architecture\"\n    height=\"400\"\n  />\n <br/>\n</div>\n\n\n\nIf you are serious and wanna dive down the rabbit hole, read our **[whitepapers](https://github.com/Aquila-Network/whitepaper)** and **[technical specifications](https://github.com/Aquila-Network/specs)** (being actively worked on). \n\n\n\n**As a side note**, everything in **[Aquila Network](https://github.com/Aquila-Network)** is defined by the specifications and a large chunk of our efforts goes into it. We also maintain quality implementations of those specifications with non-technical users in mind. This is to make sure that - Aquila Network is fully open, decentralized by design, and Fair. You can follow those specifications to implement your alternative software and still interact with the network without any restrictions.\n\n# Install\n### Debian\n\nRun `curl -s -L https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/install.sh | /bin/bash -s -- -d 1 `.\n\n### Docker\n\n**You need docker installed in your system**\n\nBuild image (lite): `docker build https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/Dockerfile -t aquiladb:local`\n\nBuild image (big data): `docker build https://raw.githubusercontent.com/Aquila-Network/AquilaDB/master/DockerfileBig -t aquiladb:localbg`\n\nRun image (to deploy Aquila DB lite): `docker run -p 5001:5001 -d aquiladb:local`\n\nRun image (to deploy Aquila DB big): `docker run -p 5001:5001 -d aquiladb:localbg`\n\n# Client SDKs\nWe currently have multiple client libraries in progress to abstract the communication between deployed Aquila DB and your applications.\n\n[Python](https://github.com/Aquila-Network/AquilaPy)\n\n[Node JS](https://github.com/Aquila-Network/AquilaJS)\n\n## Where to get private key (wallet key) for client authentication\nWhen you use a client library to authenticate with AquilaDB, you might need access the same private key (wallet key) used by AquilaDB. This key is located inside `/ossl/` directory within AquilaDB docker container (in your computer if you have installed AquilaDB directly without docker). To access the keys inside your AquilaDB container, follow below steps:\n\n* identify `CONTAINER ID` for the already running `aquiladb` docker instance:\n`docker ps`\n* take a copy of private keys from docker container to your host machine:\n`docker cp CONTAINER_ID:/ossl/ ./`\n* now you will see a new directory named `ossl` at your current location. Use the keys inside it.\n#### tips for advanced users\nIf your pipeline requires the private keys to be generated in advance, you can do it in your host machine and then mount it to the container's `/ossl/` directory. \n\nRun:\n```\nmkdir -p <host>/ossl/\nopenssl genrsa -passout pass:1234 -des3 -out <host>/ossl/private.pem 2048\nopenssl rsa -passin pass:1234 -in <host>/ossl/private.pem -outform PEM -pubout -out <host>/ossl/public.pem\nopenssl rsa -passin pass:1234 -in <host>/ossl/private.pem -out <host>/ossl/private_unencrypted.pem -outform PEM\n```\n\n# Progress\nThis project is still and will be under active development with intermediate production releases. It can either be used as a standalone database or as a participating node in Aquila Network. Please note, [Aquila Port](https://github.com/Aquila-Network/specs/blob/main/README.md#aquila-port) (peer-peer network layer for Aquila DB nodes) is also a work in progress. Currently, you need to deploy your custom models to feed vector embeddings to Aquila DB, until [Aquila Hub](https://github.com/Aquila-Network/specs/blob/main/README.md#aquila-hub) developments get started.\n\n# Contribute\nWe have [prepared a document](https://docs.google.com/document/d/1bT2_9FQIxQpx_rdYbkTukn_DJRi_haVK_ixTf8uTaDE/edit?usp=sharing) to get anyone interested to contribute, immediately started with Aquila DB.\nHere is our high-level [release roadmap](https://user-images.githubusercontent.com/19545678/62313851-5af82880-b4af-11e9-84f6-21e24bf46e8a.png).\n\n# Learn\n\nWe have started meeting developers and do small talks on Aquila DB. Here are the slides that we use on those occasions: http://bit.ly/AquilaDB-slides \n\n**Video:**\n\n[<img alt=\"introduction to Neural Information retrieval with AquilaDB\" src=\"http://img.youtube.com/vi/-VYpjpLXU5Q/0.jpg\" width=\"300\" />](http://www.youtube.com/watch?v=-VYpjpLXU5Q)\n\nAs of current AquilaDB release features, you can build **[Neural Information Retrieval](https://www.microsoft.com/en-us/research/uploads/prod/2017/06/INR-061-Mitra-neuralir-intro.pdf)** applications out of the box without any external dependencies. Here are some useful links to learn more about it and start building:\n\n* Microsoft published a paper and youtube video on this to onboard anyone interested: \n  * paper: https://www.microsoft.com/en-us/research/uploads/prod/2017/06/INR-061-Mitra-neuralir-intro.pdf\n  * video: https://www.youtube.com/watch?v=g1Pgo5yTIKg\n* Embeddings for Everything: Search in the Neural Network Era: https://www.youtube.com/watch?v=JGHVJXP9NHw\n* Autoencoders are one such deep learning algorithms that will help you to build semantic vectors - foundation for Neural Information retrieval. Here are some links to Autoencoders based IR:\n  * go to chapter 15 in this link: https://www.cs.toronto.edu/~hinton/coursera_lectures.html\n  * https://www.coursera.org/lecture/ml-foundations/examples-of-document-retrieval-in-action-CW25H\n  * https://www.coursera.org/lecture/intro-to-deep-learning/autoencoders-101-QqBOa\n* Note that, the idea of information retrieval applies not only to text data but for any data. All you need to do is, encode any source datatype to a dense vector with deep neural networks.\n\n<br/><br/>\n<h1 align=\"center\">Our Sponsors</h1>\n<p align=\"center\"><b></b></p>\n\n<br/>\n\n> email us to sponsor this project [adbadmin@protonmail.ch](mailto:adbadmin@protonmail.ch).\n\n<br/><br/>\n\n# Citing Aquila DB\nIf you use Aquila DB in an academic paper, we would 😍 to be cited. Here are the two ways of citing Aquila DB:\n```\n\\footnote{https://github.com/Aquila-Network/AquilaDB}\n```\n```\n@misc{AquilaNetwork2019AquilaDB,\n  title={AquilaDB: Neural Search Engine},\n  author={Jubin Jose, Nibin Peter},\n  howpublished={\\url{https://github.com/Aquila-Network/AquilaDB}},\n  year={2019}\n}\n```\n\n# License\n\nApache License 2.0 [license file](https://github.com/Aquila-Network/AquilaDB/blob/master/LICENSE)\n\ncreated by ❤️ with a-mma (a_മ്മ)\n"
  },
  {
    "path": "aquila/metricstore/authentication.py",
    "content": "from utils import cryptops\n\nimport os\n\npub_key = cryptops.read_public_key(os.environ[\"AUTH_KEY_FILE\"])\n\ndef check (json_data, signature):\n    return cryptops.verify_signature(json_data, pub_key, signature)"
  },
  {
    "path": "aquila/metricstore/index.py",
    "content": "import logging\n\nfrom flask import Flask, request\nfrom flask_cors import CORS\nfrom flask import jsonify\nfrom functools import wraps\n\nfrom utils import config\nimport authentication\n\nimport router\n\napp = Flask(__name__, instance_relative_config=True)\n\n# Enable CORS\nCORS(app)\n\n# preload databases\nrouter.preload_databases()\n\n# Add authentication\ndef authenticate ():\n    def decorator (f):\n        @wraps(f)\n        def wrapper (*args, **kwargs):\n            params = extract_request_params(request)\n\n            if not params or not \"data\" in params or not \"signature\" in params:\n                return \"Unauthorised access\", 401\n\n            if not authentication.check(params[\"data\"], params[\"signature\"]):\n                return \"Unauthorised access\", 401\n\n            return f(*args, **kwargs)\n\n        return wrapper\n    return decorator\n\ndef extract_request_params (request):\n    if not request.is_json:\n        logging.error(\"Cannot parse request parameters\")\n\n        # request is invalid\n        return None\n\n    # Extract JSON data\n    data_ = request.get_json()\n    return data_\n\n@app.route(\"/\", methods=['GET'])\ndef info ():\n    \"\"\"\n    Check server status\n    \"\"\"\n\n    # Build response\n    return {\n            \"success\": True,\n            \"message\": \"AquilaDB is running healthy\"\n        }, 200\n\n@app.route(\"/db/create\", methods=['POST'])\n@authenticate()\ndef db_create ():\n    \"\"\"\n    Create database from schema definition\n    \"\"\"\n\n    # get parameters\n    params = extract_request_params(request)[\"data\"]\n\n    if not params:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    if \"schema\" in params:\n        database_name = router.create_database(params.get(\"schema\"))\n\n    # Build response\n    if database_name:\n        return {\n                \"success\": True,\n                \"database_name\": database_name\n            }, 200\n    else:\n        return {\n                \"success\": False,\n                \"message\": \"Invalid schema definition\"\n            }, 400\n\n@app.route(\"/db/doc/insert\", methods=['POST'])\n@authenticate()\ndef doc_insert ():\n    \"\"\"\n    insert documents\n    \"\"\"\n\n    # get parameters\n    params = extract_request_params(request)[\"data\"]\n\n    if not params:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    if \"docs\" in params and \"database_name\" in params:\n        cids = router.insert_docs(params.get(\"docs\"), params.get(\"database_name\"))\n\n    # Build response\n    return {\n            \"success\": True,\n            \"ids\": cids\n        }, 200\n\n@app.route(\"/db/doc/delete\", methods=['POST'])\n@authenticate()\ndef doc_delete ():\n    \"\"\"\n    delete documents by cid\n    \"\"\"\n\n    # get parameters\n    params = extract_request_params(request)[\"data\"]\n\n    if not params:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    if \"ids\" in params and \"database_name\" in params:\n        ids = router.delete_docs(params.get(\"ids\"), params.get(\"database_name\"))\n\n    # Build response\n    return {\n            \"success\": True,\n            \"ids\": ids\n        }, 200\n\n@app.route(\"/db/search\", methods=['GET'])\n@authenticate()\ndef db_search ():\n    \"\"\"\n    search documents\n    \"\"\"\n\n    # get parameters\n    params = extract_request_params(request)[\"data\"]\n\n    if not params:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    if \"matrix\" in params and \"k\" in params and \"database_name\" in params:\n        docs, dists = router.search(params.get(\"matrix\"), params.get(\"k\"), None, params.get(\"database_name\"))\n\n    # Build response\n    return {\n            \"success\": True,\n            \"docs\": docs,\n            \"dists\": dists\n        }, 200\n\n\ndef flaskserver ():\n    \"\"\"\n    start server\n    \"\"\"\n    app.run(host='0.0.0.0', port=5001, debug=False)\n\nif __name__ == \"__main__\":\n    flaskserver()\n"
  },
  {
    "path": "aquila/metricstore/install.sh",
    "content": "#!/bin/bash -e\n\nexport DEBIAN_FRONTEND=noninteractive\napt update\n\nexport USER=$(whoami)\nexport ROOT_DIR=/home/$USER\n\nmkdir -p /data/\nmkdir -p $ROOT_DIR\ncd $ROOT_DIR\n\nmini=1\ngpu=0\ntest=0\ndemon=0\n\nwhile getopts m:g:t:d: flag\ndo\n    case \"${flag}\" in\n        m) mini=${OPTARG};;\n        g) gpu=${OPTARG};;\n        t) test=${OPTARG};;\n        d) demon=${OPTARG};;\n    esac\ndone\n\nif [[ $mini -eq 1 ]]; # if minimal install enabled\nthen\n    echo \"Aquila DB minimal install will be done by default. \\\n    Minimal install is recommended for personal use - \\\n    install process is fast and lightweight. If you are planning to deal \\\n    with big-data, disable minimal install with '-m 0' argument\"\nfi\n\n# system packs install\napt install -y git wget nano python3 python3-pip libssl-dev\nif [[ $mini -eq 0 ]]; # if minimal install disabled\nthen\n    apt install -y libblas-dev liblapack-dev swig\nfi\n\n# setup venv\npip3 install virtualenv\nvirtualenv $ROOT_DIR/env\nsource $ROOT_DIR/env/bin/activate\n\n# install python packages\npip3 install numpy pycryptodome base58 chardet Flask requests flask_cors PyYAML bson fastjsonschema annoy plyvel\n\nif [[ $mini -eq 0 ]]; # if minimal install disabled\nthen\n    # install cmake\n    apt purge --auto-remove cmake\n\n    version=3.19\n    build=1\n    mkdir -p $ROOT_DIR/temp\n    cd $ROOT_DIR/temp\n    wget https://cmake.org/files/v$version/cmake-$version.$build.tar.gz\n    tar -xzvf cmake-$version.$build.tar.gz\n    cd cmake-$version.$build/\n\n    ./bootstrap\n    make -j$(nproc)\n    make install\n\n    cmake --version\n\n    # install faiss\n    cd $ROOT_DIR\n    mkdir -p faiss\n    cd faiss\n    git clone https://github.com/facebookresearch/faiss.git .\n\n    if [[ $gpu -eq 0 ]]; # if gpu not enabled\n    then\n            echo \"build FAISS without GPU\"\n            cmake -DFAISS_ENABLE_GPU=OFF -B build .\n    else\n            echo \"build FAISS with GPU\"\n            cmake -B build .\n    fi\n    make -C build\n\n    # For the Python interface:\n    cd build/faiss/python\n    python setup.py install\n\n    cp -r $ROOT_DIR/faiss/build/faiss/python/ $ROOT_DIR/env/lib/python3.8/site-packages/faiss\nfi\n\n# clone & test AquilaDB\ncd $ROOT_DIR\nmkdir -p adb\ncd adb\ngit clone https://github.com/Aquila-Network/AquilaDB.git .\n\nmkdir -p /ossl/\nopenssl genrsa -passout pass:1234 -des3 -out /ossl/private.pem 2048\nopenssl rsa -passin pass:1234 -in /ossl/private.pem -outform PEM -pubout -out /ossl/public.pem\nopenssl rsa -passin pass:1234 -in /ossl/private.pem -out /ossl/private_unencrypted.pem -outform PEM\n\ncd $ROOT_DIR/adb/src\nif [[ $test -eq 1 ]]; # if tests enabled\nthen\n\tchmod +x run_tests.sh\n\t./run_tests.sh\nelse\n\techo \"Not running tests\"\nfi\n\necho \"===================================\"\necho \"     AquilaDB setup complete.      \"\necho \"===================================\"\n\nif [[ $demon -eq 1 ]]; # if demon run enabled\nthen\n    # install node\n    apt install -y nodejs npm\n    # install pm2\n    npm i pm2 -g\n\n    # start server\n    pm2 start index.py\n    # Keep logs alive\n    pm2 logs -f\nfi\n"
  },
  {
    "path": "aquila/metricstore/manager.py",
    "content": "import logging\n\nfrom utils import CID, schema\n\nfrom vec_index import hannoy \n\nimport os\nis_mini_instance = os.environ[\"MINI_AQDB\"]\nif is_mini_instance == \"inactive\":\n    from vec_index import hfaiss\n\nimport plyvel\n\nimport numpy as np\n\nimport json\nimport random\nimport threading\nimport queue\nimport time\nimport pickle\n\nINDEX_LABEL = [\"annoy\", \"faiss\"]\nSTORE_LOCATION = os.environ[\"DATA_STORE_LOCATION\"]\n\nTRAIN_DAT_LEN = int(os.environ[\"MIN_SAWP_COUNT\"])\nPROCESS_TIMEOUT = int(os.environ[\"THREAD_SLEEP\"])\nMAX_Q_LEN = int(os.environ[\"FIXED_Q_LEN\"])\n\ndef byt (inp):\n    return bytes(str(inp), 'ascii')\n\nclass VecManager:\n\n    def __init__ (self, json_schema):\n        # get database name from schema CID\n        database_name = CID.doc2CID(json_schema)\n\n        # keep database name\n        self.database_name = database_name\n\n        # set DB disk location\n        self.DB_disk_location = STORE_LOCATION + database_name\n\n        # create data directory for database\n        if not os.path.exists(self.DB_disk_location):\n            os.makedirs(self.DB_disk_location)\n\n        # keep schema in store location\n        with open(self.DB_disk_location + '/schema.json', 'w') as oschema:\n            json.dump(json_schema, oschema)\n        \n        # get vector index\n        self.active_index = INDEX_LABEL[0]\n        self.index = self.get_index(self.DB_disk_location)\n\n        # Create KV store instance\n        self.KV_store = plyvel.DB(self.DB_disk_location + \"/kv.db\", create_if_missing=True)\n        if self.KV_store.get(byt(-1)) == None:\n            self.KV_store.put(byt(-1), byt(0))\n\n        # Training data holder\n        self.training_data = []\n        self.TD_location = self.DB_disk_location + \"/TD\"\n        # Try loading training data\n        self.load_TD_from_disk()\n\n        # spawn worker thread\n        self.q_maxsize = MAX_Q_LEN\n        self.process_flag = True\n        self.process_timeout_sec = PROCESS_TIMEOUT\n        self.spawn()\n\n    def __del__(self):\n        self.process_flag = False\n        if self.process_thread:\n            self.process_thread.join()\n            logging.debug(\"Thread stopped\")\n        # close level database connection\n        self.KV_store.close()\n\n    def add_vectors (self, documents):\n        # add to KV store\n        next_index = int(self.KV_store.get(byt(-1)))\n\n        # check if it is ready to swap index\n        if is_mini_instance == \"inactive\" and next_index > TRAIN_DAT_LEN \\\n            and self.active_index == INDEX_LABEL[0] \\\n            and len(self.training_data) >= TRAIN_DAT_LEN:\n            # swap index\n            self.swap_index(self.DB_disk_location)\n\n        # init batch write to DB\n        wb_ = self.KV_store.write_batch()\n        for idx_, doc_ in enumerate(documents):\n            cid_ = byt(doc_[\"CID\"])\n            # resize \"code\"\n            doc_[\"code\"] = self.resize_vector(doc_[\"code\"], int(os.environ[\"FIXED_VEC_DIMENSION\"]))\n            # cod_ = pickle.dumps(cod_)\n            documents[idx_][\"_id\"] = next_index\n\n            # TBD: convert to bulk insert\n            wb_.put(byt(next_index), byt(len(cid_)) + cid_ + CID.doc2bson(doc_))\n            wb_.put(cid_, byt(next_index))\n            \n            next_index += 1\n\n        wb_.put(byt(-1), byt(next_index))\n        # commit DB write\n        wb_.write()\n\n        # push to training data\n        self.update_training_data(documents)\n\n        # add vectors to index\n        return self.index.add_vectors(documents)\n\n    def delete_vectors (self, cids):\n        # get ids from cids\n        ids_ = []\n        wb_ = self.KV_store.write_batch()\n        for cid_ in cids:\n            id_ = self.KV_store.get(byt(cid_))\n            if id_:\n                ids_.append(int(id_))\n                wb_.delete(id_)\n        # commit db write\n        wb_.write()\n        # delete vectors by ID from index\n        status, ids = self.index.delete_vectors(ids_)\n\n        if status and len(ids) == len(cids):\n            return cids\n        else:\n            return []\n\n    def get_nearest (self, qmatrix, k, rad):\n        ids = []\n        dists = []\n\n        qmatrix = self.resize_matrix(qmatrix, int(os.environ[\"FIXED_VEC_DIMENSION\"]))\n\n        # radius defined, \n        if rad is not None:\n            if k is not None:\n                ids, dists = self.index.get_nearest_rad(qmatrix, rad)\n            else:\n                ids, dists = self.index.get_nearest_rad(qmatrix, rad)[:k]\n        else:\n            ids, dists = self.index.get_nearest_k(qmatrix, k)\n\n        # get docs\n        for idx_, idb in enumerate(ids):\n            for idx__, id_ in enumerate(idb):\n                value = self.KV_store.get(byt(id_))\n                if value:\n                    cid_len_ = int(value[:2]) + 2\n                    ids[idx_][idx__] = CID.bson2doc(value[cid_len_:])\n                else:\n                    ids[idx_][idx__] = None\n\n        return ids, dists\n        \n\n    def get_index (self, location):\n        index = None\n        annoy_location = location + \"/h_annoy\"\n        faiss_location = location + \"/h_faiss\"\n\n        if is_mini_instance == \"inactive\":\n            # try loading faiss\n            index = hfaiss.Faiss(faiss_location)\n            # check if faiss is not loaded,\n            if not index.is_initiated():\n                # destruct faiss\n                del index\n                # load annoy\n                index = hannoy.Annoy(annoy_location)\n                self.active_index = INDEX_LABEL[0]\n            else:\n                self.active_index = INDEX_LABEL[1]\n        else:\n            # load annoy\n            index = hannoy.Annoy(annoy_location)\n            self.active_index = INDEX_LABEL[0]\n\n        return index\n\n    def resize_vector (self, vector, dim):\n        # resize vectors\n        vector_l = len(vector)\n        # check if the vector length is below dimention limit\n        # then pad vector with 0 by dimension\n        if vector_l < dim:\n            vector.extend([0]*(dim-vector_l))\n        # make sure vector length doesn't exceed dimension limit\n        vector = vector[:dim]\n        return vector\n\n    def resize_matrix (self, matrix_, dim):\n        # numpize\n        matrix = np.array(matrix_)\n        # check for valid dimensions\n        if matrix.ndim < 2:\n            matrix = np.array([matrix_])\n        elif matrix.ndim > 2:\n            logging.error(\"Invalid query dimensions\")\n            return [[]]\n\n        # resize vectors\n        vector_l = len(matrix_[0])\n        # check if the vector length is below dimention limit\n        # then pad vector with 0 by dimension\n        if vector_l < dim:\n            matrix = np.pad(matrix, ((0, 0), (0, dim-vector_l)))\n        # make sure vector length doesn't exceed dimension limit\n        matrix = matrix[:, :dim]\n        # listize\n        return matrix.tolist()\n\n    def swap_index (self, location):\n        logging.debug(\"Swapping index to FAISS\")\n        \n        faiss_location = location + \"/h_faiss\"\n\n        # init faiss index\n        self.index = hfaiss.Faiss(faiss_location)\n\n        # train faiss index\n        self.index.init_faiss(self.training_data)\n\n        # migrate data\n        for idx_ in range(int(self.KV_store.get(byt(-1)))):\n            value = self.KV_store.get(byt(idx_))\n            \n            if value:\n                cid_len_ = int(value[:2]) + 2\n\n                self.index.add_vectors([{\n                    \"_id\": int(idx_),\n                    \"code\": CID.bson2doc(value[cid_len_:])[\"code\"]\n                }])\n\n        # set active index\n        self.active_index = INDEX_LABEL[1]\n\n    def update_training_data (self, documents):\n        # insert new vectors to array\n        self.pipeline.put(documents)\n\n    def save_TD_to_disk (self):\n        try:\n            # write index\n            np.save(self.TD_location, np.array(self.training_data))\n            logging.debug('Training data writing success')\n            return True\n        except Exception as e:\n            logging.error('Training data writing failed' + str(e))\n            return False\n\n    def load_TD_from_disk (self):\n        try:\n            # load training data\n            self.training_data = np.load(self.TD_location+'.npy').tolist()\n            logging.debug('Training data loaded successfully')\n            return True\n        except Exception as e:\n            logging.error('Training data loading failed' + str(e))\n            self.training_data = []\n            return False\n\n    def process (self):\n        while (self.process_flag):\n\n            # set a timeout\n            time.sleep(self.process_timeout_sec)\n\n            # check if queue is not empty\n            if not self.pipeline.empty():\n            \n                # fetch all currently available codes from queue\n                while not self.pipeline.empty():\n                    # pop available codes\n                    for doc_ in self.pipeline.get_nowait():\n                        self.training_data.append(doc_[\"code\"])\n\n                # shuffle array\n                random.shuffle(self.training_data)\n                # resize array\n                self.training_data = self.training_data[:TRAIN_DAT_LEN]\n                \n                # write to disk\n                self.save_TD_to_disk()\n\n    def spawn (self):\n        # create pipeline to add documents\n        self.pipeline = queue.Queue(maxsize=self.q_maxsize)\n        # create process thread\n        self.process_thread = threading.Thread(target=self.process, args=(), daemon=True)\n        # start process thread\n        self.process_thread.start()\n    \n"
  },
  {
    "path": "aquila/metricstore/router.py",
    "content": "import logging\nlogging.basicConfig()\nlogging.getLogger().setLevel(logging.DEBUG)\n\nimport manager\n\nimport os\nimport json\n\nfrom utils import CID, schema\n\nSTORE_LOCATION = os.environ[\"DATA_STORE_LOCATION\"]\n\n# databases dictionary\ndatabases = {}\n\ndef preload_databases ():\n    \"\"\"\n    Load available databases from disk\n    \"\"\"\n    # list database names\n    for content_ in os.listdir(STORE_LOCATION):\n        # simple validation for database name (CID lenngth)\n        if len(content_) >= 43: # TODO: 43 check is a bad method, replace it soon\n            database_name = content_\n\n            with open(STORE_LOCATION + database_name + \"/schema.json\") as ischema:\n                json_schema = json.load(ischema)\n\n            manager_h = manager.VecManager(json_schema)\n\n            # load and create databases dict\n            validator_fn = schema.compile(json_schema)\n            databases[database_name] = {\n                \"manager_h\": manager_h,\n                \"schema\": {\n                    \"json\": json_schema,\n                    \"validator\": validator_fn\n                }\n            }\n\n    logging.debug(\"Loaded all existing databases\")\n\ndef create_database (json_schema):\n    \"\"\"\n    Create a database from a given valid JSON schema\n    \"\"\"\n    # TBD: write ahead logging (INIT)\n\n    # generate proper schema definition from templete schema\n    json_schema = schema.generate_schema(json_schema)\n\n    # identify invalid schema template\n    if json_schema == None:\n        return None\n\n    # Check if database already exists\n    database_name = CID.doc2CID(json_schema)\n    if databases.get(database_name):\n        # return database name\n        logging.debug(\"Database already exists\")\n        return database_name\n\n    # If database doesn't exist already,\n    # then create one\n    manager_h = manager.VecManager(json_schema)\n\n    database_name = manager_h.database_name\n\n    validator_fn = schema.compile(json_schema)\n    databases[database_name] = {\n        \"manager_h\": manager_h,\n        \"schema\": {\n            \"json\": json_schema,\n            \"validator\": validator_fn\n        }\n    }\n\n    # TBD: save schema to storage\n    # TBD: write ahead logging (END)\n\n    return database_name\n\ndef load_database (database_name):\n    \"\"\"\n    Load an already existing database \n    \"\"\"\n\n    return databases.get(database_name)\n\ndef insert_docs (docs, database_name):\n    \"\"\"\n    Insert a set of valid documents to database\n    \"\"\"\n\n    # write ahead log (INIT)\n\n    cids_ = []\n    docs_ = []\n\n    # get manager_h for database_name\n    database_h = load_database(database_name)\n    # invalid database name\n    if not database_h:\n        logging.debug(\"Database doesn't exist. Please create one.\")\n        return cids_\n\n    # validate docs against schema\n    # and add CID\n    \n    for doc_ in docs:\n        payload = doc_[\"payload\"]\n        if schema.validate_json_docs(database_h[\"schema\"][\"validator\"], payload):\n            CID_ = CID.doc2CID(payload)\n            cids_.append(CID_)\n            payload[\"CID\"] = CID_\n            docs_.append(payload)\n        else:\n            cids_.append(None)\n            \n    # get manager_h for database_name\n    manager_h = database_h[\"manager_h\"]\n\n    manager_h.add_vectors(docs_)\n\n    # write ahead log (END)\n\n    return cids_\n\ndef delete_docs (ids, database_name):\n\n    # write ahead log (INIT)\n\n    # get manager_h for database_name\n    database_h = load_database(database_name)\n    # invalid database name\n    if not database_h:\n        logging.debug(\"Database doesn't exist. Please create one.\")\n        return []\n\n    return database_h[\"manager_h\"].delete_vectors(ids)\n\ndef search (matrix, k, rad, database_name):\n\n    # write ahead log (INIT)\n\n    # get manager_h for database_name\n    database_h = load_database(database_name)\n\n    return database_h[\"manager_h\"].get_nearest(matrix, k, rad)\n"
  },
  {
    "path": "aquila/metricstore/run_tests.sh",
    "content": "rm -r /data/*\n\npython3 -m unittest test.apis.db_fns -v\npython3 -m unittest test.apis.doc_fns -v\npython3 -m unittest test.apis.search_fns -v\npython3 -m unittest test.apis.auth_fns -v"
  },
  {
    "path": "aquila/metricstore/test/__init__.py",
    "content": ""
  },
  {
    "path": "aquila/metricstore/test/apis/auth_fns.py",
    "content": "import unittest\n\nimport index\nfrom utils import CID, schema\n\nfrom Crypto.Hash import SHA384\nfrom Crypto.PublicKey import RSA\nfrom Crypto.Signature import pkcs1_15\nimport base58\n\nimport requests\nfrom requests.structures import CaseInsensitiveDict\nimport json\nimport bson\n\nfrom multiprocessing import Process\n\n\n# load private key\nwith open(\"/ossl/private_unencrypted.pem\", \"r\") as pkf:\n    k = pkf.read()\n    priv_key = RSA.import_key(k)\n\nclass TestAuth (unittest.TestCase):\n\n    # A fresh DB is created\n    def test_1_auth_create_db (self):\n        # deploy app\n        server = Process(target=index.flaskserver)\n        server.start()\n\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd905\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 30,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        data_ = { \"schema\": schema_def }\n        data_bson = bson.dumps(data_)\n        # generate hash\n        hash = SHA384.new()\n        hash.update(data_bson)\n        \n        # Sign with pvt key\n        signer = pkcs1_15.new(priv_key)\n        signature = signer.sign(hash)\n        signature = base58.b58encode(signature).decode(\"utf-8\")\n\n        url = \"http://127.0.0.1:5001/db/create\"\n\n        headers = CaseInsensitiveDict()\n        headers[\"Content-Type\"] = \"application/json\"\n\n        data = {\n            \"data\": data_,\n            \"signature\": signature\n        }\n\n        data = json.dumps(data)\n\n\n        resp = requests.post(url, headers=headers, data=data)\n        \n        database_name_ = resp.json()[\"database_name\"]\n\n        schema_def = schema.generate_schema(schema_def)\n        database_name = CID.doc2CID(schema_def)\n\n        server.terminate()\n        server.join()\n\n        self.assertEqual(database_name, database_name_, \"DB name doesn't match\")\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "aquila/metricstore/test/apis/db_fns.py",
    "content": "import unittest\n\nimport index # includes preloading databases\nimport router\nfrom utils import CID, schema\n\nclass TestDB (unittest.TestCase):\n\n    # A fresh DB is created\n    def test_1_db_fresh_create (self):\n        schema_def1 = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd90\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        schema_def2 = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd90\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def1)\n\n        schema_def = schema.generate_schema(schema_def2)\n        database_name_ = CID.doc2CID(schema_def)\n\n        self.assertEqual(database_name, database_name_, \"DB name doesn't match\")\n\n    # An existing DB is created\n    def test_2_db_exist_create (self):\n        schema_def1 = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd90\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        schema_def2 = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd90\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def1)\n\n        schema_def = schema.generate_schema(schema_def2)\n        database_name_ = CID.doc2CID(schema_def)\n\n        self.assertEqual(database_name, database_name_, \"DB name doesn't match\")\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "aquila/metricstore/test/apis/doc_fns.py",
    "content": "import unittest\n\nimport index # includes preloading databases\nimport router\nfrom utils import CID\nimport numpy as np\n\nimport time\n\nclass TestDocs (unittest.TestCase):\n\n    # A fresh doc is created\n    def test_1_doc_fresh_create (self):\n        # create database\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd901\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def)\n\n        # add document\n        docs = [{\n                \"metadata\": {\n                    \"name\":\"name1\", \n                    \"age\": 20\n                },\n                \"code\": [1,2,3]\n            }, {\n                    \"metadata\": {\n                    \"name\":\"name2\", \n                    \"age\": 30\n                },\n                \"code\": [1,2,3]\n            }]\n        cids = router.insert_docs(docs, database_name)\n\n        self.assertEqual(len(cids), len(docs), \"Document creation failed\")\n\n    # An incomplete doc is created\n    def test_1a_doc_incomplete_create (self):\n        # create database\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd901\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def)\n\n        # add document with \"code\" missing\n        docs = [{\n                \"metadata\": {\n                    \"name\":\"name1\", \n                    \"age\": 20\n                }\n            }, {\n                    \"metadata\": {\n                    \"name\":\"name2\", \n                    \"age\": 30\n                }\n            }]\n        cids = router.insert_docs(docs, database_name)\n\n        self.assertEqual(cids, [None, None], \"Document creation test failed\")\n\n    # An existing doc is created\n    def test_2_doc_exist_create (self):\n        # create database\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd901\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def)\n\n        # add existing document\n        docs = [{\n                \"metadata\": {\n                    \"name\":\"name1\", \n                    \"age\": 20\n                },\n                \"code\": [1,2,3]\n            }, {\n                    \"metadata\": {\n                    \"name\":\"name2\", \n                    \"age\": 30\n                },\n                \"code\": [1,2,3]\n            }]\n        cids = router.insert_docs(docs, database_name)\n\n        self.assertEqual(len(cids), len(docs), \"Document creation failed\")\n\n    # A non existing DB is used to create doc\n    def test_3_db_fresh_doc_create (self):\n        # create random DB name\n        database_name = \"BRANDOM\"\n\n        # add existing document\n        docs = [{\n                \"metadata\": {\n                    \"name\":\"name1\", \n                    \"age\": 20\n                },\n                \"code\": [1,2,3]\n            }, {\n                    \"metadata\": {\n                    \"name\":\"name2\", \n                    \"age\": 30\n                },\n                \"code\": [1,2,3]\n            }]\n        cids = router.insert_docs(docs, database_name)\n\n        self.assertEqual(len(cids), 0, \"Document creation failed\")\n\n    # A fresh doc is deleted\n    def test_4_doc_fresh_delete (self):\n        # create database\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd901fr\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 3,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def)\n\n        # delete non existing documents\n        cids = router.delete_docs([\"sdfsdfsdf\", \"tret456\"], database_name)\n\n        self.assertEqual(len(cids), 0, \"Doc deletion failed\")\n\n    # An existing doc is deleted for small dataset\n    def test_5a_doc_exist_delete_small (self):\n        # create database\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd902\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 100,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def)\n\n        # add small epoch document\n        docs = []\n        # create special doc\n        matrix_r_spec = np.random.rand(1, 100)\n        docs.append({\n            \"metadata\": {\"name\":\"special\", \"age\":11},\n            \"code\": matrix_r_spec[0].tolist()\n        })\n        cids_spec = router.insert_docs(docs, database_name)\n\n        # create other docs\n        for _ in range(90):\n            docs = []\n            # create random matrix\n            matrix_r = np.random.rand(100, 100)\n            # create documents\n            for item in matrix_r:\n                docs.append({\n                    \"metadata\": {\"name\":\"generic\", \"age\":10},\n                    \"code\": item.tolist()\n                })\n            \n            cids = router.insert_docs(docs, database_name)\n\n        # check for doc existance\n        k = 2\n        docs, dists = router.search([matrix_r_spec[0].tolist()], k, None, database_name)\n        self.assertEqual(docs[0][0][\"metadata\"][\"name\"], \"special\", \"Doc doesn't exist\")\n\n        # delete special doc\n        cids = router.delete_docs(cids_spec, database_name)\n        time.sleep(10)\n\n        # check for doc existance\n        k = 2\n        docs, dists = router.search([matrix_r_spec[0].tolist()], k, None, database_name)\n        self.assertEqual(len(docs[0]), k, \"Doc deletion failed\")\n        self.assertEqual(docs[0][0][\"metadata\"][\"name\"], \"generic\", \"Doc deletion failed\")\n\n    # An existing doc is deleted for large dataset\n    def test_5b_doc_exist_delete_large (self):\n        # create database\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd902\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 100,\n            \"metadata\": {\n                \"name\": \"string\",\n                \"age\": \"number\"\n            }\n        }\n        database_name = router.create_database(schema_def)\n\n        # add small epoch document\n        docs = []\n        # create special doc\n        matrix_r_spec = np.random.rand(1, 100)\n        docs.append({\n            \"metadata\": {\"name\":\"special\", \"age\":11},\n            \"code\": matrix_r_spec[0].tolist()\n        })\n        cids_spec = router.insert_docs(docs, database_name)\n\n        # create other docs\n        for _ in range(120):\n            docs = []\n            # create random matrix\n            matrix_r = np.random.rand(100, 100)\n            # create documents\n            for item in matrix_r:\n                docs.append({\n                    \"metadata\": {\"name\":\"generic\", \"age\":10},\n                    \"code\": item.tolist()\n                })\n            \n            cids = router.insert_docs(docs, database_name)\n\n        time.sleep(60)\n        # check for doc existance\n        k = 2\n        docs, dists = router.search([matrix_r_spec[0].tolist()], k, None, database_name)\n        self.assertEqual(docs[0][0][\"metadata\"][\"name\"], \"special\", \"Doc doesn't exist\")\n\n        # delete special doc\n        cids = router.delete_docs(cids_spec, database_name)\n        time.sleep(60)\n\n        # check for doc existance\n        k = 2\n        docs, dists = router.search([matrix_r_spec[0].tolist()], k, None, database_name)\n        \n        self.assertEqual(len(docs[0]), k, \"Doc deletion failed\")\n        self.assertEqual(docs[0][0][\"metadata\"][\"name\"], \"generic\", \"Doc deletion failed\")\n\n    # A non existing DB is used to delete doc\n    def test_6_db_fresh_doc_delete (self):\n        # create random DB name\n        database_name = \"BRANDOM\"\n\n        # delete non existing documents\n        cids = router.delete_docs([\"sdfsdfsdf\", \"tret456\"], database_name)\n\n        self.assertEqual(len(cids), 0, \"Doc deletion failed\")\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "aquila/metricstore/test/apis/search_fns.py",
    "content": "import unittest\n\nimport time\n\nimport index # includes preloading databases\nimport router\nfrom utils import CID\n\nimport numpy as np\n\nclass TestSearch (unittest.TestCase):\n\n    # Perform search on small data\n    def test_1_insert_and_search_small (self):\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd903\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 100,\n            \"metadata\": {}\n        }\n        database_name = router.create_database(schema_def)\n\n        # insert documents in bulk --------------------\n        for i_ in range(99):\n            # create random matrix\n            matrix_r = np.random.rand(100, 100)\n            # create documents\n            docs = []\n            for item in matrix_r:\n                docs.append({\n                \"metadata\": {},\n                \"code\": item.tolist()\n            })\n\n            cids = router.insert_docs(docs, database_name)\n\n        k = 10\n        docs, dists = router.search(np.random.rand(1, 784), k, None, database_name)\n\n        self.assertEqual(k, len(docs[0]), \"Search failed\")\n\n    # Perform search on large data\n    def test_2_insert_and_search_large (self):\n        schema_def = {\n            \"description\": \"this is my database\",\n            \"unique\": \"r8and0mseEd904\",\n            \"encoder\": \"example.com/autoencoder/API\",\n            \"codelen\": 100,\n            \"metadata\": {}\n        }\n        database_name = router.create_database(schema_def)\n\n        # insert documents in bulk --------------------\n        for i_ in range(120):\n            # create random matrix\n            matrix_r = np.random.rand(100, 100)\n            # create documents\n            docs = []\n            for item in matrix_r:\n                docs.append({\n                \"metadata\": {},\n                \"code\": item.tolist()\n            })\n\n            cids = router.insert_docs(docs, database_name)\n\n        # time.sleep(5)\n\n        k = 10\n        docs, dists = router.search(np.random.rand(1, 784), k, None, database_name)\n\n        self.assertEqual(k, len(docs[0]), \"Search failed\")\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "aquila/metricstore/utils/CID.py",
    "content": "import logging\n\nimport bson\nimport hashlib\nimport base58\n\ndef doc2CID (inp):\n    try:\n        # JSON OBJ to BSON encode\n        bson_ = bson.dumps(inp)\n        # SHA-256 Double Hashing\n        hash_ = hashlib.sha256(bson_)\n        hash_ = hashlib.sha256(hash_.digest())\n        # Convert to Base-58 string\n        b58c_ = base58.b58encode(hash_.digest())\n\n        return b58c_.decode('utf-8')\n    except Exception as e:\n        logging.debug(e)\n        return None\n\ndef doc2bson (inp):\n    try:\n        # JSON OBJ to BSON encode\n        bson_ = bson.dumps(inp)\n\n        return bson_\n    except Exception as e:\n        logging.debug(e)\n        return None\n\ndef bson2doc (inp):\n    try:\n        # BSON to JSON OBJ\n        json_ = bson.loads(inp)\n\n        return json_\n    except Exception as e:\n        logging.debug(e)\n        return None"
  },
  {
    "path": "aquila/metricstore/utils/config.py",
    "content": "import yaml\nimport os\n\nos.environ[\"DATA_STORE_LOCATION\"] = \"/data/\"\nos.environ[\"LOG_CHUNK_LEN\"] = \"1000\"\n\nif \"MINI_AQDB\" not in os.environ:\n    os.environ[\"MINI_AQDB\"] = \"inactive\"\nelse:\n    os.environ[\"MINI_AQDB\"] = \"active\"\n\nwith open(\"DB_config.yml\", \"r\") as stream:\n    DB_config = yaml.safe_load(stream)\n    \n    if \"AUTH_KEY_FILE\" not in os.environ:\n        os.environ[\"AUTH_KEY_FILE\"] = str(DB_config[\"auth\"][\"pubkey\"])\n    \n    if \"FIXED_VEC_DIMENSION\" not in os.environ:\n        os.environ[\"FIXED_VEC_DIMENSION\"] = str(DB_config[\"docs\"][\"vd\"])\n\n    if \"MIN_SAWP_COUNT\" not in os.environ:\n        os.environ[\"MIN_SAWP_COUNT\"] = str(DB_config[\"docs\"][\"cswap\"])\n    \n    if \"FIXED_Q_LEN\" not in os.environ:\n        os.environ[\"FIXED_Q_LEN\"] = str(DB_config[\"queue\"][\"qlen\"])\n\n    if \"THREAD_SLEEP\" not in os.environ:\n        os.environ[\"THREAD_SLEEP\"] = str(DB_config[\"queue\"][\"sleep\"])\n\n    if \"FAISS_MAX_CELLS\" not in os.environ:\n        os.environ[\"FAISS_MAX_CELLS\"] = str(DB_config[\"faiss\"][\"init\"][\"nlist\"])\n\n    if \"FAISS_VISIT_CELLS\" not in os.environ:\n        os.environ[\"FAISS_VISIT_CELLS\"] = str(DB_config[\"faiss\"][\"init\"][\"nprobe\"])\n\n    if \"FAISS_BYTES_PER_VEC\" not in os.environ:\n        os.environ[\"FAISS_BYTES_PER_VEC\"] = str(DB_config[\"faiss\"][\"init\"][\"bpv\"])\n\n    if \"FAISS_BYTES_PER_SUB_VEC\" not in os.environ:\n        os.environ[\"FAISS_BYTES_PER_SUB_VEC\"] = str(DB_config[\"faiss\"][\"init\"][\"bpsv\"])\n\n    if \"ANNOY_SIM_METRIC\" not in os.environ:\n        os.environ[\"ANNOY_SIM_METRIC\"] = str(DB_config[\"annoy\"][\"init\"][\"smetric\"])\n\n    if \"ANNOY_NTREES\" not in os.environ:\n        os.environ[\"ANNOY_NTREES\"] = str(DB_config[\"annoy\"][\"init\"][\"ntrees\"])\n\n    if \"ANNOY_SK\" not in os.environ:\n        os.environ[\"ANNOY_SK\"] = str(DB_config[\"annoy\"][\"init\"][\"search_k\"])\n"
  },
  {
    "path": "aquila/metricstore/utils/cryptops.py",
    "content": "import logging\n\nfrom Crypto.Hash import SHA384\nfrom Crypto.PublicKey import RSA\nfrom Crypto.Signature import pkcs1_15\n\nimport base58\n\nimport chardet\n\nimport bson\n\ndef read_public_key (location):\n    # disk read public key\n    with open(location, \"r\") as pkf:\n        k = pkf.read()\n        pub_key = RSA.import_key(k)\n\n        return pub_key\n\ndef verify_signature (json_data, pub_key, signature):\n    \n    ret = True\n\n    binary_data = bson.dumps(json_data)\n\n    # generate hash\n    hash = SHA384.new()\n    hash.update(binary_data)\n    \n    signature = base58.b58decode(signature)\n\n    # Verify with pub key\n    verifier = pkcs1_15.new(pub_key)\n    \n    try:\n        verifier.verify(hash, signature)\n    except Exception as e:\n        logging.debug(e)\n        ret = False\n\n    return ret"
  },
  {
    "path": "aquila/metricstore/utils/schema.py",
    "content": "import logging\n\nimport fastjsonschema\n\ndef generate_schema (template):\n    # get all keys from template schema\n    metadata_templ = template.get(\"metadata\")\n    if metadata_templ:\n        del template[\"metadata\"]\n    else:\n        metadata_templ = {}\n\n    keys_ = list(template.keys())\n\n    # sort keys\n    keys_.sort()\n\n    # validate required keys\n    req_k = [\"description\", \"encoder\", \"unique\"]\n    for r_ in req_k:\n        if r_ not in keys_:\n            # cannot continue, invalid schema\n            return None\n\n    # generate schema in sorted keys\n    generated_schema = { \n        \"$schema\": \"http://json-schema.org/schema#\", \n        \"$id\": \"http://aquilanetwork.com/schema/id/v1\", \n        \"title\": \"Schema\", \n        \"description\": \"\",\n        \"encoder\": \"\",\n        \"unique\": \"\",\n        \"type\": \"object\",\n        \"properties\": {\n            \"code\": {\n                \"description\": \"Encoded data\",\n                \"type\": \"array\",\n                \"items\": {\n                    \"type\": \"number\"\n                }\n            },\n            \"metadata\": {\n                \"$ref\": \"#/definitions/metadata\"\n            }\n        },\n        \"definitions\": {\n            \"metadata\": {\n                \"description\": \"User defined metadata\",\n                \"type\": \"object\",\n                \"properties\": {},\n                \"required\": []\n            }\n        },\n        \"required\": [\"code\", \"metadata\"]\n    }\n\n    metadata = {}\n    metadata_types = [\"number\", \"string\"]\n\n    for key_ in keys_:\n        if key_ in req_k:\n            # fill in root level keys\n            generated_schema[key_] = template[key_]\n        elif key_ == \"codelen\":\n            generated_schema[\"properties\"][\"code\"][\"maxItems\"] = template[key_]\n        else:\n            # fill in root level keys :: extra info that we don't care\n            generated_schema[key_] = template[key_]\n\n    for key_ in metadata_templ.keys():\n        # check type is predefined\n        if metadata_templ[key_] not in metadata_types:\n            return None\n\n        # fill in metadata keys\n        metadata[key_] = {\n            \"type\": metadata_templ[key_]\n        }\n\n    generated_schema[\"definitions\"][\"metadata\"][\"properties\"] = metadata\n    generated_schema[\"definitions\"][\"metadata\"][\"required\"] = list(metadata.keys())\n\n\n    # validate values\n    if type(generated_schema[\"properties\"][\"code\"].get(\"maxItems\")) != int:\n        return None\n        \n    return generated_schema\n\ndef compile (schema_def):\n    # compile schema\n    validator = fastjsonschema.compile(schema_def)\n\n    return validator\n\ndef validate_json_docs (validator, json_doc):\n    try:\n        # validate doc on schema :: will except on fail\n        validator(json_doc)\n        # validated\n        # logging.debug(\"Schema validation success\")\n        return True\n    except Exception as e:\n        logging.error(e)\n        return False\n"
  },
  {
    "path": "aquila/metricstore/vec_index/hannoy.py",
    "content": "import logging\n\nimport numpy as np\nfrom annoy import AnnoyIndex\nimport yaml\nimport os\n\nimport threading\nimport queue\nimport time\n\nclass Annoy:\n    def __init__(self, model_location):\n        # set model location\n        self.model_location = model_location\n\n        # to keep the thread & queue running\n        self.process_flag = True\n        self.q_maxsize = int(os.environ[\"FIXED_Q_LEN\"])\n        self.build_batch_size = int(os.environ[\"FIXED_Q_LEN\"])\n        self.process_thread = None\n        self._lock = threading.Lock()\n        self.process_timeout_sec = int(os.environ[\"THREAD_SLEEP\"]) # seconds\n        # this is to keep track of all vectors inserted\n        # for saving into disk and retrieve later\n        self.index_disk = None\n        try:\n            # make sure to parse env variables to their expected type\n            self.dim = int(os.environ[\"FIXED_VEC_DIMENSION\"])\n            self.sim_metric = str(os.environ[\"ANNOY_SIM_METRIC\"])\n            self.n_trees = int(os.environ[\"ANNOY_NTREES\"])\n            self.search_k = int(os.environ[\"ANNOY_SK\"])\n            self.model_loaded = self.load_model_from_disk()\n            if not self.model_loaded:\n                if self.init_annoy():\n                    logging.debug(\"Annoy Init done\")\n                else:\n                    logging.debug(\"Annoy Init Failed\")\n        except Exception as e:\n            logging.error('Error initializing Annoy: ' + e)\n\n        # spawn process thread\n        self.spawn()\n\n    def __del__(self):\n        self.process_flag = False\n        if self.process_thread:\n            self.process_thread.join()\n\n    def spawn (self):\n        # create pipeline to add documents\n        self.pipeline = queue.Queue(maxsize=self.q_maxsize)\n        # create process thread\n        self.process_thread = threading.Thread(target=self.process, args=(), daemon=True)\n        # start process thread\n        self.process_thread.start()\n        # return self.pipeline\n\n    def init_annoy(self):\n        # only do if no index loaded from disk\n        if not self.model_loaded:\n            logging.debug('Annoy init index')\n            self.a_index = AnnoyIndex(self.dim, self.sim_metric)\n\n        # Lock index read / wtite until it is built\n        with self._lock:\n            # build index\n            build_ = self.a_index.build(self.n_trees)\n\n            if build_:\n                self.model_loaded = self.save_model_to_disk()\n\n        return self.model_loaded\n\n    def add_vectors(self, documents):\n        # add documents to queue\n        self.pipeline.put({\"action\":\"add\", \"docs\": documents})\n        \n        return True\n\n    def process(self):\n        while (self.process_flag):\n            # set a timeout till next vector indexing\n            time.sleep(self.process_timeout_sec)\n\n            # check if queue is not empty\n            if self.pipeline.qsize() > 0:\n                # Lock index read / wtite until it is built\n                with self._lock:\n\n                    # unbuild index first \n                    self.a_index.unbuild()\n                    len_documents = 0\n\n                    # fetch all currently available documents from queue\n                    while not self.pipeline.empty():\n                        # extract document & contents\n                        qitem = self.pipeline.get_nowait()\n                        if qitem[\"action\"] == \"add\":\n                            documents = qitem[\"docs\"]\n                            len_documents += len(documents)\n                            for document in documents:\n                                _id = document[\"_id\"]\n                                vector_e = document[\"code\"]\n                            \n                                # add vector to index\n                                self.a_index.add_item(int(_id), vector_e)\n                                # append to disk proxy\n                                if self.index_disk is None:\n                                    self.index_disk = np.array([vector_e + [int(_id)]], dtype=float)\n                                else:\n                                    self.index_disk = np.append(self.index_disk, [vector_e + [int(_id)]], axis=0)\n                        elif qitem[\"action\"] == \"delete\":\n                            ids = qitem[\"ids\"]\n                            len_documents += len(ids)\n                            # reset\n                            zero_ = np.zeros(self.dim + 1)\n                            for id_ in ids:\n                                # add zero vector to index\n                                self.a_index.add_item(int(id_), zero_[:-1].tolist())\n                            # reset npy disk array\n                            if self.index_disk is not None:\n                                self.index_disk[ids] = zero_\n\n                        # take a rest if doc length is > batch_size\n                        if len_documents > self.build_batch_size:\n                            break\n                    \n                    # build vector\n                    build_ = self.a_index.build(self.n_trees, n_jobs=-1)\n\n                # write to disk\n                if build_:\n                    self.model_loaded = self.save_model_to_disk()\n\n    def delete_vectors(self, ids):\n        # add documents to queue\n        self.pipeline.put({\"action\":\"delete\", \"ids\": ids})\n\n        return True, ids\n\n    def get_nearest_k(self, matrix, k):\n        ids = []\n        dists = []\n\n        # Lock index read / wtite until nearest neighbor search\n        with self._lock:\n            for vec_data in matrix:\n                if self.search_k != -1:\n                    _id, _dist = self.a_index.get_nns_by_vector(vec_data, k, self.search_k, include_distances=True)\n                else: \n                    _id, _dist = self.a_index.get_nns_by_vector(vec_data, k, include_distances=True)\n            ids.append(_id)\n            dists.append(_dist)\n\n        return ids, dists\n\n    def get_nearest_rad(self, matrix, rad):\n        ids = []\n        dists = []\n\n        # Lock index read / wtite until nearest neighbor search\n        with self._lock:\n            for vec_data in matrix:\n                if self.search_k != -1:\n                    _id, _dist = self.a_index.get_nns_by_vector(vec_data, k, self.search_k, include_distances=True)\n                else: \n                    _id, _dist = self.a_index.get_nns_by_vector(vec_data, k, include_distances=True)\n            ids.append(_id)\n            dists.append(_dist)\n\n        return ids, dists\n\n    def load_model_from_disk(self):\n        try:\n            # prepare new index\n            self.a_index = AnnoyIndex(self.dim, self.sim_metric)\n            # read index\n            self.index_disk = np.load(self.model_location+'.npy')\n            # build Annoy Index\n            for vec_ in self.index_disk.tolist():\n                self.a_index.add_item(int(vec_[-1]), vec_[0:-1])\n            # build index\n            build_ = self.a_index.build(self.n_trees)\n            logging.debug('Annoy index loading success')\n            return True\n        except Exception as e: \n            logging.debug('Annoy index loading failed. Creating new index..')\n            return False\n\n    def save_model_to_disk(self):\n        try:\n            # write index\n            np.save(self.model_location, self.index_disk)\n            logging.debug('Annoy index writing success')\n            return True\n        except Exception as e:\n            logging.error('Annoy index writing failed' + e)\n            return False\n"
  },
  {
    "path": "aquila/metricstore/vec_index/hfaiss.py",
    "content": "import logging\n\nimport numpy as np\nimport faiss\nimport yaml\n\nimport os\nimport threading\nimport queue\nimport time\n\nclass Faiss:\n    def __init__(self, model_location):\n        # set model location\n        self.model_location = model_location\n\n        self.is_active = False\n        self.nlist = int(os.environ[\"FAISS_MAX_CELLS\"])\n        self.nprobe = int(os.environ[\"FAISS_VISIT_CELLS\"])\n        self.bytesPerVec = int(os.environ[\"FAISS_BYTES_PER_VEC\"])\n        self.bytesPerSubVec = int(os.environ[\"FAISS_BYTES_PER_SUB_VEC\"])\n        \n        # make sure to parse env variables to their expected type\n        self.dim = int(os.environ[\"FIXED_VEC_DIMENSION\"])\n\n        self.model_loaded = self.load_model_from_disk(self.model_location)\n        self.is_initiated_ = self.model_loaded\n\n        # to keep the thread & queue running\n        self.process_flag = True\n        self.q_maxsize = int(os.environ[\"FIXED_Q_LEN\"])\n        self.process_thread = None\n        self._lock = threading.Lock()\n        self.process_timeout_sec = int(os.environ[\"THREAD_SLEEP\"]) # seconds\n\n        # spawn process thread\n        self.spawn()\n\n    def __del__(self):\n        self.process_flag = False\n        if self.process_thread:\n            self.process_thread.join()\n\n    def spawn (self):\n        # create pipeline to add documents\n        self.pipeline = queue.Queue(maxsize=self.q_maxsize)\n        # create process thread\n        self.process_thread = threading.Thread(target=self.process, args=(), daemon=True)\n        # start process thread\n        self.process_thread.start()\n        # return self.pipeline\n\n    def init_faiss(self, matrix):\n        self.train_data = np.matrix(matrix).astype('float32')\n        logging.debug('FAISS init quantizer')\n        self.f_quantizer = faiss.IndexFlatIP(self.dim)\n        # Lock index read / wtite until it is built\n        with self._lock:\n            logging.debug('FAISS init index')\n            self.f_index = faiss.IndexIVFPQ(self.f_quantizer, self.dim, self.nlist, self.bytesPerVec, self.bytesPerSubVec)\n            logging.debug('FAISS train index')\n            self.f_index.train(self.train_data)\n            logging.debug('FAISS train index finished')\n\n            # write index to disk\n            self.model_loaded = self.save_model_to_disk(self.model_location, self.f_index)\n        self.is_initiated_ = self.model_loaded\n\n        return self.is_initiated_\n\n    def is_initiated(self):\n        return self.is_initiated_\n\n    def load_model_from_disk(self, location):\n        try:\n            # read index\n            self.f_index = faiss.read_index(location)\n            logging.debug('FAISS index loading success')\n            return True\n        except Exception as e: \n            logging.error('FAISS index loading failed' + str(e))\n            return False\n\n    def save_model_to_disk(self, location, index):\n        try:\n            # write index\n            faiss.write_index(index, location)\n            logging.debug('FAISS index writing success')\n            return True\n        except:\n            logging.error('FAISS index writing failed')\n            return False\n\n    def add_vectors(self, documents):\n        # add document to queue\n        self.pipeline.put({\"action\":\"add\", \"docs\": documents})\n        \n        return True\n\n    def process(self):\n        while (self.process_flag):\n            # set a timeout till next vector indexing\n            time.sleep(self.process_timeout_sec)\n\n            # check if queue is not empty\n            if self.pipeline.qsize() > 0:\n                ids = []\n                vecs = []\n                # f_delete = False\n                # f_add = False\n\n                # fetch all currently available documents from queue\n                while not self.pipeline.empty():\n                    # extract document & contents\n                    qitem = self.pipeline.get_nowait()\n                    if qitem[\"action\"] == \"add\":\n                        # f_add = True\n                        documents = qitem[\"docs\"]\n                        for document in documents:\n                            _id = document[\"_id\"]\n                            vector_e = document[\"code\"]\n                            ids.append(_id)\n                            vecs.append(vector_e)\n                    elif qitem[\"action\"] == \"delete\":\n                        # f_delete = True\n                        ids = qitem[\"ids\"]\n                        # remove vectors and add zero reset\n                        self.f_index.remove_ids(np.array(ids).astype('int'))\n                        vecs = np.zeros((len(ids), self.dim))\n\n                # if f_add:\n                # convert to np matrix\n                vec_data = np.matrix(vecs).astype('float32')\n                id_data = np.array(ids).astype('int')\n\n                # Lock index read / wtite until it is built\n                with self._lock:\n                    # add vectors\n                    self.f_index.add_with_ids(vec_data, id_data)\n\n                # if f_delete:\n                    # pass\n                \n                # write to disk\n                self.save_model_to_disk(self.model_location, self.f_index)\n\n    def delete_vectors(self, ids):\n        # remove vectors\n        self.pipeline.put({\"action\":\"delete\", \"ids\": ids})\n        \n        return True, ids\n\n    def get_nearest_rad(self, matrix, rad):\n        pass\n        # # convert to np matrix\n        # vec_data = np.matrix(matrix).astype('float32')\n        \n        # # Lock index read / wtite until nearest neighbor search\n        # with self._lock:\n        #     D, I = self.f_index.search(vec_data, k)\n        # return I.tolist(), D.tolist()\n\n    def get_nearest_k(self, matrix, k):\n        # convert to np matrix\n        vec_data = np.matrix(matrix).astype('float32')\n        \n        # Lock index read / wtite until nearest neighbor search\n        with self._lock:\n            D, I = self.f_index.search(vec_data, k)\n        return I.tolist(), D.tolist()\n"
  },
  {
    "path": "aquila/metricstore/wal/walman.py",
    "content": "import logging\n\nimport os\nimport time\nimport queue\nimport threading\n\nLOG_STORE_LOCATION = os.environ[\"DATA_STORE_LOCATION\"] + \"/log/\"\nLOG_CHUNK_LEN = int(os.environ[\"LOG_CHUNK_LEN\"])\nPROCESS_TIMEOUT = int(os.environ[\"THREAD_SLEEP\"])\nMAX_Q_LEN = int(os.environ[\"FIXED_Q_LEN\"])\n\nprocess_flag = True\npipeline = None\nprocess_thread = None\n\n# list logs in log directory\nlog_files_asc = os.listdir(LOG_STORE_LOCATION).sort()\n\n# load last log chunk\nlast_chunk_name = log_files_asc[-1]\nlast_chunk_data_len = 0\n\n# read last chunk\nwith open(LOG_STORE_LOCATION + last_chunk_name) as flog:\n    # check if the file is full capacity\n    if len(flog.split(\"\\n\")) >= LOG_CHUNK_LEN:\n        create_new_chunk()\n    else:\n        last_chunk_data_len = len(flog.split(\"\\n\"))\n\ndef create_new_chunk ():\n    global log_files_asc\n    global last_chunk_name\n    global last_chunk_data_len\n\n    # name a new log file\n    new_f_name = time.time()\n    log_files_asc.append(new_f_name)\n    last_chunk_name = new_f_name\n\n    # initialize log file\n    with open(LOG_STORE_LOCATION + last_chunk_name, \"a\") as aflog:\n        aflog.write(\"WALOG INIT\")\n        last_chunk_data_len = 1\n\ndef spawn ():\n    # spawn worker thread\n    global process_flag\n    process_flag = True\n    # create pipeline to add documents\n    global pipeline\n    pipeline = queue.Queue(maxsize=MAX_Q_LEN)\n    # create process thread\n    global process_thread\n    process_thread = threading.Thread(target=process, args=(), daemon=True)\n    # start process thread\n    process_thread.start()\n\ndef add_log (batch_in):\n    global pipeline\n    pipeline.put(batch_in)\n    return True\n\ndef terminate ():\n    global process_flag\n    process_flag = False\n\ndef process ():\n    global pipeline\n\n    while (process_flag):\n        time.sleep(PROCESS_TIMEOUT)\n        \n        # check if queue is not empty\n        if not pipeline.empty():\n            # fetch all currently available codes from queue\n            while not pipeline.empty():\n                # pop available logs\n                for batch in pipeline.get_nowait():\n                    for log_ in batch:\n                        # check if the batch length exceeded\n                        if last_chunk_data_len + 1 >= LOG_CHUNK_LEN:\n                            create_new_chunk()\n\n                        # write log to disk\n                        with open(LOG_STORE_LOCATION + last_chunk_name, \"a\") as aflog:\n                            aflog.write(\"\\n\" + log_)\n"
  },
  {
    "path": "aquila/metricstore/wal/walmon.py",
    "content": ""
  },
  {
    "path": "aquila/network/go.mod",
    "content": "module aquilaport\n\ngo 1.15\n\nrequire (\n\tgithub.com/gorilla/mux v1.8.0\n\tgithub.com/syndtr/goleveldb v1.0.0\n\tgo.mongodb.org/mongo-driver v1.4.4\n)\n"
  },
  {
    "path": "aquila/network/go.sum",
    "content": "github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=\ngithub.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=\ngithub.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=\ngithub.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=\ngithub.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=\ngithub.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=\ngithub.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=\ngithub.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=\ngithub.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=\ngithub.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=\ngithub.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=\ngithub.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=\ngithub.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=\ngithub.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=\ngithub.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=\ngithub.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=\ngithub.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=\ngithub.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=\ngithub.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=\ngithub.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=\ngithub.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=\ngithub.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=\ngithub.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=\ngithub.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=\ngithub.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=\ngithub.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=\ngithub.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=\ngithub.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=\ngithub.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=\ngithub.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=\ngithub.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=\ngithub.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=\ngithub.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=\ngithub.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=\ngithub.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=\ngithub.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=\ngo.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs=\ngo.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=\ngolang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "aquila/network/main.go",
    "content": "// main.go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/http/cookiejar\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gorilla/mux\"\n\t\"github.com/syndtr/goleveldb/leveldb\"\n\t\"go.mongodb.org/mongo-driver/bson\"\n)\n\nvar _localDb, _ = leveldb.OpenFile(\"./db/_local\", nil)\nvar replicationDb, _ = leveldb.OpenFile(\"./db/replication\", nil)\nvar sourceDb, _ = leveldb.OpenFile(\"./db/source\", nil)\n\nvar jar, err = cookiejar.New(nil)\n\n// if err != nil {\n//     fmt.Println(err)\n// }\n\n// Document struct\ntype Document struct {\n\tID        string `json:\"id\"`\n\tTitle     string `json:\"title\"`\n\tDeleted   bool   `json:\"deleted\"`\n\tTimestamp string `json:\"timestamp\"`\n\tVersion   string `json:\"version\"`\n}\n\nfunc homePage(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"Welcome to the HomePage!\")\n\tfmt.Println(\"Endpoint Hit: homePage\")\n}\n\nfunc createNewDocument(w http.ResponseWriter, r *http.Request) {\n\t// decode json body\n\tvar documents []Document\n\tjson.NewDecoder(r.Body).Decode(&documents)\n\n\t// init a batch insert to level\n\tbatch := new(leveldb.Batch)\n\n\t// insert docs to batch\n\tfor _, doc := range documents {\n\t\t// update document version\n\t\tdoc.Version = string(getVersion(doc))\n\t\t// convert struct to bson\n\t\tdata, err := bson.Marshal(doc)\n\t\tfmt.Println(err)\n\t\t// insert doc\n\t\tbatch.Put([]byte(doc.ID), data)\n\t}\n\n\t// write batch to level db\n\terr := sourceDb.Write(batch, nil)\n\tfmt.Println(err)\n\n\t// iterate over leveldb and get key, val\n\titer := sourceDb.NewIterator(nil, nil)\n\tfor iter.Next() {\n\t\tkey := iter.Key()\n\t\tvalue := iter.Value()\n\n\t\tvar docRet Document\n\t\t// convert bson to byte\n\t\tbson.Unmarshal(value, &docRet)\n\n\t\tfmt.Println(string(key), docRet)\n\t}\n\titer.Release()\n\terr = iter.Error()\n\n\tjson.NewEncoder(w).Encode(documents)\n}\n\nfunc deleteDocument(w http.ResponseWriter, r *http.Request) {\n\tvar ids []string\n\n\tjson.NewDecoder(r.Body).Decode(&ids)\n\n\t// init a batch insert to level\n\tbatch := new(leveldb.Batch)\n\n\t// delete docs batch\n\tfor _, id := range ids {\n\t\t// delete doc\n\t\tbatch.Delete([]byte(id))\n\t}\n\n\t// write batch to level db\n\terr := sourceDb.Write(batch, nil)\n\tfmt.Println(err)\n\n\t// iterate over leveldb and get key, val\n\titer := sourceDb.NewIterator(nil, nil)\n\tfor iter.Next() {\n\t\tkey := iter.Key()\n\t\tvalue := iter.Value()\n\n\t\tvar docRet Document\n\t\t// convert bson to byte\n\t\tbson.Unmarshal(value, &docRet)\n\n\t\tfmt.Println(string(key), docRet)\n\t}\n\titer.Release()\n\terr = iter.Error()\n\n\tjson.NewEncoder(w).Encode(ids)\n}\n\nfunc getDocuments(selector string) []Document {\n\tvar documents []Document\n\n\tif selector == \"all\" {\n\t\t// iterate over leveldb and get key, val\n\t\titer := sourceDb.NewIterator(nil, nil)\n\t\tfor iter.Next() {\n\t\t\t// key := iter.Key()\n\t\t\tvalue := iter.Value()\n\n\t\t\tvar docRet Document\n\t\t\t// convert bson to byte\n\t\t\tbson.Unmarshal(value, &docRet)\n\n\t\t\tdocuments = append(documents, docRet)\n\t\t}\n\t\titer.Release()\n\t\terr = iter.Error()\n\t}\n\n\treturn documents\n}\n\nfunc getVersion(document Document) []byte {\n\t// version: timestamp (milliseconds, 13 digits) + deleted\n\tvar delStatus byte\n\tdelStatus = 48\n\tif document.Deleted {\n\t\tdelStatus = 49\n\t}\n\tversionGen := append([]byte(document.Timestamp), delStatus)\n\n\treturn versionGen\n}\n\n// =========================== COUCHDB ======================================================================\nfunc authenticate() (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/_session\", \"POST\", \"name=admin&password=password\", \"x-www-form-urlencoded\")\n\n}\n\nfunc checkDB(dbName string) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName, \"HEAD\", \"\", \"\")\n}\n\nfunc createDB(dbName string) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName, \"PUT\", \"\", \"\")\n}\n\nfunc getDBInfo(dbName string) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName, \"GET\", \"\", \"\")\n}\n\nfunc getReplicationLog(dbName string, logID string) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName+\"/_local/\"+logID, \"GET\", \"\", \"\")\n}\n\nfunc addBatchDocs(dbName string, documents []Document) (int, []byte) {\n\tdata, err := json.Marshal(documents)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tdataStr := `{\"docs\":` + string(data) + `}`\n\treturn request(\"http://127.0.0.1:5984/\"+dbName+\"/_bulk_docs\", \"POST\", dataStr, \"application/json\")\n}\n\nfunc getChanges(dbName string) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName+\"/_changes?style=all_docs\", \"GET\", \"\", \"\")\n}\n\nfunc ensureCommit(dbName string) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName+\"/_ensure_full_commit\", \"POST\", \"\", \"application/json\")\n}\n\nfunc setReplChkPoint(dbName string, replLog []byte) (int, []byte) {\n\treturn request(\"http://127.0.0.1:5984/\"+dbName+\"/_ensure_full_commit\", \"POST\", string(replLog), \"application/json\")\n}\n\nfunc request(url string, method string, payload string, contentType string) (int, []byte) {\n\n\tclient := &http.Client{\n\t\tJar: jar,\n\t}\n\n\tvar req *http.Request\n\tvar err error\n\n\tif payload == \"\" {\n\t\treq, err = http.NewRequest(method, url, nil)\n\t} else {\n\t\treq, err = http.NewRequest(method, url, strings.NewReader(payload))\n\t}\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tif contentType == \"x-www-form-urlencoded\" {\n\t\treq.Header.Add(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\t} else if contentType == \"application/json\" {\n\t\treq.Header.Add(\"Content-Type\", \"application/json\")\n\t}\n\n\tres, err := client.Do(req)\n\tif err != nil {\n\t\tfmt.Println(err)\n\n\t}\n\tdefer res.Body.Close()\n\n\tbody, err := ioutil.ReadAll(res.Body)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\treturn res.StatusCode, body\n}\n\nfunc handleRequests() {\n\tmyRouter := mux.NewRouter().StrictSlash(true)\n\tmyRouter.HandleFunc(\"/\", homePage)\n\tmyRouter.HandleFunc(\"/create\", createNewDocument).Methods(\"POST\")\n\tmyRouter.HandleFunc(\"/delete\", deleteDocument).Methods(\"POST\")\n\tlog.Fatal(http.ListenAndServe(\":10000\", myRouter))\n}\n\nfunc replicatorDemon() {\n\tfor {\n\t\t// authenticate couchDB\n\t\tstat, _ := authenticate()\n\t\tif stat != 200 {\n\t\t\tfmt.Println(\"CouchDB Authentication failed. Exiting demon.\")\n\t\t} else {\n\t\t\tfmt.Println(\"CouchDB authentication success.\")\n\t\t}\n\n\t\t// perform replication to target =======================================\n\t\t// sourceDB := \"source\"\n\t\ttargetDB := \"target\"\n\n\t\t// 1. verify peers\n\t\tstat, _ = checkDB(targetDB)\n\t\tif stat == 404 {\n\t\t\tfmt.Println(\"Target DB do not exist. Creating it..\")\n\t\t\t// create target database\n\t\t\tstat, _ = createDB(targetDB)\n\t\t\tif stat == 201 {\n\t\t\t\tfmt.Println(\"Target DB created.\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Target DB can not be created. Aborting replication..\")\n\t\t\t\tbreak\n\t\t\t}\n\t\t} else if stat == 200 {\n\t\t\tfmt.Println(\"Target DB exists\")\n\t\t}\n\t\t// 2. get peers information\n\t\tfmt.Println(\"Getting peers information..\")\n\t\tstat, _ = getDBInfo(targetDB)\n\t\treplicationID := \"\"\n\t\tif stat == 200 {\n\t\t\t// generate replication ID\n\t\t\treplicationID = \"123456\"\n\t\t}\n\n\t\t// 3. find common ascestry\n\t\tfullReplication := false\n\n\t\tif replicationID != \"\" {\n\t\t\tfmt.Println(\"Generated replication ID: \", replicationID)\n\t\t\t// get replication log from target\n\t\t\tfmt.Println(\"Getting replication log from target..\")\n\t\t\tstat, rlog := getReplicationLog(targetDB, replicationID)\n\t\t\tif stat == 200 {\n\t\t\t\t// compare logs\n\t\t\t\tfmt.Println(string(rlog))\n\t\t\t} else if stat == 404 {\n\t\t\t\tfullReplication = true\n\t\t\t\tfmt.Println(\"Replication log not available. Full replication needed.\")\n\t\t\t}\n\t\t} else {\n\t\t\tfmt.Println(\"Replication ID generation failed. Exiting.. \")\n\t\t\tbreak\n\t\t}\n\n\t\t// 4. locate changed documents\n\t\tvar documents []Document\n\t\tif fullReplication {\n\t\t\t// get all documents\n\t\t\tdocuments = getDocuments(\"all\")\n\t\t} else {\n\t\t\t// Get changed documents in target\n\t\t\tstat, changes := getChanges(targetDB)\n\t\t\tif stat == 200 {\n\t\t\t\tfmt.Println(\"Changes: \", changes)\n\t\t\t}\n\t\t\t// finalize documents to be replicated\n\t\t\tdocuments = getDocuments(\"all\") // TODO: To be changed to selectives\n\n\t\t\t// finalize replication if no change found\n\t\t\tif len(documents) <= 0 {\n\t\t\t\tfmt.Println(\"No more changes to replicate.\")\n\t\t\t}\n\t\t}\n\n\t\t// 5. replicate changes\n\t\tif len(documents) > 0 {\n\t\t\tstat, _ := addBatchDocs(targetDB, documents)\n\t\t\tif stat == 201 {\n\t\t\t\tfmt.Println(\"Documents written succesfully.\")\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Documents write failed.\")\n\t\t\t}\n\n\t\t\t// ensure in commit\n\t\t\tstat, data := ensureCommit(targetDB)\n\t\t\tif stat == 201 {\n\t\t\t\tfmt.Println(\"Documents commited succesfully.\")\n\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Documents commit failed.\", string(data))\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// set record replication checkpoint\n\t\t\tstat, _ = setReplChkPoint(targetDB, []byte(\"\"))\n\t\t}\n\n\t\t// wait 5 seconds before next replication loop\n\t\ttime.Sleep(time.Duration(5 * time.Second))\n\t}\n}\n\nfunc main() {\n\tgo replicatorDemon()\n\n\thandleRequests()\n}\n"
  },
  {
    "path": "aquila/search/.dockerignore",
    "content": "node_modules\n.vscode\n.env*\ndist"
  },
  {
    "path": "aquila/search/.nvmrc",
    "content": "v16.17.0"
  },
  {
    "path": "aquila/search/Dockerfile",
    "content": "FROM node:16-alpine as builder\n\n# Browserless\nARG BROWSERLESS_API_KEY=your-api-key-here\n\nWORKDIR /app\n\nRUN apk add curl bash\nRUN apk add --no-cache git openssh\n\n\n# install node-prune (https://github.com/tj/node-prune)\nRUN curl -sfL https://gobinaries.com/tj/node-prune | bash -s -- -b /usr/local/bin\n\nCOPY . .\n\nRUN yarn\n\nRUN yarn build\n\n\nRUN npm prune --production\n\n# run node prune\nRUN /usr/local/bin/node-prune\n\nFROM node:16-alpine\n\n# Application Port\nENV PORT=5000\n\n# Database\nENV DB_HOST=host.docker.internal\nENV DB_PORT=5432\nENV DB_NAME=test_db\nENV DB_USERNAME=user\nENV DB_PASSWORD=password\n\n# Redis\nENV REDIS_HOST=redis-19166.c62.us-east-1-4.ec2.cloud.redislabs.com\nENV REDIS_PORT=19166\nENV REDIS_USERNAME=default\nENV REDIS_PASSWORD=WUFOqcuORH4VoVNKBmzPIQvwsmpHqE5a\n\n# Jwt\nENV JWT_SECRET=jwtsecret\nENV JWT_EXPIRES_IN=2h\n\n#Summarizer\nENV SUMMARIZER_URL=http://host.docker.internal:5008/process\n\n#Aquila\nENV AQUILA_DB_HOST=http://host.docker.internal\nENV AQUILA_DB_PORT=5001\nENV AQUILA_DB_KEY_PATH=../../private_unencrypted.pem\nENV AQUILA_HUB_HOST=http://host.docker.internal\nENV AQUILA_HUB_PORT=5002\nENV AQUILA_HUB_KEY_PATH=../../private_unencrypted_hub.pem\n\n# Browserless\nENV BROWSERLESS_API_KEY=b94a8c0c-3b5c-4342-ab2d-a4b19bf1f13b\n\nWORKDIR /app\n\nCOPY --from=builder /app/dist ./dist\nCOPY --from=builder /app/node_modules ./node_modules\n\nEXPOSE 5000\n\nCMD [\"node\", \"./dist/index.js\"]"
  },
  {
    "path": "aquila/search/README.md",
    "content": "# AquilaX EE\n\n## ⚠️ Server and other Credentials are in workflow file\nNever make this repo Public\n\nSteps to run this project:\n\n1. Run `yarn` command\n2. Setup database settings inside `data-source.ts` file\n3. Run `yarn run start:dev` command\n4. Generate migration `yarn run typeorm -- migration:generate src/migrations/bookmark --dataSource src/config/db.ts`\n5. Run migration `yarn run typeorm -- migration:run --dataSource src/config/db.ts`\n\n\n## Run using Docker\nDocker build\n```bash\ndocker build -t manekshms/aquila-network-api .\n\ndocker run -d -p 5000:5000 \\\n-e DB_HOST=localhost \\\n-e DB_PORT=5432 \\\n-e DB_NAME=test_db \\\n-e DB_USERNAME=test \\\n-e DB_PASSWORD=example \\\n-e REDIS_HOST=localhost \\\n-e REDIS_PORT=6379 \\\n-e REDIS_USERNAME=default \\\n-e REDIS_PASSWORD=redis123 \\\n-e JWT_SECRET=jwtsecret \\\n-e JWT_EXPIRES_IN=2h \\\n-e SUMMARIZER_URL=http://localhost:5008/process \\\n-e AQUILA_DB_HOST=http://localhost.internal \\\n-e AQUILA_DB_PORT=5001 \\\n-e AQUILA_DB_KEY_PATH=/ossl/private_unencrypted.pem \\\n-e AQUILA_HUB_HOST=http://localhost.internal \\\n-e AQUILA_HUB_PORT=5002 \\\n-e AQUILA_HUB_KEY_PATH=/ossl/private_unencrypted.pem \\\n-e ENV BROWSERLESS_API_KEY=key \\\n-v ${HOME}/aquilax/ossl:/ossl\n--name manekshms/aquila-network-ui\n```\n\n"
  },
  {
    "path": "aquila/search/package.json",
    "content": "{\n   \"name\": \"aquilax-ee\",\n   \"version\": \"1.0.0\",\n   \"description\": \"AquilaX api\",\n   \"main\": \"index.js\",\n   \"repository\": \"https://github.com/Aquila-HQ/AquilaX-EE.git\",\n   \"author\": \"manekshms <manekshms@gmail.com>\",\n   \"scripts\": {\n      \"build\": \"tsc\",\n      \"listen\": \"node dist/index.js\",\n      \"start\": \"yarn listen\",\n      \"dev\": \"cross-env NODE_ENV=development nodemon  -e './**/*.ts' --exec 'yarn build && yarn listen'\",\n      \"typeorm\": \"typeorm-ts-node-commonjs\"\n   },\n   \"license\": \"MIT\",\n   \"devDependencies\": {\n      \"@types/body-parser\": \"^1.19.2\",\n      \"@types/cors\": \"^2.8.13\",\n      \"@types/express\": \"^4.17.17\",\n      \"@types/jsonwebtoken\": \"^9.0.1\",\n      \"@types/multer\": \"^1.4.7\",\n      \"@types/node\": \"^18.15.0\",\n      \"@types/uuid\": \"^9.0.1\",\n      \"cross-env\": \"^7.0.3\",\n      \"nodemon\": \"^2.0.21\",\n      \"ts-node\": \"^10.9.1\",\n      \"typescript\": \"^4.9.5\"\n   },\n   \"dependencies\": {\n      \"@bull-board/express\": \"^5.0.0\",\n      \"@postlight/parser\": \"^2.2.3\",\n      \"aquila-js\": \"^1.0.3\",\n      \"axios\": \"^1.3.4\",\n      \"body-parser\": \"^1.20.2\",\n      \"bs58\": \"^5.0.0\",\n      \"bullmq\": \"^3.10.1\",\n      \"cheerio\": \"^1.0.0-rc.12\",\n      \"class-transformer\": \"^0.5.1\",\n      \"class-validator\": \"^0.14.0\",\n      \"cors\": \"^2.8.5\",\n      \"express\": \"^4.18.2\",\n      \"express-validator\": \"^6.15.0\",\n      \"ioredis\": \"^5.3.1\",\n      \"jsonwebtoken\": \"^9.0.0\",\n      \"multer\": \"^1.4.5-lts.1\",\n      \"pg\": \"^8.10.0\",\n      \"puppeteer-core\": \"^19.7.4\",\n      \"reflect-metadata\": \"^0.1.13\",\n      \"routing-controllers\": \"^0.10.2\",\n      \"typedi\": \"^0.10.0\",\n      \"typeorm\": \"^0.3.12\",\n      \"uuid\": \"^9.0.0\"\n   }\n}\n"
  },
  {
    "path": "aquila/search/src/@types/express/index.d.ts",
    "content": "import { AccountStatus } from \"../../service/dto/AuthServiceDto\";\n\ndeclare global {\n\tnamespace Express {\n\t\tinterface Request {\n\t\t\ttoken?: string;\n\t\t\tjwtTokenPayload?: {\n\t\t\t\tcustomerId: string;\n\t\t\t\taccountStatus: AccountStatus\n\t\t\t}\n\t\t}\n\t}\n}"
  },
  {
    "path": "aquila/search/src/@types/index.d.ts",
    "content": "declare module '@postlight/parser' {\n  export type ExtractorArgs = any;\n\n  export type ParserOptions = {\n    html?: string;\n    fetchAllPages?: boolean;\n    fallback?: boolean;\n    contentType?: 'html' | 'markdown' | 'text';\n    headers?: Record<string, string>;\n    extend?: boolean;\n    customExtractor?: (args: ExtractorArgs) => ParserResult;\n  };\n\n  export type ParserResult = {\n    title: string;\n    content: string;\n    author: string;\n    date_published: string;\n    lead_image_url: string;\n    dek: string;\n    next_page_url: string;\n    url: string;\n    domain: string;\n    excerpt: string;\n    word_count: number;\n    direction: string;\n    total_pages: number;\n    rendered_pages: number;\n  };\n\n  export function parse(\n    url: string,\n    opts: ParserOptions\n  ): Promise<ParserResult>;\n\n  const exported: {\n    parse: typeof parse;\n  };\n  export default exported;\n}"
  },
  {
    "path": "aquila/search/src/app.ts",
    "content": "import 'reflect-metadata';\nimport express from 'express';\nimport { Container } from 'typedi';\nimport { useExpressServer, useContainer} from 'routing-controllers';\nimport { BullAdapter }  from '@bull-board/api/bullAdapter';\nimport { ExpressAdapter } from '@bull-board/express';\nimport { createBullBoard } from '@bull-board/api';\n\nimport db from './config/db';\nimport redisConnection from './config/redisConnection'; \nimport { AquilaClientService } from './lib/AquilaClientService';\nimport { authorizationChecker } from './helper/auth';\nimport { currentUserChecker } from './helper/user';\nimport { getAppWorker } from './job/appWorker';\nimport { AppQueue } from './job/AppQueue';\n\n\nexport default async function main() {\n  useContainer(Container);\n\n  const app = express();\n  app.use(express.json());\n  useExpressServer(app, {\n    cors: true,\n    authorizationChecker,\n    currentUserChecker,\n    middlewares: [`${__dirname}/middleware/**/*.{ts,js}`],\n    controllers: [`${__dirname}/controller/*.js`],\n    defaultErrorHandler: false\n  });\n\n  await db.initialize();\n  const appWorker = getAppWorker(redisConnection);\n  const aqc = Container.get(AquilaClientService);\n  await aqc.connect();\n  const serverAdapter = new ExpressAdapter();\n  serverAdapter.setBasePath('/admin/queues');\n  const appQueue = Container.get(AppQueue);\n  const { addQueue, removeQueue, setQueues, replaceQueues } = createBullBoard({\n    queues: [new BullAdapter(appQueue.queue)],\n    serverAdapter: serverAdapter,\n  });\n  app.use('/admin/queues', serverAdapter.getRouter());\n\n  return app;\n}\n"
  },
  {
    "path": "aquila/search/src/config/db.ts",
    "content": "import { DataSource, DataSourceOptions } from \"typeorm\";\n\nimport { ConfigService } from \"../lib/ConfigService\";\n\nconst configService = new ConfigService();\n\nconst dataSourceOptions: DataSourceOptions = {\n\t\ttype: 'postgres',\n\t\thost: configService.get('DB_HOST'),\n\t\tport: parseInt(configService.get('DB_PORT'), 10),\n\t\tusername: configService.get('DB_USERNAME'),\n\t\tpassword: configService.get('DB_PASSWORD'),\n\t\tdatabase: configService.get('DB_NAME'),\n\t\tsynchronize: false,\n\t\tentities: [`${__dirname}/../entity/**/*.{ts,js}`],\n\t\tmigrations: [`${__dirname}/../migrations/**/*.{ts,js}`],\n\t\tmigrationsTableName: \"migrations\",\n}\n\nconst dataSource = new DataSource(dataSourceOptions);\n\nexport default dataSource;"
  },
  {
    "path": "aquila/search/src/config/redisConnection.ts",
    "content": "import Redis from 'ioredis';\nimport { ConfigService } from '../lib/ConfigService';\n\nconst configService = new ConfigService();\n\nconst redisConnection = new Redis({\n\thost: configService.get('REDIS_HOST'),\n\tport: parseInt(configService.get('REDIS_PORT'), 10),\n\tusername: configService.get('REDIS_USERNAME'),\n\tpassword: configService.get('REDIS_PASSWORD')\n})\n\nexport default redisConnection;"
  },
  {
    "path": "aquila/search/src/controller/AuthController.ts",
    "content": "import { Body, JsonController, Post } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { AuthService } from \"../service/AuthService\";\nimport { LoginCustomerRequestBodyDto, LoginCustomerResponseBodyDto } from \"./dto/AuthControllerDto\";\n\n@Service()\n@JsonController('/auth')\nexport class AuthController {\n\n\tpublic constructor(private authService: AuthService) {}\n\n\t@Post('/login')\n\tpublic async login(\n\t\t@Body() body: LoginCustomerRequestBodyDto\n\t): Promise<LoginCustomerResponseBodyDto> {\n\t\tconst token = await this.authService.login(body.secretKey);\n\t\treturn {\n\t\t\ttoken\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/controller/BookmarkController.ts",
    "content": "import { Body, Get, JsonController, Param, Post, QueryParams, UseBefore } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { Bookmark } from \"../entity/Bookmark\";\nimport { BookmarkTemp } from \"../entity/BookmarkTemp\";\n\nimport { JwtPayloadData } from \"../helper/decorators/jwtPayloadData\";\nimport { AuthMiddleware } from \"../middleware/global/AuthMiddleware\";\nimport { AddBookmarkValidator } from \"../middleware/validator/bookmark/AddBookmarkValidator\";\nimport { GetBookmarkByCollectionIdValidator } from \"../middleware/validator/bookmark/GetBookmarkByCollectionIdValidator\";\nimport { GetFeaturedBookmarkValidator } from \"../middleware/validator/bookmark/GetFeaturedBookmarkValidator\";\nimport { GetPublicBookmarkByCollectionIdParamValidator } from \"../middleware/validator/bookmark/GetPublicBookmarkByCollectionIdParamValidator\";\nimport { GetPublicBookmarkByCollectionIdValidator } from \"../middleware/validator/bookmark/GetPublicBookmarkByCollectionIdValidator\";\nimport { BookmarkService } from \"../service/BookmarkService\";\nimport { AccountStatus, JwtPayload } from \"../service/dto/AuthServiceDto\";\nimport { GetBookmarksByCollectionIdOptionsInputDto, GetFeaturedBookmarksOptionsInputDto } from \"../service/dto/BookmarkServiceDto\";\nimport { AddBookmarkReqBodyDto, GetBookmarksByCollectionIdReqQueryParamsDto, GetBookmarksByCollectionIdResBodyDto, GetFeaturedBookmarksReqQueryParamsDto, GetFeaturedBookmarksResBodyDto } from \"./dto/BookmarkControllerDto\";\n\n@Service()\n@JsonController('/bookmark')\nexport class BookmarkController {\n\n\tpublic constructor(private bookmarkService: BookmarkService) {}\n\n\t@UseBefore(AuthMiddleware, AddBookmarkValidator)\n\t@Post('/')\n\tpublic async addBookmark(\n\t\t@Body() body: AddBookmarkReqBodyDto,\n\t\t@JwtPayloadData() JwtPayloadData: JwtPayload\n\t): Promise<Bookmark|BookmarkTemp> {\n\t\treturn await this.bookmarkService.addBookmark(body, JwtPayloadData.accountStatus);\n\t}\n\n\t@UseBefore(AuthMiddleware, GetBookmarkByCollectionIdValidator)\n\t@Get('/:collectionId/search')\n\tpublic async getBookmarksByCollectionId(\n\t\t@Param('collectionId') collectionId: string,\n\t\t@QueryParams() queryParams: GetBookmarksByCollectionIdReqQueryParamsDto,\n\t\t@JwtPayloadData() JwtPayloadData: JwtPayload\n\t): Promise<GetBookmarksByCollectionIdResBodyDto> {\n\t\tconst options: GetBookmarksByCollectionIdOptionsInputDto = {\n\t\t\tlimit: queryParams.limit ? parseInt(queryParams.limit, 10) : 10,\n\t\t\tpage: queryParams.page ? parseInt(queryParams.page, 10) : 1\n\t\t}\n\t\tif(queryParams.query) {\n\t\t\toptions.query = queryParams.query;\n\t\t}\n\t\treturn this.bookmarkService.getBookmarksByCollectionId(collectionId, options, JwtPayloadData.accountStatus);\n\t}\n\n\t@UseBefore(GetPublicBookmarkByCollectionIdValidator, GetPublicBookmarkByCollectionIdParamValidator)\n\t@Get('/public/:collectionId/search')\n\tpublic async getPublicBookmarksByCollectionId(\n\t\t@Param('collectionId') collectionId: string,\n\t\t@QueryParams() queryParams: GetBookmarksByCollectionIdReqQueryParamsDto,\n\t): Promise<GetBookmarksByCollectionIdResBodyDto> {\n\t\tconst options: GetBookmarksByCollectionIdOptionsInputDto = {\n\t\t\tlimit: queryParams.limit ? parseInt(queryParams.limit, 10) : 10,\n\t\t\tpage: queryParams.page ? parseInt(queryParams.page, 10) : 1\n\t\t}\n\t\tif(queryParams.query) {\n\t\t\toptions.query = queryParams.query;\n\t\t}\n\t\treturn this.bookmarkService.getBookmarksByCollectionId(collectionId, options, AccountStatus.PERMANENT);\n\t}\n\n\t@UseBefore(GetFeaturedBookmarkValidator)\n\t@Get('/public/featured')\n\tpublic async getAllFeaturedBookmark(\n\t\t@QueryParams() queryParams: GetFeaturedBookmarksReqQueryParamsDto\n\t): Promise<GetFeaturedBookmarksResBodyDto> {\n\t\tconst options: GetFeaturedBookmarksOptionsInputDto = {\n\t\t\tlimit: queryParams.limit ? parseInt(queryParams.limit, 10) : 10,\n\t\t\tpage: queryParams.page ? parseInt(queryParams.page, 10) : 1\n\t\t}\n\t\treturn this.bookmarkService.getFeaturedBookmarks(options);\n\t}\n\t\n}"
  },
  {
    "path": "aquila/search/src/controller/CollectionController.ts",
    "content": "import { Authorized, Get, JsonController, Param, QueryParams, UseBefore } from \"routing-controllers\";\nimport { Service } from \"typedi\";\n\nimport { Collection } from \"../entity/Collection\";\nimport { CollectionTemp } from \"../entity/CollectionTemp\";\nimport { JwtPayloadData } from \"../helper/decorators/jwtPayloadData\";\nimport { GetAllFeaturedCollectionValidator } from \"../middleware/validator/collection/GetAllFeaturedCollectionValidator\";\nimport { GetAllPublicCollectionValidator } from \"../middleware/validator/collection/GetAllPublicCollectionValidator\";\nimport { GetPublicCollectionByIdValidator } from \"../middleware/validator/collection/GetPublicCollectionByIdValidator\";\nimport { CollectionService } from \"../service/CollectionService\";\nimport { AccountStatus, JwtPayload } from \"../service/dto/AuthServiceDto\";\nimport { GetAllFeaturedCollectionReqQueryParamsDto, GetAllFeaturedCollectionResPayloadDto, GetAllPublicCollectionReqQueryParamsDto, GetAllPublicCollectionResPayloadDto } from \"./dto/CollectionControllerDto\";\n\n@Service()\n@JsonController('/collection')\nexport class CollectionController {\n\n\tpublic constructor(private collectionService: CollectionService) {}\n\n\t@UseBefore(GetAllPublicCollectionValidator)\n\t@Get('/public')\n\tpublic async getAllPublicCollection(\n\t\t@QueryParams() queryParams: GetAllPublicCollectionReqQueryParamsDto\n\t): Promise<GetAllPublicCollectionResPayloadDto> {\n\t\tconst options = {\n\t\t\tlimit: queryParams.limit? parseInt(queryParams.limit) : 10,\n\t\t\tpage: queryParams.page ? parseInt(queryParams.page)  : 1,\n\t\t\twhere: {\n\t\t\t\tisShareable: true\n\t\t\t}\n\t\t};\n\t\treturn await this.collectionService.getAllCollections(options, AccountStatus.PERMANENT);\n\t}\n\t\n\t@UseBefore(GetAllFeaturedCollectionValidator)\n\t@Get('/public/featured')\n\tpublic async getAllPublicFeaturedCollection(\n\t\t@QueryParams() queryParams: GetAllFeaturedCollectionReqQueryParamsDto\n\t): Promise<GetAllFeaturedCollectionResPayloadDto> {\n\t\tconst options = {\n\t\t\tlimit: queryParams.limit? parseInt(queryParams.limit) : 10,\n\t\t\tpage: queryParams.page ? parseInt(queryParams.page)  : 1,\n\t\t\twhere: {\n\t\t\t\tisShareable: true,\n\t\t\t\tisFeatured: true\n\t\t\t}\n\t\t};\n\t\treturn await this.collectionService.getAllCollections(options, AccountStatus.PERMANENT);\n\t}\n\n\t@UseBefore(GetPublicCollectionByIdValidator)\n\t@Get('/public/:collectionId')\n\tpublic async getPublicCollectionById(\n\t\t@Param('collectionId') collectionId: string\n\t): Promise<Collection> {\n\t\treturn await this.collectionService.getPublicCollectionById(collectionId);\n\t}\n\n\t@Authorized()\n\t@Get('/my-collections')\n\tpublic async getCurrentCustomerCollections(\n\t\t@JwtPayloadData() jwtPayload: JwtPayload\n\t): Promise<Collection[] | CollectionTemp[]> {\n\t\tconst collections = await this.collectionService.getCustomerCollectionsByCustomerId(jwtPayload.customerId, jwtPayload.accountStatus);\n\t\treturn collections;\n\t}\t\n\n}"
  },
  {
    "path": "aquila/search/src/controller/CollectionSubscriptionController.ts",
    "content": "import { Body, Get, JsonController, Param, Post, QueryParams, UseBefore } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { Collection } from \"../entity/Collection\";\nimport { CollectionSubscription } from \"../entity/CollectionSubscription\";\nimport { CollectionSubscriptionTemp } from \"../entity/CollectionSubscriptionTemp\";\n\nimport { JwtPayloadData } from \"../helper/decorators/jwtPayloadData\";\nimport { AuthMiddleware } from \"../middleware/global/AuthMiddleware\";\nimport { SubscribeCollectionValidator } from \"../middleware/validator/csubscription/SubscribeCollectionValidator\";\nimport { UnSubscribeCollectionValidator } from \"../middleware/validator/csubscription/UnSubscribeCollectionValidator\";\nimport { CollectionSubscriptionService } from \"../service/CollectionSubscriptionService\";\nimport { JwtPayload } from \"../service/dto/AuthServiceDto\";\nimport { GetSubscriptionsByCustomerIdOptionsInputDto } from \"../service/dto/CollectionSubscriptionServiceDto\";\nimport { GetSubscriptionsByCustomerIdReqQueryParamsDto, GetSubscriptionsByCustomerIdResBodyDto } from \"./dto/CollectionSubscriptionControllerDto\";\n\n@Service()\n@JsonController('/subscription')\nexport class CollectionSubscriptionController {\n\n\tpublic constructor(private collectionSubscriptionService: CollectionSubscriptionService) {}\n\n\t@UseBefore(AuthMiddleware)\n\t@Get('/list')\n\tpublic async getCurrentCustomerSubscriptions(\n\t\t@JwtPayloadData() JwtPayloadData: JwtPayload\n\t): Promise<CollectionSubscriptionTemp[] | CollectionSubscription[]> {\n\t\t\n\t\treturn await this.collectionSubscriptionService.getCustomerSubscriptions(JwtPayloadData.customerId, JwtPayloadData.accountStatus);\n\t}\n\n\t@UseBefore(AuthMiddleware, SubscribeCollectionValidator)\n\t@Post('/:collectionId/add')\n\tpublic async subscribeCollection(\n\t\t@Param('collectionId') collectionId: string,\n\t\t@JwtPayloadData() JwtPayloadData: JwtPayload\n\t): Promise<CollectionSubscription|CollectionSubscriptionTemp> {\n\t\t\n\t\treturn await this.collectionSubscriptionService.subscribeCollection(collectionId, JwtPayloadData.customerId, JwtPayloadData.accountStatus);\n\t}\n\n\t@UseBefore(AuthMiddleware)\n\t@Post('/:collectionId/is-subscribed')\n\tpublic async isCollectionAlreadySubscribed(\n\t\t@Param('collectionId') collectionId: string,\n\t\t@JwtPayloadData() jwtPayloadData: JwtPayload\n\t):Promise<{ isSubscribed: boolean}> {\n\t\tconst isSubscribed = await this.collectionSubscriptionService.isCollectionSubscribedByCustomer(collectionId, jwtPayloadData.customerId, jwtPayloadData.accountStatus);\n\t\treturn { isSubscribed };\n\t}\n\n\t@UseBefore(AuthMiddleware, UnSubscribeCollectionValidator)\n\t@Post('/:collectionId/remove')\n\tpublic async unSubscribeCollection(\n\t\t@Param('collectionId') collectionId: string,\n\t\t@JwtPayloadData() JwtPayloadData: JwtPayload\n\t): Promise<CollectionSubscription | CollectionSubscriptionTemp | null> {\n\t\t\n\t\treturn await this.collectionSubscriptionService.unSubscribeCollection(collectionId, JwtPayloadData.customerId, JwtPayloadData.accountStatus);\n\t}\n\n\t@Get('/')\n\t@UseBefore(AuthMiddleware)\n\tpublic async getSubscriptionsByCustomerId(\n\t\t@JwtPayloadData() jwtPayloadData: JwtPayload,\n\t\t@QueryParams() queryParams: GetSubscriptionsByCustomerIdReqQueryParamsDto,\n\t): Promise<GetSubscriptionsByCustomerIdResBodyDto> {\n\t\tconst options: GetSubscriptionsByCustomerIdOptionsInputDto = {\n\t\t\tlimit: queryParams.limit ? parseInt(queryParams.limit, 10) : 10,\n\t\t\tpage: queryParams.page ? parseInt(queryParams.page, 10) : 1\n\t\t}\n\t\tif(queryParams.query) {\n\t\t\toptions.query = queryParams.query;\n\t\t}\n\t\treturn await this.collectionSubscriptionService.getSubscriptionsByCustomerId(jwtPayloadData.customerId, options, jwtPayloadData.accountStatus);\n\t}\n\n\t@UseBefore(AuthMiddleware)\n\t@Get('/collections')\n\tpublic async getCustomerSubscribedCollections(\n\t\t@JwtPayloadData() jwtPayloadData: JwtPayload,\n\t): Promise<Collection[]> {\n\t\treturn await this.collectionSubscriptionService.getCustomerSubscribedCollections(jwtPayloadData.customerId, jwtPayloadData.accountStatus);\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/controller/CustomerController.ts",
    "content": "import { Authorized, Body, CurrentUser, Get, JsonController, Param, Patch, Post, Put, UseBefore } from \"routing-controllers\";\nimport { Service } from \"typedi\";\n\nimport { Customer } from \"../entity/Customer\";\nimport { CustomerTemp } from \"../entity/CustomerTemp\";\nimport { JwtPayloadData } from \"../helper/decorators/jwtPayloadData\";\nimport { AuthMiddleware } from \"../middleware/global/AuthMiddleware\";\nimport { ActivateCustomerValidator } from \"../middleware/validator/customer/ActivateCustomerValidator\";\nimport { CreateCustomerValidator } from \"../middleware/validator/customer/CreateCustomerValidator\";\nimport { GetCustomerPublicInfoByIdValidator } from \"../middleware/validator/customer/GetCustomerPublicInfoByIdValidator\";\nimport { UpdateCustomerValidator } from \"../middleware/validator/customer/UpdateCustomerValidator\";\nimport { CustomerService } from \"../service/CustomerService\";\nimport { JwtPayload } from \"../service/dto/AuthServiceDto\";\nimport { ActivateCustomerReqBodyDto, CreateCustomerReqBodyDto, CreateCustomerResponseDto, GetCustomerPublicInfoByIdRespBodyDto, GetRandomCustomerNameRespBodyDto, UpdateCustomerReqBodyDto } from \"./dto/CustomerControllerDto\";\n\n@Service()\n@JsonController('/customer')\nexport class CustomerControler {\n\n\tpublic constructor(private customerService: CustomerService){}\n\n\t@UseBefore(AuthMiddleware, UpdateCustomerValidator)\n\t@Patch('/')\n\tpublic async updateCustomer(\n\t\t@JwtPayloadData() JwtPayloadData: JwtPayload,\n\t\t@Body() body: UpdateCustomerReqBodyDto\n\t):Promise<Customer> {\n\t\treturn await this.customerService.updateCustomerById(JwtPayloadData.customerId, body);\n\t}\n\n\t@UseBefore(GetCustomerPublicInfoByIdValidator)\n\t@Get('/public/:customerId')\n\tpublic async getCustomerPublicInfoById(\n\t\t@Param('customerId') customerId: string\n\t): Promise<GetCustomerPublicInfoByIdRespBodyDto> {\n\t\treturn await this.customerService.getCustomerPublicInfoById(customerId);\n\t}\t\n\n\t@Authorized()\n\t@Get('/me')\n\tpublic async getCustomerById(\n\t\t@CurrentUser() customer: Customer | CustomerTemp\n\t): Promise<Customer|CustomerTemp> {\n\t\treturn customer;\n\t}\n\n\t@UseBefore(CreateCustomerValidator)\n\t@Post('/')\n\tpublic async createCustomer(\n\t\t@Body() body: CreateCustomerReqBodyDto\n\t): Promise<CreateCustomerResponseDto> {\n\t\treturn await this.customerService.createCustomer(body);\n\t}\n\n\t@UseBefore(AuthMiddleware,ActivateCustomerValidator)\n\t@Post('/activate')\n\tpublic async activateCustomer(\n\t\t@JwtPayloadData() jwtPayloadData: JwtPayload,\n\t\t@Body() body: ActivateCustomerReqBodyDto\n\t): Promise<Customer> {\n\t\treturn await this.customerService.activateCustomerById(jwtPayloadData.customerId, body);\n\t}\t\n\n\t@Get('/generate-name')\n\tpublic async generateRandomCustomerName(\n\t): Promise<GetRandomCustomerNameRespBodyDto> {\n\t\treturn await this.customerService.getRandomCustomerName();\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/controller/HomeController.ts",
    "content": "import { Get, JsonController } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { Queue } from 'bullmq';\n\n@Service()\n@JsonController('/')\nexport class HomeController {\n\n\t@Get('/')\n\tpublic index() {\n\n\t\tconst queue = new Queue('Paint',  { connection: {\n\t\t\thost: \"redis-17256.c17.us-east-1-4.ec2.cloud.redislabs.com\",\n\t\t\tport: 17256,\n\t\t\tusername: 'default',\n\t\t\tpassword: 'AbcRVEZFVHYjRNPFxAwLcSdUCA4DuUll'\n\t\t}});\n\t\t\n\t\tqueue.add('cars', { color: 'blue' });\n\t\treturn {\n\t\t\tmsg: \"Welcome to Aquila X\"\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/controller/dto/AuthControllerDto.ts",
    "content": "import { AccountStatus } from \"../../service/dto/AuthServiceDto\";\n\nexport interface LoginCustomerRequestBodyDto {\n\tsecretKey: string;\n}\n\nexport interface LoginCustomerResponseBodyDto {\n\ttoken: string;\n}"
  },
  {
    "path": "aquila/search/src/controller/dto/BookmarkControllerDto.ts",
    "content": "export interface AddBookmarkReqBodyDto {\n\thtml?: string;\n\turl: string;\n\tcollectionId: string;\n}\n\nexport interface GetBookmarksByCollectionIdReqQueryParamsDto {\n\tquery?: string;\n\tlimit?: string;\n\tpage?: string;\n}\n\nexport interface GetBookmarksByCollectionIdResBodyDto {\n\ttotalPages: number;\n\ttotalRecords: number;\n\tcurrentPage: number;\t\n\tlimit: number;\n\tbookmarks: {\n\t\tid: string;\n\t\tcollectionId: string;\n\t\turl: string;\n\t\ttitle: string;\n\t\tauthor: string;\n\t\tcoverImg: string;\n\t\tsummary: string\n\t\tdescription: string;\n\t}[] \n}\n\nexport interface GetFeaturedBookmarksReqQueryParamsDto {\n\tlimit?: string;\n\tpage?: string;\n}\n\nexport interface GetFeaturedBookmarksResBodyDto {\n\ttotalPages: number;\n\ttotalRecords: number;\n\tcurrentPage: number;\t\n\tlimit: number;\n\tbookmarks: {\n\t\tid: string;\n\t\tcollectionId: string;\n\t\turl: string;\n\t\ttitle: string;\n\t\tauthor: string;\n\t\tcoverImg: string;\n\t\tsummary: string\n\t\tdescription: string;\n\t}[] \n}"
  },
  {
    "path": "aquila/search/src/controller/dto/CollectionControllerDto.ts",
    "content": "import { Collection } from \"../../entity/Collection\";\nimport { CollectionTemp } from \"../../entity/CollectionTemp\";\n\nexport interface GetAllPublicCollectionReqQueryParamsDto {\n\tlimit?: string;\n\tpage?: string;\n}\n\nexport interface GetAllPublicCollectionResPayloadDto {\n\ttotalRecords: number;\n\ttotalPages: number;\n\tcurrentPage: number,\n\tlimit: number;\n\tcollections: Collection[] | CollectionTemp[]\n}\n\nexport interface GetAllFeaturedCollectionReqQueryParamsDto {\n\tlimit?: string;\n\tpage?: string;\n}\n\nexport interface GetAllFeaturedCollectionResPayloadDto {\n\ttotalRecords: number;\n\ttotalPages: number;\n\tcurrentPage: number,\n\tlimit: number;\n\tcollections: Collection[] | CollectionTemp[]\n}"
  },
  {
    "path": "aquila/search/src/controller/dto/CollectionSubscriptionControllerDto.ts",
    "content": "export interface GetSubscriptionsByCustomerIdReqQueryParamsDto {\n\tquery?: string;\n\tlimit?: string;\n\tpage?: string;\n}\n\nexport interface GetSubscriptionsByCustomerIdResBodyDto {\n\ttotalPages: number;\n\ttotalRecords: number;\n\tcurrentPage: number;\t\n\tlimit: number;\n\tbookmarks: {\n\t\tid: string;\n\t\tcollectionId: string;\n\t\turl: string;\n\t\ttitle: string;\n\t\tauthor: string;\n\t\tcoverImg: string;\n\t\tsummary: string\n\t\tdescription: string;\n\t}[] \n}"
  },
  {
    "path": "aquila/search/src/controller/dto/CustomerControllerDto.ts",
    "content": "import { CollectionTemp } from \"../../entity/CollectionTemp\";\nimport { CustomerTemp } from \"../../entity/CustomerTemp\";\n\nexport interface CreateCustomerReqBodyDto {\n\tfirstName: string;\n\tlastName: string;\n}\n\nexport interface CreateCustomerResponseDto {\n\tcustomer: CustomerTemp,\n\tcollection: CollectionTemp\n}\n\nexport interface ActivateCustomerReqBodyDto {\n\tfirstName: string;\n\tlastName: string;\n\temail: string;\n\tdesc: string;\n\tlightningAddress: string;\n}\n\nexport interface UpdateCustomerReqBodyDto {\n\tfirstName: string;\n\tlastName: string;\n\temail: string;\n\tdesc: string;\n\tlightningAddress: string;\n}\n\nexport interface GetCustomerPublicInfoByIdRespBodyDto {\n\tid: string;\n\tfirstName: string;\n\tlastName: string;\n\tdesc: string;\n\tcustomerId: number;\n}\n\nexport interface GetRandomCustomerNameRespBodyDto {\n\tfirstName: string;\n\tlastName: string;\n}"
  },
  {
    "path": "aquila/search/src/entity/Bookmark.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\nexport enum BookmarkStatus {\n\tNOT_PROCESSED = 'NOT_PROCESSED',\n\tPROCESSING = 'PROCESSING',\n\tPROCESSED = 'PROCESSED',\n}\n\n@Entity({ name: 'bookmark'})\nexport class Bookmark extends BaseEntity {\n\n\t@PrimaryGeneratedColumn('uuid')\n\tpublic id: string;\n\n\t@Column({ name: 'collection_id', type: 'uuid', nullable: false})\n\tpublic collectionId: string;\n\n\t@Column({ type: 'varchar', length: 2048, nullable: false})\n\tpublic url: string;\n\n\t@Column({ type: 'text', nullable: false})\n\tpublic html: string;\n\n\t@Column({ type: 'varchar', length: 2048, nullable: true})\n\tpublic title: string;\n\n\t@Column({ type: 'varchar', length: 100, nullable: true})\n\tpublic author: string;\n\n\t@Column({ name: 'cover_img', type: 'varchar', length: 2048, nullable: true})\n\tpublic coverImg: string;\n\n\t@Column({ type: 'text', nullable: true})\n\tpublic summary: string;\n\n\t@Column({ type: 'varchar', length: 2048, nullable: true})\n\tpublic links: string;\n\n\t@Column({ name: 'is_hidden', type: 'boolean', default: false})\n\tpublic isHidden: boolean;\n\n\t@Column({ type: 'enum', enum: BookmarkStatus, default: BookmarkStatus.NOT_PROCESSED})\n\tpublic status: BookmarkStatus;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/BookmarkPara.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity('bookmark_para')\nexport class BookmarkPara extends BaseEntity {\n\n\t@PrimaryGeneratedColumn('uuid')\n\tpublic id: string;\n\n\t@Column({ name: 'bookmark_id', nullable: false})\n\tpublic bookmarkId: string;\n\n\t@Column({ type: 'text', nullable: false})\n\tpublic content: string;\n\n\t@CreateDateColumn()\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn()\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/BookmarkParaTemp.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity('bookmark_para_temp')\nexport class BookmarkParaTemp extends BaseEntity {\n\n\t@PrimaryGeneratedColumn('uuid')\n\tpublic id: string;\n\n\t@Column({ name: 'bookmark_id', nullable: false})\n\tpublic bookmarkId: string;\n\n\t@Column({ type: 'text', nullable: false})\n\tpublic content: string;\n\n\t@CreateDateColumn()\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn()\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/BookmarkTemp.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\nexport enum BookmarkTempStatus {\n\tNOT_PROCESSED = 'NOT_PROCESSED',\n\tPROCESSING = 'PROCESSING',\n\tPROCESSED = 'PROCESSED',\n}\n\n@Entity({ name: 'bookmark_temp'})\nexport class BookmarkTemp extends BaseEntity {\n\n\t@PrimaryGeneratedColumn('uuid')\n\tpublic id: string;\n\n\t@Column({ name: 'collection_id', type: 'uuid', nullable: false})\n\tpublic collectionId: string;\n\n\t@Column({ type: 'varchar', length: 2048, nullable: false})\n\tpublic url: string;\n\n\t@Column({ type: 'text', nullable: false})\n\tpublic html: string;\n\n\t@Column({ type: 'varchar', length: 100, nullable: true})\n\tpublic title: string;\n\n\t@Column({ type: 'varchar', length: 100, nullable: true})\n\tpublic author: string;\n\n\t@Column({ name: 'cover_img', type: 'varchar', length: 255, nullable: true})\n\tpublic coverImg: string;\n\n\t@Column({ type: 'varchar', length: 255, nullable: true})\n\tpublic summary: string;\n\n\t@Column({ type: 'varchar', length: 255, nullable: true})\n\tpublic links: string;\n\n\t@Column({ name: 'is_hidden', type: 'boolean', default: false})\n\tpublic isHidden: boolean;\n\n\t@Column({ type: 'enum', enum: BookmarkTempStatus, default: BookmarkTempStatus.NOT_PROCESSED})\n\tpublic status: BookmarkTempStatus;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/Collection.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, JoinTable, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\nimport { Customer } from \"./Customer\";\n\n@Entity({ name: 'collection'})\nexport class Collection extends BaseEntity {\n\n\t@PrimaryGeneratedColumn(\"uuid\")\n\tpublic id: string;\n\n\t@Column({ type: 'varchar', length: 25})\n\tpublic name: string;\n\n\t@Column({ type: 'varchar', length: 255})\n\tpublic desc: string;\n\n\t@Column({ name: 'customer_id', type: 'uuid' })\n\tpublic customerId: string;\n\n\t@ManyToOne(type => Customer)\n\t@JoinColumn({ name: 'customer_id', referencedColumnName: 'id'})\n\tpublic customer: Customer;\n\n\t@Column({ name: 'aquila_db_name', type: 'varchar', length: 255, unique: true})\n\tpublic aquilaDbName: string;\n\n\t@Column({ name: 'is_shareable', type: 'boolean', default: true})\n\tpublic isShareable: boolean;\n\n\t@Column({ name: 'indexed_docs_count', type: 'bigint', default: 0})\n\tpublic indexedDocsCount: number;\n\n\t@Column({ name: 'is_featured', type: 'boolean', default: false})\n\tpublic isFeatured: boolean;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({ name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/CollectionSubscription.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({ name: 'collection_subscription'})\nexport class CollectionSubscription extends BaseEntity {\n\n\t@PrimaryGeneratedColumn('uuid')\n\tpublic id: string;\n\n\t@Column({ name: 'collection_id', type: 'uuid', nullable: false})\n\tpublic collectionId: string;\n\n\t@Column({ name: 'subscriber_id', type: 'uuid', nullable: false})\n\tpublic subscriberId: string;\n\n\t@CreateDateColumn({ name: 'subscribed_at'})\n\tpublic subscribedAt: Date;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/CollectionSubscriptionTemp.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({ name: 'collection_subscription_temp'})\nexport class CollectionSubscriptionTemp extends BaseEntity {\n\n\t@PrimaryGeneratedColumn('uuid')\n\tpublic id: string;\n\n\t@Column({ name: 'collection_id', type: 'uuid', nullable: false})\n\tpublic collectionId: string;\n\n\t@Column({ name: 'subscriber_id', type: 'uuid', nullable: false})\n\tpublic subscriberId: string;\n\n\t@CreateDateColumn({ name: 'subscribed_at'})\n\tpublic subscribedAt: Date;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/CollectionTemp.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({ name: 'collection_temp'})\nexport class CollectionTemp extends BaseEntity {\n\n\t@PrimaryGeneratedColumn(\"uuid\")\n\tpublic id: string;\n\n\t@Column({ type: 'varchar', length: 25})\n\tpublic name: string;\n\n\t@Column({ type: 'varchar', length: 255})\n\tpublic desc: string;\n\n\t@Column({ name: 'customer_id', type: 'uuid' })\n\tpublic customerId: string;\n\n\t@Column({ name: 'aquila_db_name', type: 'varchar', length: 255, unique: true})\n\tpublic aquilaDbName: string;\n\n\t@Column({ name: 'is_shareable', type: 'boolean', default: true})\n\tpublic isShareable: boolean;\n\n\t@Column({ name: 'indexed_docs_count', type: 'bigint', default: 0})\n\tpublic indexedDocsCount: number;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({ name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/Customer.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, Generated, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({ name: 'customer'})\nexport class Customer extends BaseEntity {\n\n\t@PrimaryGeneratedColumn(\"uuid\")\n\tpublic id: string;\n\n\t@Generated(\"increment\")\n\t@Column({ name: \"customer_id\", type: 'bigint'})\n\tpublic customerId: number;\n\n\t@Column({ \n\t\tname: 'first_name',\n\t\ttype: 'varchar',\n\t\tlength: 20\n\t})\n\tpublic firstName: string;\n\n\t@Column({ \n\t\tname: 'last_name',\n\t\ttype: 'varchar',\n\t\tlength: 20\n\t})\n\tpublic lastName: string;\n\n\t@Column({ type: 'varchar', length: 255})\n\tpublic avatar: string;\n\n\t@Column({ type: 'varchar', length: 50})\n\tpublic email: string;\n\n\t@Column({ type: 'varchar', length: 255})\n\tpublic desc: string;\n\n\t@Column({ \n\t\tname: 'secret_key',\n\t\ttype: 'varchar', \n\t\tlength: 255,\n\t\tunique: true\n\t})\n\tpublic secretKey: string;\n\n\t@Column({\n\t\tname: 'lightning_address',\n\t\ttype: 'varchar',\n\t\tlength: 255,\n\t\tunique: true,\n\t\tdefault: null\n\t})\n\tpublic lightningAddress: string | null;\n\n\t@Column({\n\t\tname: 'is_active',\n\t\ttype: 'boolean',\n\t\tdefault: true\n\t})\n\tpublic isActive: boolean;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({ name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/entity/CustomerTemp.ts",
    "content": "import { BaseEntity, Column, CreateDateColumn, Entity, Generated, PrimaryGeneratedColumn, UpdateDateColumn } from \"typeorm\";\n\n@Entity({ name: 'customer_temp'})\nexport class CustomerTemp extends BaseEntity {\n\n\t@PrimaryGeneratedColumn(\"uuid\")\n\tpublic id: string;\n\n\t@Generated(\"increment\")\n\t@Column({ name: \"customer_id\", type: 'bigint'})\n\tpublic customerId: number;\n\n\t@Column({ \n\t\tname: 'first_name',\n\t\ttype: 'varchar',\n\t\tlength: 20\n\t})\n\tpublic firstName: string;\n\n\t@Column({ \n\t\tname: 'last_name',\n\t\ttype: 'varchar',\n\t\tlength: 20\n\t})\n\tpublic lastName: string;\n\n\t@Column({ type: 'varchar', length: 255})\n\tpublic avatar: string;\n\n\t@Column({ type: 'varchar', length: 255})\n\tpublic desc: string;\n\n\t@Column({ \n\t\tname: 'secret_key',\n\t\ttype: 'varchar', \n\t\tlength: 255,\n\t\tunique: true\n\t})\n\tpublic secretKey: string;\n\n\t@Column({\n\t\tname: 'is_active',\n\t\ttype: 'boolean',\n\t\tdefault: true\n\t})\n\tpublic isActive: boolean;\n\n\t@CreateDateColumn({ name: 'created_at'})\n\tpublic createdAt: Date;\n\n\t@UpdateDateColumn({ name: 'updated_at'})\n\tpublic updatedAt: Date;\n\n}"
  },
  {
    "path": "aquila/search/src/helper/auth.ts",
    "content": "import { Action } from \"routing-controllers\";\nimport Container from \"typedi\";\nimport { AuthService } from \"../service/AuthService\";\n\nexport function authorizationChecker(action: Action): boolean {\n\tconst token = (action.request.headers.authorization || \"\").replace('Bearer ', '') || '';\n\tconst authService = Container.get(AuthService);\t\n\tauthService.authenticate(token);\n\treturn true;\n}"
  },
  {
    "path": "aquila/search/src/helper/decorators/jwtPayloadData.ts",
    "content": "import { Action, createParamDecorator } from \"routing-controllers\";\nimport Container from \"typedi\";\nimport { AuthService } from \"../../service/AuthService\";\n\nexport function JwtPayloadData() {\n\treturn createParamDecorator({\n\t\tvalue: (action: Action) => {\n\t\t\tconst token = (action.request.headers.authorization || \"\").replace('Bearer ', '') || '';\n\t\t\tconst authService = Container.get(AuthService);\n\t\t\tconst payload = authService.decodeToken(token);\n\t\t\treturn payload;\n\t\t}\n\t})\n}"
  },
  {
    "path": "aquila/search/src/helper/user.ts",
    "content": "import { Action } from \"routing-controllers\";\nimport Container from \"typedi\";\nimport { Customer } from \"../entity/Customer\";\nimport { CustomerTemp } from \"../entity/CustomerTemp\";\nimport { AuthService } from \"../service/AuthService\";\nimport { CustomerService } from \"../service/CustomerService\";\n\nexport async function currentUserChecker(action: Action): Promise<Customer|CustomerTemp> {\n\tconst token = (action.request.headers.authorization || \"\").replace('Bearer ', '') || '';\n\tconst authService = Container.get(AuthService);\n\tconst customerService = Container.get(CustomerService);\n\tconst payload = authService.decodeToken(token);\n\tconst customer = await customerService.getCustomerById(payload.customerId, payload.accountStatus);\n\treturn customer;\n}"
  },
  {
    "path": "aquila/search/src/index.ts",
    "content": "import { exit } from 'process';\nimport main from './app';\nimport { ConfigService } from './lib/ConfigService';\n\nconst configService = new ConfigService();\n\nconst port = configService.get('PORT');\nmain().then(app => {\n    app.listen(port, () => console.log(`App running on port ${port}`))\n}).catch(err => {\n    console.log(err);\n    exit(1);\n})"
  },
  {
    "path": "aquila/search/src/job/AppQueue.ts",
    "content": "import { Job, Queue } from \"bullmq\";\nimport { Service } from \"typedi\";\nimport connection from '../config/redisConnection';\nimport { AppJobNames } from \"./types\";\n\n\n@Service()\nexport class AppQueue {\n\tpublic queue: Queue;\n\n\tpublic constructor(){\n\t\tthis.queue = new Queue(\"APP\", { connection })\n\t}\n\n\tpublic async add<T>(name: AppJobNames, data: T) {\n\t\treturn await this.queue.add(name, data);\n\t}\n}"
  },
  {
    "path": "aquila/search/src/job/appWorker.ts",
    "content": "import { Worker } from \"bullmq\";\nimport Redis from \"ioredis\";\n\nexport function getAppWorker(connection: Redis) {\n\tconst processorFile = `${__dirname}/appWorkerProcessor.js`;\n\tconst worker = new Worker('APP', processorFile, { connection });\n\treturn worker;\n}"
  },
  {
    "path": "aquila/search/src/job/appWorkerProcessor.ts",
    "content": "import { Job } from \"bullmq\";\nimport Parser from \"@postlight/parser\";\nimport axios from 'axios';\nimport Container from \"typedi\";\nimport { DataSource } from \"typeorm\";\n\nimport db from '../config/db';\nimport { AppJobData, AppJobNames, IndexDocumentData } from \"./types\";\nimport { AquilaClientService } from \"../lib/AquilaClientService\";\nimport { AccountStatus } from \"../service/dto/AuthServiceDto\";\nimport { CollectionTemp } from \"../entity/CollectionTemp\";\nimport { Collection } from \"../entity/Collection\";\nimport { Bookmark, BookmarkStatus } from \"../entity/Bookmark\";\nimport { BookmarkPara } from \"../entity/BookmarkPara\";\nimport { BookmarkParaTemp } from \"../entity/BookmarkParaTemp\";\nimport { BookmarkTemp, BookmarkTempStatus } from \"../entity/BookmarkTemp\";\nimport { ConfigService } from \"../lib/ConfigService\";\n\n\nasync function summarize(html: string) {\n\tconst configService = Container.get(ConfigService);\n\tconst response = await axios.post(configService.get(\"SUMMARIZER_URL\"), { html });\t\n\treturn response.data.result;\n}\n\nlet dataSource: DataSource;\n\nexport default async function(job: Job<AppJobData, void, AppJobNames>) {\n\tif(job.name === AppJobNames.INDEX_DOCUMENT) {\n\t\t\tconst { data  } = <{data: IndexDocumentData}>job;\n\n\t\t\t// load database\n\t\t\tif(!dataSource) {\n\t\t\t\tdataSource = await db.initialize();\n\t\t\t}\n\n\t\t\t// load bookmark\n\t\t\tlet bookmarkObj: Bookmark | BookmarkTemp | null; \n\t\t\tif(data.accountStatus === AccountStatus.TEMPORARY) {\n\t\t\t\tbookmarkObj = await BookmarkTemp.findOne({ where: {id: data.bookmarkId}});\n\t\t\t}else {\n\t\t\t\tbookmarkObj = await Bookmark.findOne({ where: {id : data.bookmarkId}});\n\t\t\t}\n\t\t\tif(bookmarkObj) {\n\t\t\t\tconst bookmark: Bookmark | BookmarkTemp = bookmarkObj;\n\t\t\t\t// extract metadata from html\n\t\t\t\tconst parsedHtml = await Parser.parse(bookmark.url, { html: bookmark.html});\n\t\t\t\t// generate array summary from text content\n\t\t\t\tconst summary = await summarize(parsedHtml.content || \"\");\n\t\t\t\tif(bookmark.title) {\n\t\t\t\t\tsummary.push(bookmark.title);\n\t\t\t\t}\n\t\t\t\tif(bookmark.summary) {\n\t\t\t\t\tsummary.push(bookmark.summary);\n\t\t\t\t}\n\n\t\t\t\t// connect to aquila\n\t\t\t\tconst aquilaClient = Container.get(AquilaClientService)\n\t\t\t\tawait aquilaClient.connect();\n\n\t\t\t\t// load collection\n\t\t\t\tlet collection: Collection | CollectionTemp | null;\n\t\t\t\tif(data.accountStatus === AccountStatus.TEMPORARY) {\n\t\t\t\t\tcollection = await CollectionTemp.findOne({ where: { id: bookmark.collectionId }});\n\t\t\t\t}else {\n\t\t\t\t\tcollection = await Collection.findOne({ where: { id: bookmark.collectionId }});\n\t\t\t\t}\n\t\t\t\tif(collection === null) {\n\t\t\t\t\tthrow new Error('Collection not found');\n\t\t\t\t}\n\t\t\t\t// generate vector from array of paragraph \n\t\t\t\tconst vectorArray = await aquilaClient.getHubServer().compressDocument(collection.aquilaDbName, summary);\n\t\t\t\t// bulk insert into aquiladb\n\n\t\t\t\tlet bookmarkParas: BookmarkPara[] | BookmarkParaTemp[];\n\t\t\t\tawait db.transaction(async transactionalEntityManager => {\n\t\t\t\t\t// insert all para to bookmark_para table\n\t\t\t\t\tif(data.accountStatus === AccountStatus.TEMPORARY) {\n\t\t\t\t\t\tbookmarkParas = summary.map((para: string) => {\n\t\t\t\t\t\t\tconst bookmarkPara = new BookmarkParaTemp()\n\t\t\t\t\t\t\tbookmarkPara.bookmarkId = bookmark.id,\n\t\t\t\t\t\t\tbookmarkPara.content = para;\n\t\t\t\t\t\t\treturn bookmarkPara;\n\t\t\t\t\t\t})\n\t\t\t\t\t\tawait transactionalEntityManager.save(bookmarkParas);\n\t\t\t\t\t}else {\n\t\t\t\t\t\t\tbookmarkParas = summary.map((para: string) => {\n\t\t\t\t\t\t\tconst bookmarkPara = new BookmarkPara()\n\t\t\t\t\t\t\tbookmarkPara.bookmarkId = bookmark.id,\n\t\t\t\t\t\t\tbookmarkPara.content = para;\n\t\t\t\t\t\t\treturn bookmarkPara;\n\t\t\t\t\t\t})\n\t\t\t\t\t\tawait transactionalEntityManager.save(bookmarkParas);\n\t\t\t\t\t}\n\t\t\t\t\t// create documents on aquiladb\n\t\t\t\t\tconst documents = summary.map((para: string, index: number) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\tpara,\n\t\t\t\t\t\t\t\tbookmark_para_id: bookmarkParas[index].id,\n\t\t\t\t\t\t\t\tbookmark_id: bookmark.id\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcode: vectorArray[index]\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\tawait aquilaClient.getDbServer().createDocuments((collection as Collection | CollectionTemp).aquilaDbName, documents)\n\n\t\t\t\t\t// update status as PROCESSED\n\t\t\t\t\tif(data.accountStatus === AccountStatus.TEMPORARY) {\n\t\t\t\t\t\tbookmark.status = BookmarkTempStatus.PROCESSED;\n\t\t\t\t\t}else {\n\t\t\t\t\t\tbookmark.status = BookmarkStatus.PROCESSED;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait transactionalEntityManager.save(bookmark);\n\t\t\t\t});\n\t\t\t}\n\t}\n}"
  },
  {
    "path": "aquila/search/src/job/types.ts",
    "content": "import { Bookmark } from \"../entity/Bookmark\"\nimport { BookmarkTemp } from \"../entity/BookmarkTemp\"\nimport { AccountStatus } from \"../service/dto/AuthServiceDto\";\n\nexport enum AppJobNames {\n\tINDEX_DOCUMENT = 'INDEX_DOCUMENT'\n}\n\nexport interface IndexDocumentData {\n\tbookmarkId: string;\n\taccountStatus: AccountStatus\n}\n\nexport interface AddData {\n\tname: string;\n}\n\nexport type AppJobData = IndexDocumentData;"
  },
  {
    "path": "aquila/search/src/lib/AquilaClientService.ts",
    "content": "import { AquilaClient, Db, Hub, Schema, Wallet } from \"aquila-js\";\nimport path from \"path\";\nimport { Service } from \"typedi\";\nimport crypto from 'crypto';\nimport { ConfigService } from \"./ConfigService\";\n\n@Service()\nexport class AquilaClientService {\n\tprivate db: Db;\n\tprivate hub: Hub;\n\n\tpublic constructor(private configService: ConfigService) {}\n\n\tpublic async connect() {\n\t\tconst wallet = new Wallet( path.join(this.configService.get(\"AQUILA_DB_KEY_PATH\")));\n\t\tconst dbUrl = this.configService.get(\"AQUILA_DB_HOST\");\n\t\tconst dbPort = parseInt(this.configService.get(\"AQUILA_DB_PORT\"), 10);\n\t\tconst hubWallet = new Wallet( path.join(this.configService.get(\"AQUILA_HUB_KEY_PATH\")));\n\t\tconst hubUrl = this.configService.get(\"AQUILA_HUB_HOST\");\n\t\tconst hubPort = parseInt(this.configService.get(\"AQUILA_HUB_PORT\"), 10);\n\n\t\t// connecting to aquila db server\n\t\tthis.db = await AquilaClient.getDbServer(dbUrl, dbPort, wallet);\n\t\t// connecting to aquila hub server\n\t\tthis.hub = await AquilaClient.getHubServer(hubUrl, hubPort, hubWallet);\n\t}\n\n\tpublic getDbServer() {\n\t\treturn this.db;\n\t}\n\n\tpublic getHubServer() {\n\t\treturn this.hub;\n\t}\n\n\tpublic async createCollection(desc: string, secretKey: string) {\n\t\tconst hashSecret = crypto.createHash('sha256');\n\t\t\tconst schema: Schema = {\n\t\t\t\tdescription: desc,\n\t\t\t\tunique: hashSecret.update(secretKey).digest('hex'),\n\t\t\t\tencoder: \"strn:msmarco-distilbert-base-tas-b\",\n\t\t\t\tcodelen: 768,\n\t\t\t\tmetadata: {\n\t\t\t\t\t\t\"para\": \"string\",\n\t\t\t\t\t\t\"bookmark_para_id\": \"string\",\n\t\t\t\t\t\t\"bookmark_id\": \"string\"\n\t\t\t\t}\n\t\t\t};\n\t\tawait this.hub.createDatabase(schema);\n\t\tconst dbName = await this.db.createDatabase(schema);\n\t\treturn dbName;\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/lib/ConfigService.ts",
    "content": "import fs from 'fs';\nimport dotenv from 'dotenv';\nimport { Service } from 'typedi';\n\n@Service()\nexport class ConfigService {\n  constructor() {\n    this.loadEnv();\n  }\n\n  private loadEnv() {\n    let envFile;\n    const env = process.env.NODE_ENV || 'development';\n    switch (env) {\n      case 'production':\n        envFile = '.env.production';\n        break;\n      case 'test':\n        envFile = '.env.test';\n        break;\n      default:\n        envFile = '.env.development';\n    }\n    const path = `${__dirname}/../../${envFile}`;\n    const options: dotenv.DotenvConfigOptions = {}\n    if(fs.existsSync(path)) {\n      options.path = path;\n    }\n    dotenv.config(options);\n  }\n\n  get(key: string, defaultValue?: string): string {\n    let data = process.env[key];\n    if (!data && !defaultValue) {\n      throw new Error(`Environment variable not found [${key}]`);\n    }\n    if (!data && defaultValue) {\n      data = defaultValue;\n    }\n    return data as string;\n  }\n}"
  },
  {
    "path": "aquila/search/src/middleware/global/AuthMiddleware.ts",
    "content": "import { NextFunction, Request, Response } from 'express';\nimport { ExpressMiddlewareInterface } from 'routing-controllers';\nimport { Service } from 'typedi';\nimport { AuthService } from '../../service/AuthService';\n\n@Service()\nexport class AuthMiddleware implements ExpressMiddlewareInterface {\n\tpublic constructor(private authService: AuthService) {}\n\n\tpublic use(req: Request, res: Response, next: NextFunction): void {\n\t\tconst token = (req.headers.authorization || \"\").replace('Bearer ', '') || '';\n\t\tthis.authService.authenticate(token);\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/global/GlobalErrorMiddleware.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { ExpressErrorMiddlewareInterface, HttpError, Middleware } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { ValidationError } from \"../../utils/errors/ValidationError\";\n\n@Service()\n@Middleware({ type: 'after', priority: 1})\nexport class GlobalErrorHandler implements ExpressErrorMiddlewareInterface {\n\terror(err: Error, req: Request, res: Response, next: NextFunction) {\n\t\tconsole.log(err);\n\t\tif( err instanceof ValidationError) {\n\t\t\treturn res.status(err.httpCode).send({\n\t\t\t\tcode: err.httpCode,\n\t\t\t\tname: err.name,\n\t\t\t\tmessage: err.message,\n\t\t\t\terrors: err.errors\n\t\t\t});\n\t\t}\n\t\tif (err instanceof HttpError) {\n\t\t\treturn res.status(err.httpCode).send({\n\t\t\t\tcode: err.httpCode,\n\t\t\t\tname: err.name,\n\t\t\t\tmessage: err.message,\n\t\t\t});\n\t\t} else {\n\t\t\tconst env = process.env.NODE_ENV;\n\t\t\tres.status(500).send({\n\t\t\t\tcode: 500,\n\t\t\t\tname:  env === 'development' ? err.name : 'Unknown Error',\n\t\t\t\tmessage: env === 'development' ? err.message : 'Something went wrong',\n\t\t\t\tstack: env === 'development' ? err.stack : null,\n\t\t\t});\n\t\t}\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/global/TokenParserMiddleware.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { ExpressMiddlewareInterface, Middleware } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { AuthService } from \"../../service/AuthService\";\n\n@Service()\n@Middleware({type: 'before'})\nexport class TokenParserMiddleware implements ExpressMiddlewareInterface {\n\tpublic constructor(private authService: AuthService) {}\n\n\tpublic use(req: Request, res: Response, next: NextFunction) {\n\t\tconst token = (req.headers.authorization || \"\").replace('Bearer ', '') || '';\n\t\tif(token) {\n\t\t\treq.token = token;\n\t\t}\n\t\ttry{\n\t\t\tconst payload = this.authService.decodeToken(token);\n\t\t\treq.jwtTokenPayload = payload;\n\t\t}catch(e) {}\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/bookmark/AddBookmarkValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { body } from \"express-validator\";\nimport { ExpressMiddlewareInterface, Middleware } from \"routing-controllers\";\nimport Container, { Service } from \"typedi\";\n\nimport { JwtPayloadData } from \"../../../helper/decorators/jwtPayloadData\";\nimport { CollectionService } from \"../../../service/CollectionService\";\nimport { JwtPayload } from \"../../../service/dto/AuthServiceDto\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class AddBookmarkValidator implements ExpressMiddlewareInterface {\n\tpublic constructor(private collectionService: CollectionService, @JwtPayloadData() private jwtPayloadData: JwtPayload) {}\n\n\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tbody('html')\n\t\t\t\t// .trim().not().isEmpty()\n\t\t\t\t// .withMessage(\"Html is required\")\n\t\t\t\t// .bail()\n\t\t\t\t.isLength({max: 900000})\n\t\t\t\t.withMessage(\"Html content length should be less than 900,000 characters\"),\n\n\t\t\tbody(\"url\")\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Url is required\")\n\t\t\t\t.bail()\n\t\t\t\t.isLength({max: 2048})\n\t\t\t\t.withMessage(\"Url must be less than 2048 characters\")\n\t\t\t\t.bail()\n\t\t\t\t.isURL()\n\t\t\t\t.withMessage(\"Invalid url\")\n\t\t\t\t.bail()\n\t\t\t\t.custom((value) => {\n\t\t\t\t\tconst url = new URL(value);\n\t\t\t\t\tif(['www.localhost', 'localhost', 'www.127.0.0.1', '127.0.0.1'].includes(url.hostname)) {\n\t\t\t\t\t\tthrow new Error(`Url '${value}' not allowed`)\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}),\n\n\t\t\tbody('collectionId')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Collection Id is required\")\n\t\t\t\t.bail()\n\t\t\t\t.isUUID()\n\t\t\t\t.withMessage(\"Invalid Collection Id\")\n\t\t\t\t.bail()\n\t\t\t\t.custom(async (value) => {\n\t\t\t\t\tconst jwtPayloadData = req.jwtTokenPayload;\n\t\t\t\t\tif(jwtPayloadData) {\n\t\t\t\t\t\tconst collectionService = Container.get(CollectionService);\n\t\t\t\t\t\tconst collection = await collectionService.getCollectionById(value, jwtPayloadData.accountStatus);\n\t\t\t\t\t\tif(collection.customerId !== jwtPayloadData.customerId) {\n\t\t\t\t\t\t\tthrow new Error(\"Invalid collection id\");\t\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t})\n\t\t]\n\n\t\tawait validate(validators, req);\n\t\tnext();\n\t}\n} "
  },
  {
    "path": "aquila/search/src/middleware/validator/bookmark/GetBookmarkByCollectionIdValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { param, query } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport Container, { Service } from \"typedi\";\nimport { CollectionService } from \"../../../service/CollectionService\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetBookmarkByCollectionIdValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\tquery(\"limit\")\n\t\t\t.optional()\n\t\t\t.isNumeric()\n\t\t\t.withMessage(\"Limit should be number\")\n\t\t\t.isInt({ min: 1})\n\t\t\t.withMessage(\"Limit should be greater than or equal to 1\")\n\t\t\t.isInt({ max: 10 })\n\t\t\t.withMessage(\"Limit should be less than or equal to 10\"),\n\n\t\tquery(\"page\")\n\t\t\t.optional()\n\t\t\t.isNumeric()\n\t\t\t.withMessage(\"Page should be number\")\n\t\t\t.isInt({ min: 1})\n\t\t\t.withMessage(\"Page should be greater than or equal to 1\"),\n\t\t\t\n\t\tquery(\"query\")\n\t\t\t.optional()\n\t\t\t.isLength({ max: 50})\n\t\t\t.withMessage(\"Query must be less than 50 characters\"),\n\t\t\n\t\tparam(\"collectionId\")\n\t\t\t.isUUID()\n\t\t\t.withMessage(\"Invalid collection\")\n\t\t\t.bail()\n\t\t\t.custom(async (value) => {\n\t\t\t\tconst jwtPayloadData = req.jwtTokenPayload;\n\t\t\t\t\tif(jwtPayloadData) {\n\t\t\t\t\t\tconst collectionService = Container.get(CollectionService);\n\t\t\t\t\t\tconst collection = await collectionService.getCollectionById(value, jwtPayloadData.accountStatus);\n\t\t\t\t\t\tif(collection.customerId !== jwtPayloadData.customerId) {\n\t\t\t\t\t\t\tthrow new Error(\"Invalid collection id\");\t\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t})\n\t\t];\n\n\t\tawait validate(validators, req)\n\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/bookmark/GetFeaturedBookmarkValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { query } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetFeaturedBookmarkValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\tquery(\"limit\")\n\t\t\t.optional()\n\t\t\t.isNumeric()\n\t\t\t.withMessage(\"Limit should be number\")\n\t\t\t.isInt({ min: 1})\n\t\t\t.withMessage(\"Limit should be greater than or equal to 1\")\n\t\t\t.isInt({ max: 10 })\n\t\t\t.withMessage(\"Limit should be less than or equal to 10\"),\n\n\t\tquery(\"page\")\n\t\t\t.optional()\n\t\t\t.isNumeric()\n\t\t\t.withMessage(\"Page should be number\")\n\t\t\t.isInt({ min: 1})\n\t\t\t.withMessage(\"Page should be greater than or equal to 1\")\n\n\t\t];\n\n\t\tawait validate(validators, req)\n\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/bookmark/GetPublicBookmarkByCollectionIdParamValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { param, query } from \"express-validator\";\nimport { ExpressMiddlewareInterface, NotFoundError } from \"routing-controllers\";\nimport Container, { Service } from \"typedi\";\nimport { CollectionService } from \"../../../service/CollectionService\";\nimport { AccountStatus } from \"../../../service/dto/AuthServiceDto\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetPublicBookmarkByCollectionIdParamValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst collectionService = Container.get(CollectionService);\n\t\tconst collection = await collectionService.getCollectionById(req.params.customerId, AccountStatus.PERMANENT);\n\t\tif(!collection.isShareable) {\n\t\t\tthrow new NotFoundError(\"Collection Not found\");\n\t\t}\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/bookmark/GetPublicBookmarkByCollectionIdValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { param, query } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport Container, { Service } from \"typedi\";\nimport { CollectionService } from \"../../../service/CollectionService\";\nimport { AccountStatus } from \"../../../service/dto/AuthServiceDto\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetPublicBookmarkByCollectionIdValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\tquery(\"limit\")\n\t\t\t.optional()\n\t\t\t.isNumeric()\n\t\t\t.withMessage(\"Limit should be number\")\n\t\t\t.isInt({ min: 1})\n\t\t\t.withMessage(\"Limit should be greater than or equal to 1\")\n\t\t\t.isInt({ max: 10 })\n\t\t\t.withMessage(\"Limit should be less than or equal to 10\"),\n\n\t\tquery(\"page\")\n\t\t\t.optional()\n\t\t\t.isNumeric()\n\t\t\t.withMessage(\"Page should be number\")\n\t\t\t.isInt({ min: 1})\n\t\t\t.withMessage(\"Page should be greater than or equal to 1\"),\n\t\t\t\n\t\tquery(\"query\")\n\t\t\t.optional()\n\t\t\t.isLength({ max: 50})\n\t\t\t.withMessage(\"Query must be less than 50 characters\"),\n\t\t\n\t\tparam(\"collectionId\")\n\t\t\t.isUUID()\n\t\t\t.withMessage(\"Invalid collection\")\n\t\t];\n\n\t\tawait validate(validators, req)\n\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/collection/GetAllFeaturedCollectionValidator.ts",
    "content": "import { NextFunction, Request } from \"express\";\nimport { query } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetAllFeaturedCollectionValidator implements ExpressMiddlewareInterface {\n\tasync use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tquery(\"limit\")\n\t\t\t\t.optional()\n\t\t\t\t.isNumeric()\n\t\t\t\t.withMessage(\"Limit must be a number\")\n\t\t\t\t.isInt({min: 1})\n\t\t\t\t.withMessage(\"Limit must be greater than 1\")\n\t\t\t\t.isInt({ max: 10 })\n\t\t\t\t.withMessage(\"Limit must be less than or equal to 10\"),\n\n\t\t\tquery(\"page\")\n\t\t\t\t.optional()\n\t\t\t\t.isNumeric()\n\t\t\t\t.withMessage(\"Page must be a number\")\n\n\t\t]\n\t\tawait validate(validators, req);\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/collection/GetAllPublicCollectionValidator.ts",
    "content": "import { NextFunction, Request } from \"express\";\nimport { query } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetAllPublicCollectionValidator implements ExpressMiddlewareInterface {\n\tasync use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tquery(\"limit\")\n\t\t\t\t.optional()\n\t\t\t\t.isNumeric()\n\t\t\t\t.withMessage(\"Limit must be a number\")\n\t\t\t\t.isInt({min: 1})\n\t\t\t\t.withMessage(\"Limit must be greater than 1\")\n\t\t\t\t.isInt({ max: 10 })\n\t\t\t\t.withMessage(\"Limit must be less than or equal to 10\"),\n\n\t\t\tquery(\"page\")\n\t\t\t\t.optional()\n\t\t\t\t.isNumeric()\n\t\t\t\t.withMessage(\"Page must be a number\")\n\n\t\t]\n\t\tawait validate(validators, req);\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/collection/GetPublicCollectionByIdValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { param } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetPublicCollectionByIdValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tparam(\"collectionId\")\n\t\t\t\t.isUUID()\n\t\t\t\t.withMessage(\"Invalid collection id\"),\n\t\t];\n\n\t\tawait validate(validators, req);\n\t\tnext()\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/csubscription/SubscribeCollectionValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { BadRequestError, ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\n\nimport { JwtPayloadData } from \"../../../helper/decorators/jwtPayloadData\";\nimport { CollectionSubscriptionService } from \"../../../service/CollectionSubscriptionService\";\nimport { JwtPayload } from \"../../../service/dto/AuthServiceDto\";\n\n@Service()\nexport class SubscribeCollectionValidator implements ExpressMiddlewareInterface {\n\tpublic constructor(private collectionSubService: CollectionSubscriptionService, @JwtPayloadData() private jwtPayloadData: JwtPayload) {}\n\n\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst jwtPayloadData = req.jwtTokenPayload;\n\t\tif(jwtPayloadData) {\n\t\t\tconst status = await this.collectionSubService.isCollectionSubscribedByCustomer(req.params.collectionId, jwtPayloadData.customerId, jwtPayloadData.accountStatus);\n\t\t\tif(status) {\n\t\t\t\tthrow new BadRequestError(\"Collection is already subscribed\");\t\n\t\t\t}\n\n\t\t\tconst totalSubscriptions = await this.collectionSubService.getTotalCollectionSubscribedByCustomer(jwtPayloadData.customerId, jwtPayloadData.accountStatus);\n\t\t\tif(totalSubscriptions > 5) {\n\t\t\t\tthrow new BadRequestError(\"You have reached maximum number of subscriptions\");\n\t\t\t}\n\t\t}\n\t\tnext();\n\t}\n} "
  },
  {
    "path": "aquila/search/src/middleware/validator/csubscription/UnSubscribeCollectionValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { param } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\n\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class UnSubscribeCollectionValidator implements ExpressMiddlewareInterface {\n\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tparam('collectionId')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Collection Id is required\")\n\t\t\t\t.bail()\n\t\t\t\t.isUUID()\n\t\t\t\t.withMessage(\"Invalid Collection Id\")\n\t\t];\n\n\t\tawait validate(validators, req);\n\t\tnext();\n\t}\n} "
  },
  {
    "path": "aquila/search/src/middleware/validator/customer/ActivateCustomerValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { body } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport Container, { Service } from \"typedi\";\nimport { CustomerService } from \"../../../service/CustomerService\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class ActivateCustomerValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tbody('firstName')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"First name is required\")\n\t\t\t\t.isLength({ min: 3})\n\t\t\t\t.withMessage(\"First should have atleast 3 characters\")\n\t\t\t\t.isLength({ max: 15})\n\t\t\t\t.withMessage(\"First should be less than or equal to 15 characters\")\n\t\t\t\t.matches(/^[a-zA-Z]*[a-zA-Z]$/).withMessage(\"Description must contain only alpha numeric characters\"),\n\n\t\t\tbody('lastName')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Last name is required\")\n\t\t\t\t.isLength({ min: 3})\n\t\t\t\t.withMessage(\"First should have atleast 3 characters\")\n\t\t\t\t.isLength({ max: 15})\n\t\t\t\t.withMessage(\"First should be less than or equal to 15 characters\")\n\t\t\t\t.matches(/^[a-zA-Z]*[a-zA-Z]$/).withMessage(\"Description must contain only alpha numeric characters\"),\n\n\t\t\tbody('email')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Email is required\")\t\n\t\t\t\t.isEmail()\n\t\t\t\t.withMessage(\"Invalid email\")\n\t\t\t\t.bail()\n\t\t\t\t.custom(async (value) => {\n\t\t\t\t\tconst customerService = Container.get(CustomerService);\n\t\t\t\t\tconst customer = await customerService.findCustomerByEmailId(value);\n\t\t\t\t\tif(customer) {\n\t\t\t\t\t\tthrow new Error(\"Email already exists\");\n\t\t\t\t\t}\n\t\t\t\t}),\n\n\t\t\tbody('desc')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Description is required\")\n\t\t\t\t.isLength({ min: 50})\n\t\t\t\t.withMessage(\"Description should have atleast 50 characters\")\n\t\t\t\t.isLength({max: 255})\n\t\t\t\t.withMessage(\"Description should be less than or equal to 255 characters\"),\n\t\t\t\t// .matches(/^[a-zA-Z0-9]*[a-zA-Z0-9]$/).withMessage(\"Description must contain only alpha numeric characters\"),\n\t\t];\n\n\t\tawait validate(validators, req);\n\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/customer/CreateCustomerValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { body } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class CreateCustomerValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tbody('firstName')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"First name is required\")\n\t\t\t\t.isLength({ min: 3})\n\t\t\t\t.withMessage(\"First should have atleast 3 characters\")\n\t\t\t\t.isLength({ max: 15})\n\t\t\t\t.withMessage(\"First should be less than or equal to 15 characters\")\n\t\t\t\t.matches(/^[a-zA-Z]*[a-zA-Z]$/).withMessage(\"First name must contain only alpha characters\"),\n\n\t\t\tbody('lastName')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Last name is required\")\n\t\t\t\t.isLength({ min: 3})\n\t\t\t\t.withMessage(\"First should have atleast 3 characters\")\n\t\t\t\t.isLength({ max: 15})\n\t\t\t\t.withMessage(\"First should be less than or equal to 15 characters\")\n\t\t\t\t.matches(/^[a-zA-Z]*[a-zA-Z]$/).withMessage(\"Last name must contain only alpha characters\"),\n\t\t];\n\n\t\tawait validate(validators, req);\n\n\t\tnext();\n\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/customer/GetCustomerPublicInfoByIdValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { param } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class GetCustomerPublicInfoByIdValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tparam('customerId')\n\t\t\t\t.isUUID()\n\t\t\t\t.withMessage(\"Invalid Customer Id\")\n\t\t];\n\n\t\tawait validate(validators, req);\n\t\tnext();\n\t}\n}"
  },
  {
    "path": "aquila/search/src/middleware/validator/customer/UpdateCustomerValidator.ts",
    "content": "import { NextFunction, Request, Response } from \"express\";\nimport { body } from \"express-validator\";\nimport { ExpressMiddlewareInterface } from \"routing-controllers\";\nimport Container, { Service } from \"typedi\";\nimport { Customer } from \"../../../entity/Customer\";\nimport { CustomerService } from \"../../../service/CustomerService\";\nimport { AccountStatus } from \"../../../service/dto/AuthServiceDto\";\nimport { validate } from \"../../../utils/validate\";\n\n@Service()\nexport class UpdateCustomerValidator implements ExpressMiddlewareInterface {\n\tpublic async use(req: Request, res: Response, next: NextFunction) {\n\t\tconst validators = [\n\t\t\tbody('firstName')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"First name is required\")\n\t\t\t\t.isLength({ min: 3})\n\t\t\t\t.withMessage(\"First should have atleast 3 characters\")\n\t\t\t\t.isLength({ max: 15})\n\t\t\t\t.withMessage(\"First should be less than or equal to 15 characters\")\n\t\t\t\t.matches(/^[a-zA-Z]*[a-zA-Z]$/).withMessage(\"Description must contain only alpha numeric characters\"),\n\n\t\t\tbody('lastName')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Last name is required\")\n\t\t\t\t.isLength({ min: 3})\n\t\t\t\t.withMessage(\"First should have atleast 3 characters\")\n\t\t\t\t.isLength({ max: 15})\n\t\t\t\t.withMessage(\"First should be less than or equal to 15 characters\")\n\t\t\t\t.matches(/^[a-zA-Z]*[a-zA-Z]$/).withMessage(\"Description must contain only alpha numeric characters\"),\n\n\t\t\tbody('email')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Email is required\")\t\n\t\t\t\t.isEmail()\n\t\t\t\t.withMessage(\"Invalid email\")\n\t\t\t\t.bail()\n\t\t\t\t.custom(async (value, meta) => {\n\t\t\t\t\tconst jwtPayloadData = req.jwtTokenPayload;\n\t\t\t\t\tif(jwtPayloadData) {\n\t\t\t\t\t\tconst customerService = Container.get(CustomerService);\n\t\t\t\t\t\tconst customer = await customerService.getCustomerById(jwtPayloadData?.customerId, AccountStatus.PERMANENT) as Customer;\n\t\t\t\t\t\tif(value === customer.email) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// check email exists\n\t\t\t\t\t\tconst customerExists = await customerService.findCustomerByEmailId(value);\n\t\t\t\t\t\tif(customerExists) {\n\t\t\t\t\t\t\tthrow new Error(\"Email already exists\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}),\n\n\n\t\t\tbody('desc')\n\t\t\t\t.trim().not().isEmpty()\n\t\t\t\t.withMessage(\"Description is required\")\n\t\t\t\t.isLength({ min: 50})\n\t\t\t\t.withMessage(\"Description should have atleast 50 characters\")\n\t\t\t\t.isLength({max: 255})\n\t\t\t\t.withMessage(\"Description should be less than or equal to 255 characters\")\n\t\t\t\t// .matches(/^[a-zA-Z0-9]*[a-zA-Z0-9]$/).withMessage(\"Description must contain only alpha numeric characters\"),\n\t\t];\n\n\t\tawait validate(validators, req);\n\n\t\tnext();\n\n\t}\n}"
  },
  {
    "path": "aquila/search/src/migrations/1676714378990-bookmark.ts",
    "content": "import { MigrationInterface, QueryRunner } from \"typeorm\";\n\nexport class bookmark1676714378990 implements MigrationInterface {\n    name = 'bookmark1676714378990'\n\n    public async up(queryRunner: QueryRunner): Promise<void> {\n        await queryRunner.query(`CREATE TYPE \"public\".\"bookmark_status_enum\" AS ENUM('NOT_PROCESSED', 'PROCESSING', 'PROCESSED')`);\n        await queryRunner.query(`CREATE TABLE \"bookmark\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"collection_id\" uuid NOT NULL, \"url\" character varying(2048) NOT NULL, \"html\" text NOT NULL, \"title\" character varying(2048), \"author\" character varying(100), \"cover_img\" character varying(2048), \"summary\" text, \"links\" character varying(2048), \"is_hidden\" boolean NOT NULL DEFAULT false, \"status\" \"public\".\"bookmark_status_enum\" NOT NULL DEFAULT 'NOT_PROCESSED', \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_b7fbf4a865ba38a590bb9239814\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"bookmark_para_temp\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"bookmark_id\" character varying NOT NULL, \"content\" text NOT NULL, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_96228babfbf0e3d39503847b19f\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"bookmark_para\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"bookmark_id\" character varying NOT NULL, \"content\" text NOT NULL, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_80453e30c727ef75d8d3a227ae1\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TYPE \"public\".\"bookmark_temp_status_enum\" AS ENUM('NOT_PROCESSED', 'PROCESSING', 'PROCESSED')`);\n        await queryRunner.query(`CREATE TABLE \"bookmark_temp\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"collection_id\" uuid NOT NULL, \"url\" character varying(2048) NOT NULL, \"html\" text NOT NULL, \"title\" character varying(100), \"author\" character varying(100), \"cover_img\" character varying(255), \"summary\" character varying(255), \"links\" character varying(255), \"is_hidden\" boolean NOT NULL DEFAULT false, \"status\" \"public\".\"bookmark_temp_status_enum\" NOT NULL DEFAULT 'NOT_PROCESSED', \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_1e23a591867b46d1d25cdd69421\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"customer\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"customer_id\" BIGSERIAL NOT NULL, \"first_name\" character varying(20) NOT NULL, \"last_name\" character varying(20) NOT NULL, \"avatar\" character varying(255) NOT NULL, \"email\" character varying(50) NOT NULL, \"desc\" character varying(255) NOT NULL, \"secret_key\" character varying(255) NOT NULL, \"lightning_address\" character varying(255), \"is_active\" boolean NOT NULL DEFAULT true, \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"UQ_5f387140f14dda0d07e8c69d94e\" UNIQUE (\"secret_key\"), CONSTRAINT \"UQ_0eb8dbfdf208da3611520781da9\" UNIQUE (\"lightning_address\"), CONSTRAINT \"PK_a7a13f4cacb744524e44dfdad32\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"collection\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying(25) NOT NULL, \"desc\" character varying(255) NOT NULL, \"customer_id\" uuid NOT NULL, \"aquila_db_name\" character varying(255) NOT NULL, \"is_shareable\" boolean NOT NULL DEFAULT true, \"indexed_docs_count\" bigint NOT NULL DEFAULT '0', \"is_featured\" boolean NOT NULL DEFAULT false, \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"UQ_f6f5b901feb7458d7f0ae8e40a0\" UNIQUE (\"aquila_db_name\"), CONSTRAINT \"PK_ad3f485bbc99d875491f44d7c85\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"collection_subscription\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"collection_id\" uuid NOT NULL, \"subscriber_id\" uuid NOT NULL, \"subscribed_at\" TIMESTAMP NOT NULL DEFAULT now(), \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_871ce8ad8c0bd303596085c69b3\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"collection_subscription_temp\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"collection_id\" uuid NOT NULL, \"subscriber_id\" uuid NOT NULL, \"subscribed_at\" TIMESTAMP NOT NULL DEFAULT now(), \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_0c00e1823a7935706679daab419\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"collection_temp\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying(25) NOT NULL, \"desc\" character varying(255) NOT NULL, \"customer_id\" uuid NOT NULL, \"aquila_db_name\" character varying(255) NOT NULL, \"is_shareable\" boolean NOT NULL DEFAULT true, \"indexed_docs_count\" bigint NOT NULL DEFAULT '0', \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"UQ_55a8fd150df3f170c789a81affe\" UNIQUE (\"aquila_db_name\"), CONSTRAINT \"PK_658841bdb83ea4263af2e64a683\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`CREATE TABLE \"customer_temp\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"customer_id\" BIGSERIAL NOT NULL, \"first_name\" character varying(20) NOT NULL, \"last_name\" character varying(20) NOT NULL, \"avatar\" character varying(255) NOT NULL, \"desc\" character varying(255) NOT NULL, \"secret_key\" character varying(255) NOT NULL, \"is_active\" boolean NOT NULL DEFAULT true, \"created_at\" TIMESTAMP NOT NULL DEFAULT now(), \"updated_at\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"UQ_0754f469522cf14ad9beae89a61\" UNIQUE (\"secret_key\"), CONSTRAINT \"PK_0a1542f39ffea6cffd26ce1a731\" PRIMARY KEY (\"id\"))`);\n        await queryRunner.query(`ALTER TABLE \"collection\" ADD CONSTRAINT \"FK_fbcfcef552d9e814bc2980b4401\" FOREIGN KEY (\"customer_id\") REFERENCES \"customer\"(\"id\") ON DELETE NO ACTION ON UPDATE NO ACTION`);\n    }\n\n    public async down(queryRunner: QueryRunner): Promise<void> {\n        await queryRunner.query(`ALTER TABLE \"collection\" DROP CONSTRAINT \"FK_fbcfcef552d9e814bc2980b4401\"`);\n        await queryRunner.query(`DROP TABLE \"customer_temp\"`);\n        await queryRunner.query(`DROP TABLE \"collection_temp\"`);\n        await queryRunner.query(`DROP TABLE \"collection_subscription_temp\"`);\n        await queryRunner.query(`DROP TABLE \"collection_subscription\"`);\n        await queryRunner.query(`DROP TABLE \"collection\"`);\n        await queryRunner.query(`DROP TABLE \"customer\"`);\n        await queryRunner.query(`DROP TABLE \"bookmark_temp\"`);\n        await queryRunner.query(`DROP TYPE \"public\".\"bookmark_temp_status_enum\"`);\n        await queryRunner.query(`DROP TABLE \"bookmark_para\"`);\n        await queryRunner.query(`DROP TABLE \"bookmark_para_temp\"`);\n        await queryRunner.query(`DROP TABLE \"bookmark\"`);\n        await queryRunner.query(`DROP TYPE \"public\".\"bookmark_status_enum\"`);\n    }\n\n}\n"
  },
  {
    "path": "aquila/search/src/service/AuthService.ts",
    "content": "import jwt, { Jwt } from 'jsonwebtoken';\nimport { BadRequestError, UnauthorizedError } from 'routing-controllers';\nimport { Service } from 'typedi';\n\nimport { Customer } from '../entity/Customer';\nimport { CustomerTemp } from '../entity/CustomerTemp';\nimport { ConfigService } from '../lib/ConfigService';\nimport { AccountStatus, JwtPayload } from './dto/AuthServiceDto';\n\n@Service()\nexport class AuthService {\n\n\tpublic constructor(private configService: ConfigService) {}\n\n\tpublic authenticate(token: string) {\n\t\tconst secret = this.configService.get('JWT_SECRET');\n\t\ttry {\n\t\tjwt.verify(token, secret);\n\t\t}catch(e) {\n\t\t\tthrow new UnauthorizedError(\"Authorization failed\");\n\t\t}\n\t}\n\n\tpublic decodeToken(token: string): JwtPayload {\n\t\tconst decodedToken = jwt.decode(token) as JwtPayload;\n\t\treturn decodedToken;\n\t}\n\n\tprivate generateToken(payload: JwtPayload): string {\n\t\tconst jwtSecret = this.configService.get('JWT_SECRET');\n\t\tconst expiresIn = this.configService.get('JWT_EXPIRES_IN');\n\t\tconst token = jwt.sign(payload, jwtSecret, { expiresIn })\n\t\treturn token;\n\t}\n\n\tpublic async login(secretKey: string): Promise<string> {\n\t\ttry{\n\t\t\treturn await this.loginPermanentCustoemr(secretKey);\n\t\t}catch(e) {\n\t\t\tif(!(e instanceof BadRequestError)) {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\treturn await this.loginTemporaryCustomer(secretKey);\n\t}\n\n\tpublic async loginPermanentCustoemr(secretKey: string): Promise<string>{\n\t\t// check secret is valid\n\t\tconst customer = await Customer.findOne({ where: {secretKey} })\n\t\tif(!customer) {\n\t\t\tthrow new BadRequestError(\"Invalid credentials\");\n\t\t}\n\n\t\t// if valid secret generate token\n\t\tconst payload = {\n\t\t\tcustomerId: customer.id,\n\t\t\tfirstName: customer.firstName,\n\t\t\tlastName: customer.lastName,\n\t\t\tcreatedAt: customer.createdAt,\n\t\t\taccountStatus: AccountStatus.PERMANENT\n\t\t};\n\t\tconst token = this.generateToken(payload);\n\t\treturn token;\n\t}\n\n\tpublic async loginTemporaryCustomer(secretKey: string): Promise<string> {\n\t\t\t// check secret is valid\n\t\t\tconst customer = await CustomerTemp.findOne({ where: { secretKey } })\n\t\t\tif(!customer) {\n\t\t\t\tthrow new BadRequestError(\"Invalid credentials\");\n\t\t\t}\n\t\n\t\t\t// if valid secret generate token\n\t\t\tconst payload = {\n\t\t\t\tcustomerId: customer.id,\n\t\t\t\tfirstName: customer.firstName,\n\t\t\t\tlastName: customer.lastName,\n\t\t\t\taccountStatus: AccountStatus.TEMPORARY\n\t\t\t};\n\t\t\tconst token = this.generateToken(payload);\n\t\t\treturn token;\n\t}\n}"
  },
  {
    "path": "aquila/search/src/service/BookmarkService.ts",
    "content": "import { BadRequestError, InternalServerError } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { In } from \"typeorm\";\nimport puppeteer from 'puppeteer-core';\nimport * as cheerio from \"cheerio\";\n\nimport dataSource from \"../config/db\";\nimport { Bookmark, BookmarkStatus } from \"../entity/Bookmark\";\nimport { BookmarkPara } from \"../entity/BookmarkPara\";\nimport { BookmarkParaTemp } from \"../entity/BookmarkParaTemp\";\nimport { BookmarkTemp, BookmarkTempStatus } from \"../entity/BookmarkTemp\";\nimport { Collection } from \"../entity/Collection\";\nimport { CollectionTemp } from \"../entity/CollectionTemp\";\nimport { AppQueue } from \"../job/AppQueue\";\nimport { AppJobNames, IndexDocumentData } from \"../job/types\";\nimport { AquilaClientService } from \"../lib/AquilaClientService\";\nimport { AccountStatus } from \"./dto/AuthServiceDto\";\nimport { AddBookmarkInputDto, GetAllBookmarksByCollectionIdOptionsInputDto, GetBookmarksByCollectionIdOutputDto, GetBookmarksByCollectionIdOptionsInputDto, GetFeaturedBookmarksOutputDto } from \"./dto/BookmarkServiceDto\";\nimport { ConfigService } from \"../lib/ConfigService\";\n\n@Service()\nexport class BookmarkService {\n\n\tpublic constructor(private appQueue: AppQueue, private aquilaClientService: AquilaClientService, private configService: ConfigService) {}\n\n\tprivate async fetchWebsiteContent(url: string): Promise<string> {\n\t\tconst broswerlessAPIKey = this.configService.get(\"BROWSERLESS_API_KEY\");\n\t\tconst browser = await puppeteer.connect({\n\t\t\tbrowserWSEndpoint: `wss://chrome.browserless.io?token=${broswerlessAPIKey}&ignoreDefaultArgs=true`,\n\t\t});\n\n\t\tconst page = await browser.newPage();\n\t\tawait page.goto(url, {waitUntil: 'domcontentloaded'});\n\t\tconst content = await page.content();\n\t\tawait browser.close();\n\n\t\treturn content;\n\t}\n\n\tprivate async addTemporaryBookmark(data: AddBookmarkInputDto): Promise<BookmarkTemp> {\n\t\tlet bookmark = new BookmarkTemp();\n\t\tawait dataSource.transaction(async transactionalEntityManager => {\n\t\t\tbookmark.url = data.url;\n\t\t\tlet htmlTmp = \"\"\n\t\t\tif(data.html === undefined) {\n\t\t\t\thtmlTmp = await this.fetchWebsiteContent(data.url);\n\t\t\t}\n\t\t\tconst $ = cheerio.load(htmlTmp);\n\t\t\tconst title = $(\"head\").find(\"title\").text() || \"\";\n\t\t\tconst metaDescription = $(\"meta[name='description']\").attr(\"content\") || \"\";\n\n\t\t\tbookmark.html = data.html || htmlTmp;\n\t\t\tbookmark.title = title;\n\t\t\tbookmark.summary = metaDescription;\n\t\t\t\t\n\t\t\tbookmark.collectionId = data.collectionId;\n\t\t\tawait transactionalEntityManager.save(bookmark);\n\n\t\t\tawait this.appQueue.add<IndexDocumentData>(AppJobNames.INDEX_DOCUMENT, { accountStatus: AccountStatus.TEMPORARY, bookmarkId: bookmark.id});\n\t\t})\n\t\treturn bookmark;\n\t}\n\n\tprivate async addPermanentBookmark(data: AddBookmarkInputDto): Promise<Bookmark> {\n\t\tlet bookmark = new Bookmark();\n\t\tawait dataSource.transaction(async transactionalEntityManager => {\n\t\t\tbookmark.url = data.url;\n\t\t\t\n\t\t\tlet htmlTmp = \"\"\n\t\t\tif(data.html === undefined) {\n\t\t\t\thtmlTmp = await this.fetchWebsiteContent(data.url);\n\t\t\t}\n\t\t\tconst $ = cheerio.load(htmlTmp);\n\t\t\tconst title = $(\"head\").find(\"title\").text() || \"\";\n\t\t\tconst metaDescription = $(\"meta[name='description']\").attr(\"content\") || \"\";\n\t\t\tbookmark.html = data.html || htmlTmp;\n\t\t\tbookmark.title = title;\n\t\t\tbookmark.summary = metaDescription;\n\t\t\t\n\t\t\tbookmark.collectionId = data.collectionId;\n\t\t\tawait transactionalEntityManager.save(bookmark);\n\n\t\t\tawait this.appQueue.add<IndexDocumentData>(AppJobNames.INDEX_DOCUMENT, { accountStatus: AccountStatus.PERMANENT, bookmarkId: bookmark.id});\n\t\t})\n\t\treturn bookmark;\n\t}\n\n\tpublic async addBookmark(data: AddBookmarkInputDto, accountStatus: AccountStatus): Promise<Bookmark|BookmarkTemp> {\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.addTemporaryBookmark(data);\n\t\t}\n\t\treturn await this.addPermanentBookmark(data);\n\t}\t\n\n\tprivate async getAllTemporaryBookmarksByCollectionId(collectionId: string, options: GetAllBookmarksByCollectionIdOptionsInputDto): Promise<GetBookmarksByCollectionIdOutputDto> {\n\t\tconst skip = (options.page - 1) * options.limit;\n\t\tconst take = options.limit;\n\t\tconst totalRecords = await BookmarkTemp.count({ where: { collectionId, status: BookmarkTempStatus.PROCESSED }});\n\t\tconst bookmarks = await BookmarkTemp.find({ where: { collectionId, status: BookmarkTempStatus.PROCESSED }, skip, take });\n\t\t// find all paragraphs for bookmark\n\t\tconst bookmarkIds = bookmarks.map(item => item.id);\n\t\tconst paras = await BookmarkParaTemp.find({ where: { bookmarkId: In(bookmarkIds)}});\n\t\tconst bookmarkData = bookmarks.map(item => ({\n\t\t\tid: item.id,\n\t\t\tcollectionId: item.collectionId,\n\t\t\turl: item.url,\n\t\t\ttitle: item.title,\n\t\t\tauthor: item.author,\n\t\t\tcoverImg: item.coverImg,\n\t\t\tsummary: item.summary,\n\t\t\tdescription: paras.find(para => para.bookmarkId === item.id)?.content || '',\n\t\t\tcreatedAt: item.createdAt\n\t\t}));\n\t\treturn {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / take),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\n\t}\n\n\tprivate async getAllPermanentBookmarksByCollectionId(collectionId: string, options: GetAllBookmarksByCollectionIdOptionsInputDto): Promise<GetBookmarksByCollectionIdOutputDto> {\n\t\tconst skip = (options.page - 1) * options.limit;\n\t\tconst take = options.limit;\n\t\tconst totalRecords = await Bookmark.count({ where: { collectionId, status: BookmarkStatus.PROCESSED }});\n\t\tconst bookmarks = await Bookmark.find({ where: { collectionId, status: BookmarkStatus.PROCESSED}, skip, take });\n\t\t// find all paragraphs for bookmark\n\t\tconst bookmarkIds = bookmarks.map(item => item.id);\n\t\tconst paras = await BookmarkPara.find({ where: { bookmarkId: In(bookmarkIds)}});\n\t\tconst bookmarkData = bookmarks.map(item => ({\n\t\t\tid: item.id,\n\t\t\tcollectionId: item.collectionId,\n\t\t\turl: item.url,\n\t\t\ttitle: item.title,\n\t\t\tauthor: item.author,\n\t\t\tcoverImg: item.coverImg,\n\t\t\tsummary: item.summary,\n\t\t\tdescription: paras.find(para => para.bookmarkId === item.id)?.content || '',\n\t\t\tcreatedAt: item.createdAt\n\t\t}));\n\t\treturn {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / take),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\t\n\t}\n\n\tprivate async getTemporaryBookmarksByCollectionId(collectionId: string, options: GetBookmarksByCollectionIdOptionsInputDto): Promise<GetBookmarksByCollectionIdOutputDto> {\n\t\tif(!options.query) {\n\t\t\treturn await this.getAllTemporaryBookmarksByCollectionId(collectionId, options);\n\t\t}\n\t\tconst collection = await CollectionTemp.findOne({ where: { id: collectionId }});\n\t\tif(!collection) {\n\t\t\tthrow new BadRequestError(\"Invalid collection id\");\n\t\t}\n\t\t// generate vector from hub for the search query\n\t\tconst vector = await this.aquilaClientService.getHubServer().compressDocument(collection.aquilaDbName, [options.query]) as number[][];\n\t\tif(vector.length === 0) {\n\t\t\tthrow new InternalServerError(\"Something went wrong\");\n\t\t}\n\n\t\t// search on aquiladb\n\t\tconst { docs, dists } = await this.aquilaClientService.getDbServer().searchKDocuments(collection.aquilaDbName, vector, 100)\n\t\tconst documentObjs: any = {};\n\t\t// const newDists = dists[0].map(dist => (1 - dist))\n\t\tconst newDists = dists[0];\n\t\tdocs[0].forEach((doc: any, index: number) => {\n\t\t\tconst docExists = documentObjs[doc.metadata.bookmark_id];\n\t\t\tif(!docExists) {\n\t\t\t\tdocumentObjs[doc.metadata.bookmark_id] = {\n\t\t\t\t\tbookmarkParaId: doc.metadata.bookmark_para_id,\n\t\t\t\t\tbookmarkId: doc.metadata.bookmark_id,\n\t\t\t\t\tdist:  newDists[index],\n\t\t\t\t\tparas: [{ dist: newDists[index], para: doc.metadata.para}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tconst documents = Object.values(documentObjs).sort((a: any, b: any) => (b.dist - a.dist))\n\n\t\t// sort result from aquiladb and select records within limit and offset\n\t\tconst totalRecords = documents.length;\n\t\tconst start = (options.page -1) * options.limit;\n\t\tconst end = ((options.page -1) * options.limit) + options.limit;\n\t\tconst records = documents.slice(start, end);\n\n\t\t// fetch all bookmarks\n\t\tconst bookmarkIds = records.map((item: any) => item.bookmarkId);\n\t\tconst bookmarks = await BookmarkTemp.find({ where: { id: In(bookmarkIds)}});\n\n\t\t// generate result\n\t\tconst bookmarkData = records.map((item: any) => {\n\t\t\tconst bookmark = bookmarks.find(data => data.id === item.bookmarkId) as BookmarkTemp;\n\t\t\treturn ({\n\t\t\t\tid: bookmark.id,\n\t\t\t\tcollectionId: bookmark.collectionId,\n\t\t\t\turl: bookmark.url,\n\t\t\t\ttitle: bookmark.title,\n\t\t\t\tauthor: bookmark.author,\n\t\t\t\tcoverImg: bookmark.coverImg,\n\t\t\t\tsummary: bookmark.summary,\n\t\t\t\tdescription: item.paras[0].para\n\t\t\t});\n\t\t});\n\t\tconst output = {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / options.limit),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\n\t\treturn output;\n\t} \n\n\tprivate async getPermanentBookmarksByCollectionId(collectionId: string, options: GetBookmarksByCollectionIdOptionsInputDto): Promise<GetBookmarksByCollectionIdOutputDto> {\n\t\tif(!options.query) {\n\t\t\treturn await this.getAllPermanentBookmarksByCollectionId(collectionId, options);\n\t\t}\n\t\tconst collection = await Collection.findOne({ where: { id: collectionId }});\n\t\tif(!collection) {\n\t\t\tthrow new BadRequestError(\"Invalid collection id\");\n\t\t}\n\t\t// generate vector from hub for the search query\n\t\tconst vector = await this.aquilaClientService.getHubServer().compressDocument(collection.aquilaDbName, [options.query]) as number[][];\n\t\tif(vector.length === 0) {\n\t\t\tthrow new InternalServerError(\"Something went wrong\");\n\t\t}\n\n\t\t// search on aquiladb\n\t\tconst { docs, dists } = await this.aquilaClientService.getDbServer().searchKDocuments(collection.aquilaDbName, vector, 100)\n\t\tconst documentObjs: any = {};\n\t\t// const newDists = dists[0].map(dist => (1 - dist))\n\t\tconst newDists = dists[0];\n\t\tdocs[0].forEach((doc: any, index: number) => {\n\t\t\tconst docExists = documentObjs[doc.metadata.bookmark_id];\n\t\t\tif(!docExists) {\n\t\t\t\tdocumentObjs[doc.metadata.bookmark_id] = {\n\t\t\t\t\tbookmarkParaId: doc.metadata.bookmark_para_id,\n\t\t\t\t\tbookmarkId: doc.metadata.bookmark_id,\n\t\t\t\t\tdist:  newDists[index],\n\t\t\t\t\tparas: [{ dist: newDists[index], para: doc.metadata.para}]\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tconst documents = Object.values(documentObjs).sort((a: any, b: any) => (b.dist - a.dist))\n\n\t\t// sort result from aquiladb and select records within limit and offset\n\t\tconst totalRecords = documents.length;\n\t\tconst start = (options.page -1) * options.limit;\n\t\tconst end = ((options.page -1) * options.limit) + options.limit;\n\t\tconst records = documents.slice(start, end);\n\n\t\t// fetch all bookmarks\n\t\tconst bookmarkIds = records.map((item: any) => item.bookmarkId);\n\t\tconst bookmarks = await Bookmark.find({ where: { id: In(bookmarkIds)}});\n\n\t\t// generate result\n\t\tconst bookmarkData = records.map((item: any) => {\n\t\t\tconst bookmark = bookmarks.find(data => data.id === item.bookmarkId) as Bookmark;\n\t\t\treturn ({\n\t\t\t\tid: bookmark.id,\n\t\t\t\tcollectionId: bookmark.collectionId,\n\t\t\t\turl: bookmark.url,\n\t\t\t\ttitle: bookmark.title,\n\t\t\t\tauthor: bookmark.author,\n\t\t\t\tcoverImg: bookmark.coverImg,\n\t\t\t\tsummary: bookmark.summary,\n\t\t\t\tdescription: item.paras[0].para\n\t\t\t});\n\t\t});\n\t\tconst output = {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / options.limit),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\n\t\treturn output;\n\t}\n\n\tpublic async getBookmarksByCollectionId(collectionId: string, options: GetBookmarksByCollectionIdOptionsInputDto, accountStatus: AccountStatus): Promise<GetBookmarksByCollectionIdOutputDto> {\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.getTemporaryBookmarksByCollectionId(collectionId, options);\n\t\t}\n\t\treturn await this.getPermanentBookmarksByCollectionId(collectionId, options);\n\t}\n\n\tpublic async getFeaturedBookmarks(options: GetBookmarksByCollectionIdOptionsInputDto): Promise<GetFeaturedBookmarksOutputDto> {\n\t\tconst skip = (options.page - 1) * options.limit;\n\t\tconst take = options.limit;\n\t\tconst query = Bookmark.createQueryBuilder(\"bookmark\")\n\t\t\t\t\t\t\t.innerJoinAndSelect(Collection, \"collection\", \"collection.id = bookmark.collectionId\")\n\t\t\t\t\t\t\t.where(\"collection.isFeatured = :isFeatured\", { isFeatured: true })\n\t\t\t\t\t\t\t// .orderBy(\"RANDOM()\")\n\t\tconst totalRecords = await query.getCount()\n\t\tconst featuredBookmarks = await query.skip(skip).take(take).getMany()\n\t\t// find all paragraphs for bookmark\n\t\tconst bookmarkIds = featuredBookmarks.map(item => item.id);\n\t\tconst paras = await BookmarkPara.find({ where: { bookmarkId: In(bookmarkIds)}});\n\t\tconst bookmarkData = featuredBookmarks.map(item => ({\n\t\t\tid: item.id,\n\t\t\tcollectionId: item.collectionId,\n\t\t\turl: item.url,\n\t\t\ttitle: item.title,\n\t\t\tauthor: item.author,\n\t\t\tcoverImg: item.coverImg,\n\t\t\tsummary: item.summary,\n\t\t\tdescription: paras.find(para => para.bookmarkId === item.id)?.content || ''\n\t\t}));\n\t\treturn {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / take),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\t\n\t}\n}"
  },
  {
    "path": "aquila/search/src/service/CollectionService.ts",
    "content": "import { NotFoundError } from \"routing-controllers\";\nimport { Service } from \"typedi\";\n\nimport { Collection } from \"../entity/Collection\";\nimport { CollectionTemp } from \"../entity/CollectionTemp\";\nimport { AccountStatus } from \"./dto/AuthServiceDto\";\nimport { GetAllCollectionsInputOptionsDto, GetAllCollectionsOutputDto } from \"./dto/CollectionServiceDto\";\n\n@Service()\nexport class CollectionService {\n\n\tpublic constructor() {}\n\n\tprivate async getAllTemporaryCollections(options: GetAllCollectionsInputOptionsDto): Promise<GetAllCollectionsOutputDto> {\n\t\tconst allowedWhere: ['isShareable', 'isFeatured'] = ['isShareable', 'isFeatured'];\n\n\t\tconst where = allowedWhere.reduce((prev: {[key: string]: string | boolean}, current) =>{\n\t\t\tif(options.where && current in options.where) {\n\t\t\t\tprev[current] = options.where[current] as boolean | string;\n\t\t\t}\n\t\t\treturn prev;\n\t\t}, {})\n\n\t\tconst totalRecords = await CollectionTemp.count({ where });\n\t\tconst skip = (options.page - 1) * options.limit;\n\t\tconst take = options.limit;\n\t\t\n\t\tconst collections = await CollectionTemp.find({ where, order: { createdAt: \"DESC\" }, take, skip});\n\n\t\treturn {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / options.limit),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tcollections\n\t\t};\n\t}\n\n\tpublic async getAllPermanentCollections(options: GetAllCollectionsInputOptionsDto): Promise<GetAllCollectionsOutputDto> {\n\t\tconst allowedWhere: ['isShareable', 'isFeatured'] = ['isShareable', 'isFeatured'];\n\t\tconst where = allowedWhere.reduce((prev: {[key: string]: string | boolean}, current) =>{\n\t\t\tif(options.where && current in options.where) {\n\t\t\t\tprev[current] = options.where[current] as boolean | string;\n\t\t\t}\n\t\t\treturn prev;\n\t\t}, {})\n\n\t\tconst totalRecords = await Collection.count({ where });\n\t\tconst skip = (options.page - 1) * options.limit;\n\t\tconst take = options.limit;\n\n\t\tconst collections = await Collection.find({ where, order: { createdAt: \"DESC\" }, take, skip, relations: { customer: true }});\n\t\t\n\t\treturn {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / options.limit),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tcollections\n\t\t};\n\t}\n\n\tpublic async getAllCollections(options: GetAllCollectionsInputOptionsDto, accountStatus: AccountStatus): Promise<GetAllCollectionsOutputDto> {\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.getAllTemporaryCollections(options);\n\t\t}\n\t\treturn await this.getAllPermanentCollections(options);\n\t}\n\n\tprivate async getTempCustomerCollectionsByCustomerId(customerId: string): Promise<CollectionTemp[]> {\n\t\tconst collections = await CollectionTemp.find({ where: { customerId }});\n\t\treturn collections;\n\t}\n\n\tprivate async getPermanentCustomerCollectionsByCustomerId(customerId: string): Promise<Collection[]> {\n\t\tconst collections = await Collection.find({ where: { customerId }});\n\t\treturn collections;\n\t}\n\n\tpublic async getCustomerCollectionsByCustomerId(customerId: string, accountStatus: AccountStatus): Promise<Collection[]|CollectionTemp[]> {\n\t\tif(accountStatus === AccountStatus.PERMANENT) {\n\t\t\treturn await this.getPermanentCustomerCollectionsByCustomerId(customerId);\n\t\t}\n\t\treturn await this.getTempCustomerCollectionsByCustomerId(customerId);\n\t}\n\t\n\tpublic async getTemporaryCollectionById(id: string): Promise<CollectionTemp> {\n\t\tconst collection = await CollectionTemp.findOne({ where: { id } });\n\t\tif(!collection) {\n\t\t\tthrow new NotFoundError(\"Collection Not found\");\n\t\t}\n\t\treturn collection;\n\t}\n\n\tpublic async getPermanentCollectionById(id: string): Promise<Collection> {\n\t\tconst collection = await Collection.findOne({ where: { id }});\n\t\tif(!collection) {\n\t\t\tthrow new NotFoundError(\"Collection not found\");\n\t\t}\n\t\treturn collection;\n\t}\n\n\tpublic async getCollectionById(id: string, accountStatus: AccountStatus): Promise<Collection|CollectionTemp> {\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.getTemporaryCollectionById(id);\n\t\t}\t\n\t\treturn await this.getPermanentCollectionById(id)\n\t}\n\n\tpublic async getPublicCollectionById(id: string): Promise<Collection> {\n\t\tconst collection = await Collection.findOne({ where: { id, isShareable: true }});\n\t\tif(!collection) {\n\t\t\tthrow new NotFoundError(\"Collection not found\");\n\t\t}\n\t\treturn collection;\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/service/CollectionSubscriptionService.ts",
    "content": "import { InternalServerError, NotFoundError } from \"routing-controllers\";\nimport { Service } from \"typedi\";\nimport { In } from \"typeorm\";\n\nimport dataSource from \"../config/db\";\nimport { Bookmark, BookmarkStatus } from \"../entity/Bookmark\";\nimport { BookmarkPara } from \"../entity/BookmarkPara\";\nimport { Collection } from \"../entity/Collection\";\nimport { CollectionSubscription } from \"../entity/CollectionSubscription\";\nimport { CollectionSubscriptionTemp } from \"../entity/CollectionSubscriptionTemp\";\nimport { AquilaClientService } from \"../lib/AquilaClientService\";\nimport { AccountStatus } from \"./dto/AuthServiceDto\";\nimport { GetSubscriptionsByCustomerIdOptionsInputDto, GetSubscriptionsByCustomerIdOutputDto } from \"./dto/CollectionSubscriptionServiceDto\";\n\n@Service()\nexport class CollectionSubscriptionService {\n\n\tpublic constructor(private aquilaClientService: AquilaClientService) {}\n\n\tprivate async subscribeTemporaryCollection(collectionId: string, customerId: string): Promise<CollectionSubscriptionTemp> {\n\t\tlet subscription = new CollectionSubscriptionTemp();\n\t\tawait dataSource.transaction(async transactionalEntityManager => {\n\t\t\tsubscription.collectionId = collectionId;\n\t\t\tsubscription.subscriberId = customerId;\n\t\t\tawait transactionalEntityManager.save(subscription);\n\t\t})\n\t\treturn subscription;\n\t}\n\t\n\tprivate async subscribePermanentCollection(collectionId: string, customerId: string): Promise<CollectionSubscription> {\n\t\tlet subscription = new CollectionSubscription();\n\t\tawait dataSource.transaction(async transactionalEntityManager => {\n\t\t\tsubscription.collectionId = collectionId;\n\t\t\tsubscription.subscriberId = customerId;\n\t\t\tawait transactionalEntityManager.save(subscription);\n\t\t})\n\t\treturn subscription;\n\t}\n\n\tpublic async subscribeCollection(collectionId: string, customerId: string, accountStatus: AccountStatus): Promise<CollectionSubscription|CollectionSubscriptionTemp> {\n\t\t\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.subscribeTemporaryCollection(collectionId, customerId);\n\t\t}\n\t\treturn await this.subscribePermanentCollection(collectionId, customerId);\n\t}\n\n\tprivate async getTemporaryCollectionSubscriptionList(customerId: string): Promise<CollectionSubscriptionTemp[]> {\n\t\tconst collections = await CollectionSubscriptionTemp.find({ where: { subscriberId: customerId }});\n\t\treturn collections;\n\t}\n\t\n\tprivate async getPermanentCollectionSubscriptionList(customerId: string): Promise<CollectionSubscription[]> {\n\t\tconst collections = await CollectionSubscription.find({ where: { subscriberId: customerId }});\n\t\treturn collections;\n\t}\n\n\tpublic async getCustomerSubscriptions(customerId: string, accountStatus: AccountStatus): Promise<CollectionSubscriptionTemp[] | CollectionSubscription[]> {\n\t\t\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.getTemporaryCollectionSubscriptionList(customerId);\n\t\t}\n\t\treturn await this.getPermanentCollectionSubscriptionList(customerId);\n\t}\n\n\tpublic async isCollectionSubscribedByTemporaryCustomer(collectionId: string, customerId: string): Promise<boolean> {\n\t\t// will return null if query can't find a result\n\t\tconst subscription = await CollectionSubscriptionTemp.findOne({ where: { collectionId, subscriberId: customerId} });\n\n\t\tif(subscription) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\treturn false;\n\t }\n\n\tpublic async isCollectionSubscribedByPermanentCustomer(collectionId: string, customerId: string): Promise<boolean> {\n\t\t// will return null if query can't find a result\n\t\tconst subscription = await CollectionSubscription.findOne({ where: { collectionId, subscriberId: customerId} });\n\t\t\n\t\tif(subscription) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\treturn false;\n\t }\n\t \n\t public async isCollectionSubscribedByCustomer(collectionId: string, customerId: string, accountStatus: AccountStatus): Promise<boolean> {\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.isCollectionSubscribedByTemporaryCustomer(collectionId, customerId);\n\t\t}\n\n\t\treturn await this.isCollectionSubscribedByPermanentCustomer(collectionId, customerId);\n\t }\n\n\tprivate async unSubscribeTemporaryCollection(collectionId: string, customerId: string): Promise<CollectionSubscriptionTemp | null> {\n\t\tconst collection = await CollectionSubscriptionTemp.findOne({ where: { collectionId, subscriberId: customerId }});\n\t\tif(!collection) {\n\t\t\tthrow new NotFoundError(\"Subscription not found\");\n\t\t}\n\t\tawait collection.remove();\n\t\treturn collection;\n\t}\n\t\n\tprivate async unSubscribePermanentCollection(collectionId: string, customerId: string): Promise<CollectionSubscription | null> {\n\t\tconst collection = await CollectionSubscription.findOne({ where: { collectionId, subscriberId: customerId }});\n\t\tif(!collection) {\n\t\t\tthrow new NotFoundError(\"Subscription not found\");\n\t\t}\n\t\tawait collection.remove()\n\t\treturn collection;\n\t}\n\n\tpublic async unSubscribeCollection(collectionId: string, customerId: string, accountStatus: AccountStatus): Promise<CollectionSubscription | CollectionSubscriptionTemp | null> {\n\t\t\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.unSubscribeTemporaryCollection(collectionId, customerId);\n\t\t}\n\t\treturn await this.unSubscribePermanentCollection(collectionId, customerId);\n\t}\n\n\tprivate async getTemporaryCollectionFollowerCount(collectionId: string): Promise<number> {\n\t\tconst count = await CollectionSubscriptionTemp.count({ where: { collectionId }});\n\t\treturn count;\n\t}\n\t\n\tprivate async getPermanentCollectionFollowerCount(collectionId: string): Promise<number> {\n\t\tconst count = await CollectionSubscription.count({ where: { collectionId }});\n\t\treturn count;\n\t}\n\n\tpublic async getCollectionSubscriberCount(collectionId: string, accountStatus: AccountStatus): Promise<number> {\n\t\t\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn await this.getTemporaryCollectionFollowerCount(collectionId);\n\t\t}\n\t\treturn await this.getPermanentCollectionFollowerCount(collectionId);\n\t}\n\n\tpublic async getTotalCollectionSubscribedByTemporaryCustomer(subscriberId: string): Promise<number> {\n\t\tconst count = await CollectionSubscriptionTemp.count({ where: { subscriberId }});\n\t\treturn count;\n\t}\n\n\tpublic async getTotalCollectionSubscribedByPermanentCustomer(subscriberId: string): Promise<number> {\n\t\tconst count = await CollectionSubscription.count({ where: { subscriberId }});\n\t\treturn count;\n\t} \n\n\tpublic async getTotalCollectionSubscribedByCustomer(customerId: string, accountStatus: AccountStatus): Promise<number> {\n\t\tif(accountStatus === AccountStatus.TEMPORARY) {\n\t\t\treturn this.getTotalCollectionSubscribedByTemporaryCustomer(customerId);\n\t\t}\n\t\treturn this.getTotalCollectionSubscribedByPermanentCustomer(customerId);\n\t}\n\n\n\tprivate async getAllSubscriptionsByCustomerId(collectionIds: string[], options: GetSubscriptionsByCustomerIdOptionsInputDto): Promise<GetSubscriptionsByCustomerIdOutputDto> {\n\t\tconst skip = (options.page - 1) * options.limit;\n\t\tconst take = options.limit;\n\t\tconst totalRecords = await Bookmark.count({ where: { collectionId: In(collectionIds), status: BookmarkStatus.PROCESSED }});\n\t\tconst bookmarks = await Bookmark.find({ where: { collectionId: In(collectionIds), status: BookmarkStatus.PROCESSED}, skip, take });\n\t\t// find all paragraphs for bookmark\n\t\tconst bookmarkIds = bookmarks.map(item => item.id);\n\t\tconst paras = await BookmarkPara.find({ where: { bookmarkId: In(bookmarkIds)}});\n\t\tconst bookmarkData = bookmarks.map(item => ({\n\t\t\tid: item.id,\n\t\t\tcollectionId: item.collectionId,\n\t\t\turl: item.url,\n\t\t\ttitle: item.title,\n\t\t\tauthor: item.author,\n\t\t\tcoverImg: item.coverImg,\n\t\t\tsummary: item.summary,\n\t\t\tdescription: paras.find(para => para.bookmarkId === item.id)?.content || '',\n\t\t\tcreatedAt: item.createdAt\n\t\t}));\n\t\treturn {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / take),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\t\n\t}\n\n\tpublic async getSubscriptionsByTemporaryCustomerId(customerId: string, options: GetSubscriptionsByCustomerIdOptionsInputDto): Promise<GetSubscriptionsByCustomerIdOutputDto> {\n\t\tconst collectionSubscriptions = await CollectionSubscriptionTemp.find({ where: { subscriberId: customerId }});\n\t\tconst collectionIds = collectionSubscriptions.map(collection => collection.collectionId);\n\t\tif(!options.query) {\n\t\t\treturn this.getAllSubscriptionsByCustomerId(collectionIds, options);\n\t\t}\n\t\tconst collections = await Collection.find({ where : { id: In(collectionIds)}});\n\n\t\tconst documentObjs: any = {};\n\t\tfor(let i = 0; i < collections.length; i++) {\n\t\t\tconst collection = collections[i];\n\t\t\t// generate vector from hub for the search query\n\t\t\tconst vector = await this.aquilaClientService.getHubServer().compressDocument(collection.aquilaDbName, [options.query]) as number[][];\n\t\t\tif(vector.length === 0) {\n\t\t\t\tthrow new InternalServerError(\"Something went wrong\");\n\t\t\t}\n\n\t\t\t// search on aquiladb\n\t\t\tconst { docs, dists } = await this.aquilaClientService.getDbServer().searchKDocuments(collection.aquilaDbName, vector, 10)\n\t\t\tconst newDists = dists[0];\n\t\t\tdocs[0].forEach((doc: any, index: number) => {\n\t\t\t\tconst docExists = documentObjs[doc.metadata.bookmark_id];\n\t\t\t\tif(!docExists) {\n\t\t\t\t\tdocumentObjs[doc.metadata.bookmark_id] = {\n\t\t\t\t\t\tbookmarkParaId: doc.metadata.bookmark_para_id,\n\t\t\t\t\t\tbookmarkId: doc.metadata.bookmark_id,\n\t\t\t\t\t\tdist:  newDists[index],\n\t\t\t\t\t\tparas: [{ dist: newDists[index], para: doc.metadata.para}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tconst documents = Object.values(documentObjs).sort((a: any, b: any) => (b.dist - a.dist))\n\t\t// sort result from aquiladb and select records within limit and offset\n\t\tconst totalRecords = documents.length;\n\t\tconst start = (options.page -1) * options.limit;\n\t\tconst end = ((options.page -1) * options.limit) + options.limit;\n\t\tconst records = documents.slice(start, end);\n\n\t\t// fetch all bookmarks\n\t\tconst bookmarkIds = records.map((item: any) => item.bookmarkId);\n\t\tconst bookmarks = await Bookmark.find({ where: { id: In(bookmarkIds)}});\n\n\t\t// generate result\n\t\tconst bookmarkData = records.map((item: any) => {\n\t\t\tconst bookmark = bookmarks.find(data => data.id === item.bookmarkId) as Bookmark;\n\t\t\treturn ({\n\t\t\t\tid: bookmark.id,\n\t\t\t\tcollectionId: bookmark.collectionId,\n\t\t\t\turl: bookmark.url,\n\t\t\t\ttitle: bookmark.title,\n\t\t\t\tauthor: bookmark.author,\n\t\t\t\tcoverImg: bookmark.coverImg,\n\t\t\t\tsummary: bookmark.summary,\n\t\t\t\tdescription: item.paras[0].para\n\t\t\t});\n\t\t});\n\t\tconst output = {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / options.limit),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\n\t\treturn output;\n\t}\n\n\tpublic async getSubscriptionsByPermanentCustomerId(customerId: string, options: GetSubscriptionsByCustomerIdOptionsInputDto): Promise<GetSubscriptionsByCustomerIdOutputDto> {\n\t\tconst collectionSubscriptions = await CollectionSubscription.find({ where: { subscriberId: customerId }});\n\t\tconst collectionIds = collectionSubscriptions.map(collection => collection.collectionId);\n\t\tif(!options.query) {\n\t\t\treturn this.getAllSubscriptionsByCustomerId(collectionIds, options);\n\t\t}\n\t\tconst collections = await Collection.find({ where : { id: In(collectionIds)}});\n\n\t\tconst documentObjs: any = {};\n\t\tfor(let i = 0; i < collections.length; i++) {\n\t\t\tconst collection = collections[i];\n\t\t\t// generate vector from hub for the search query\n\t\t\tconst vector = await this.aquilaClientService.getHubServer().compressDocument(collection.aquilaDbName, [options.query]) as number[][];\n\t\t\tif(vector.length === 0) {\n\t\t\t\tthrow new InternalServerError(\"Something went wrong\");\n\t\t\t}\n\n\t\t\t// search on aquiladb\n\t\t\tconst { docs, dists } = await this.aquilaClientService.getDbServer().searchKDocuments(collection.aquilaDbName, vector, 10)\n\t\t\tconst newDists = dists[0];\n\t\t\tdocs[0].forEach((doc: any, index: number) => {\n\t\t\t\tconst docExists = documentObjs[doc.metadata.bookmark_id];\n\t\t\t\tif(!docExists) {\n\t\t\t\t\tdocumentObjs[doc.metadata.bookmark_id] = {\n\t\t\t\t\t\tbookmarkParaId: doc.metadata.bookmark_para_id,\n\t\t\t\t\t\tbookmarkId: doc.metadata.bookmark_id,\n\t\t\t\t\t\tdist:  newDists[index],\n\t\t\t\t\t\tparas: [{ dist: newDists[index], para: doc.metadata.para}]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tconst documents = Object.values(documentObjs).sort((a: any, b: any) => (b.dist - a.dist))\n\t\t// sort result from aquiladb and select records within limit and offset\n\t\tconst totalRecords = documents.length;\n\t\tconst start = (options.page -1) * options.limit;\n\t\tconst end = ((options.page -1) * options.limit) + options.limit;\n\t\tconst records = documents.slice(start, end);\n\n\t\t// fetch all bookmarks\n\t\tconst bookmarkIds = records.map((item: any) => item.bookmarkId);\n\t\tconst bookmarks = await Bookmark.find({ where: { id: In(bookmarkIds)}});\n\n\t\t// generate result\n\t\tconst bookmarkData = records.map((item: any) => {\n\t\t\tconst bookmark = bookmarks.find(data => data.id === item.bookmarkId) as Bookmark;\n\t\t\treturn ({\n\t\t\t\tid: bookmark.id,\n\t\t\t\tcollectionId: bookmark.collectionId,\n\t\t\t\turl: bookmark.url,\n\t\t\t\ttitle: bookmark.title,\n\t\t\t\tauthor: bookmark.author,\n\t\t\t\tcoverImg: bookmark.coverImg,\n\t\t\t\tsummary: bookmark.summary,\n\t\t\t\tdescription: item.paras[0].para\n\t\t\t});\n\t\t});\n\t\tconst output = {\n\t\t\ttotalRecords,\n\t\t\ttotalPages: Math.ceil(totalRecords / options.limit),\n\t\t\tcurrentPage: options.page,\n\t\t\tlimit: options.limit,\n\t\t\tbookmarks: bookmarkData\n\t\t}\n\t\treturn output;\n\t}\n\n\tpublic async getSubscriptionsByCustomerId(customerId: string, options: GetSubscriptionsByCustomerIdOptionsInputDto, accountStatus: AccountStatus): Promise<GetSubscriptionsByCustomerIdOutputDto> {\n\t\tif(accountStatus == AccountStatus.TEMPORARY) {\n\t\t\treturn this.getSubscriptionsByTemporaryCustomerId(customerId, options);\n\t\t}\n\t\treturn this.getSubscriptionsByPermanentCustomerId(customerId, options);\n\t}\n\n\tpublic async getCustomerSubscribedCollections(customerId: string, accountStatus: AccountStatus): Promise<Collection[]> {\n\t\tlet collectionSubscriptions: CollectionSubscription[] | CollectionSubscriptionTemp[];\n\t\tif(accountStatus === AccountStatus.TEMPORARY){\n\t\t\tcollectionSubscriptions = await CollectionSubscriptionTemp.find({ where: { subscriberId: customerId}});\n\t\t}else {\n\t\t\tcollectionSubscriptions = await CollectionSubscription.find({ where: { subscriberId: customerId}});\n\t\t}\n\t\tconst collectionIds = collectionSubscriptions.map(item => item.collectionId);\n\t\tconst collections = await Collection.find({ where: { id: In(collectionIds)}, relations: {customer: true} });\n\t\treturn collections;\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/service/CustomerService.ts",
    "content": "import { Service } from \"typedi\";\nimport randomAnimalName from '../utils/randomAnimals';\nimport crypto from 'crypto';\nimport { v4 as uuidv4, parse as parseUuid } from 'uuid';\nimport base58 from 'bs58';\n\nimport dataSource from '../config/db';\nimport { CustomerTemp } from \"../entity/CustomerTemp\";\nimport { CollectionTemp } from \"../entity/CollectionTemp\";\nimport { ActivateCustomerByIdInputDataDto, CreateCustomerInputDataDto, CreateCustomerOutputDto, GetCustomerPublicInfoByIdOutputDto, GetRandomCustomerNameOutputDto, UpdateCustomerByIdInputDataDto } from \"./dto/CustomerServiceDto\";\nimport { AquilaClientService } from \"../lib/AquilaClientService\";\nimport { Customer } from \"../entity/Customer\";\nimport { NotFoundError } from \"routing-controllers\";\nimport { AccountStatus } from \"./dto/AuthServiceDto\";\nimport { BookmarkTemp } from \"../entity/BookmarkTemp\";\nimport { In } from \"typeorm\";\nimport { BookmarkPara } from \"../entity/BookmarkPara\";\nimport { BookmarkParaTemp } from \"../entity/BookmarkParaTemp\";\nimport { Collection } from \"../entity/Collection\";\nimport { Bookmark, BookmarkStatus } from \"../entity/Bookmark\";\nimport { CollectionSubscriptionTemp } from \"../entity/CollectionSubscriptionTemp\";\nimport { CollectionSubscription } from \"../entity/CollectionSubscription\";\n\n@Service()\nexport class CustomerService {\n\n\tpublic constructor(private aquilaClientService: AquilaClientService) {}\n\n\tpublic async getRandomCustomerName(): Promise<GetRandomCustomerNameOutputDto> {\n\t\tconst [firstName, lastName] = randomAnimalName();\n\n\t\treturn {\n\t\t\tfirstName, \n\t\t\tlastName\n\t\t};\n\t}\n\n\tpublic async getCustomerById(id: string, accountStatus: AccountStatus) {\n\t\tif(accountStatus === AccountStatus.PERMANENT) {\n\t\t\treturn await this.getPermanentCustomerById(id);\n\t\t}\t\n\t\treturn await this.getTemporaryCustomerById(id);\n\t}\n\n\tprivate async getPermanentCustomerById(id: string): Promise<Customer> {\n\t\tlet customer: Customer | null = await Customer.findOne({ where: { id: id }});\n\t\tif(!customer) {\n\t\t\tthrow new NotFoundError(\"Customer not found\");\n\t\t}\n\t\treturn customer;\n\t}\n\n\tprivate async getTemporaryCustomerById(id: string): Promise<CustomerTemp> {\n\t\tlet customer: CustomerTemp | null = await CustomerTemp.findOne({ where: { id: id }});\n\t\tif(!customer) {\n\t\t\tthrow new NotFoundError(\"Customer not found\");\n\t\t}\n\t\treturn customer;\n\t}\n\n\tpublic async createCustomer(data: CreateCustomerInputDataDto): Promise<CreateCustomerOutputDto> {\n\n\t\tconst customer = new CustomerTemp();\n\t\tconst collection = new CollectionTemp();\n\n\t\tawait dataSource.transaction(async transactionalEntityManager => {\n\t\t\t// create an new record in customer\n\t\t\tconst {firstName, lastName} = data;\n\n\t\t\tconst randomNumber = Math.random().toString();\n\t\t\tconst hash = crypto.createHash('sha256');\n\t\t\tconst avatar = hash.update(randomNumber).digest('hex');\n\n\t\t\tconst uuidV4ParsedId = new Uint8Array(parseUuid(uuidv4()));\n\t\t\tconst base58String = base58.encode(uuidV4ParsedId).slice(0, 8);\n\t\t\tconst timestampString = Date.now().toString().slice(0, -3);\n\t\t\tconst secretKey = base58String+timestampString;\n\n\t\t\tconst desc = 'Hi I’m using Aquila Network to help curate the web. I’ll be sharing some awesome websites with you. Don’t forget to follow me and support my work.';\n\n\t\t\tcustomer.firstName = firstName;\n\t\t\tcustomer.lastName = lastName;\n\t\t\tcustomer.avatar = avatar;\n\t\t\tcustomer.secretKey = secretKey;\n\t\t\tcustomer.desc = desc;\n\t\t\tawait transactionalEntityManager.save(customer);\n\n\t\t\t// create a aquilaDb\n\t\t\tconst aquilaDbName = await this.aquilaClientService.createCollection(desc, secretKey);\n\n\t\t\t// create an new record in collection\n\t\t\tconst collectionName = 'My Collection #1';\n\t\t\tconst collectionDesc = 'Hi I’m using Aquila Network to help curate the web. I’ll be sharing some awesome websites with you. Don’t forget to follow me and support my work.';\n\t\t\tconst customerId = customer.id;\n\n\t\t\tcollection.name = collectionName;\n\t\t\tcollection.desc = collectionDesc;\n\t\t\tcollection.customerId = customerId;\n\t\t\tcollection.aquilaDbName = aquilaDbName;\n\t\t\tawait transactionalEntityManager.save(collection);\n\t\t})\n\n\t\treturn {\n\t\t\tcustomer,\n\t\t\tcollection\n\t\t}\n\t}\n\n\tpublic async updateCustomerById(id: string, data: UpdateCustomerByIdInputDataDto) {\n\t\tconst customer = await this.getPermanentCustomerById(id);\n\t\tcustomer.firstName = data.firstName;\n\t\tcustomer.lastName = data.lastName;\n\t\tcustomer.desc = data.desc;\n\t\tcustomer.email = data.email;\n\t\tcustomer.lightningAddress = data.lightningAddress || null;\n\t\tcustomer.save();\n\t\treturn customer;\n\t}\n\n\tpublic async getCustomerPublicInfoById(id: string): Promise<GetCustomerPublicInfoByIdOutputDto> {\n\t\tconst customer = await this.getPermanentCustomerById(id);\n\t\treturn {\n\t\t\tid: id,\n\t\t\tfirstName: customer.firstName,\n\t\t\tlastName: customer.lastName,\n\t\t\tdesc: customer.desc,\n\t\t\tcustomerId: customer.customerId\n\t\t};\n\t}\n\n\tpublic async activateCustomerById(id: string, data: ActivateCustomerByIdInputDataDto): Promise<Customer> {\n\t\t// get temporary custoemr\n\t\tconst customerTemp = await this.getTemporaryCustomerById(id);\n\n\t\t// get all collections to permanent account\n\t\tconst collectionsTemp = await CollectionTemp.find({ where: { customerId: id }});\n\t\tconst collectionTempIds = collectionsTemp.map(item =>  item.id);\n\n\t\t// get all bookmarks to permanent account\n\t\tconst bookmarksTemp = await BookmarkTemp.find({ where: { collectionId: In(collectionTempIds) }})\n\t\tconst bookmarkTempIds = await bookmarksTemp.map(item => item.id);\n\n\t\t// get all bookmark paras to permanent account\n\t\tconst bookmarkParasTemp = await BookmarkParaTemp.find({ where: { bookmarkId: In(bookmarkTempIds)}})\n\n\t\t// get all collection subscriptions to permanent account\n\t\tconst collectionSubTemp = await CollectionSubscriptionTemp.find({ where: { subscriberId: id}})\n\n\t\t// create customer\n\t\tconst customer = new Customer();\n\t\tcustomer.id = customerTemp.id;\n\t\tcustomer.avatar = customerTemp.avatar;\n\t\tcustomer.firstName = data.firstName;\n\t\tcustomer.lastName = data.lastName;\n\t\tcustomer.email = data.email;\n\t\tcustomer.desc = data.desc;\n\t\tcustomer.secretKey = customerTemp.secretKey;\n\t\tcustomer.createdAt = customerTemp.createdAt;\n\t\tcustomer.lightningAddress = data.lightningAddress || null;\n\n\t\t// create collections\n\t\tconst collections = collectionsTemp.map(item => {\n\t\t\tconst collection = new Collection();\n\t\t\tcollection.id = item.id;\n\t\t\tcollection.desc = item.desc;\n\t\t\tcollection.aquilaDbName = item.aquilaDbName;\n\t\t\tcollection.customerId = item.customerId;\n\t\t\tcollection.name = item.name;\n\t\t\tcollection.isShareable = item.isShareable;\n\t\t\tcollection.indexedDocsCount = item.indexedDocsCount;\n\t\t\tcollection.createdAt = item.createdAt;\n\t\t\treturn collection;\n\t\t});\n\n\t\t// create bookmarks\n\t\tconst bookmarks = bookmarksTemp.map(item => {\n\t\t\tconst bookmark = new Bookmark();\n\t\t\tbookmark.id = item.id;\n\t\t\tbookmark.title = item.title;\n\t\t\tbookmark.collectionId = item.collectionId;\n\t\t\tbookmark.coverImg = item.coverImg;\n\t\t\tbookmark.author = item.author;\n\t\t\tbookmark.html = item.html;\n\t\t\tbookmark.url = item.url;\n\t\t\tbookmark.summary = item.summary;\n\t\t\tbookmark.links = item.links;\n\t\t\tbookmark.isHidden = item.isHidden;\n\t\t\tbookmark.status = item.status as unknown as BookmarkStatus;\n\t\t\tbookmark.createdAt = item.createdAt;\n\t\t\treturn bookmark;\n\t\t});\n\n\t\t// create bookmark paras\n\t\tconst bookmarkParas = bookmarkParasTemp.map(item => {\n\t\t\tconst bookmarkPara = new BookmarkPara();\n\t\t\tbookmarkPara.id = item.id;\n\t\t\tbookmarkPara.content = item.content;\n\t\t\tbookmarkPara.bookmarkId = item.bookmarkId;\n\t\t\tbookmarkPara.createdAt = item.createdAt;\n\t\t\treturn bookmarkPara;\n\t\t});\n\n\t\t// create collection subscriptions\n\t\tconst collectionSubs = collectionSubTemp.map(item => {\n\t\t\tconst collectionSub = new CollectionSubscription();\n\t\t\tcollectionSub.id = item.id;\n\t\t\tcollectionSub.subscriberId = item.subscriberId;\n\t\t\tcollectionSub.collectionId = item.collectionId;\n\t\t\tcollectionSub.subscribedAt = item.subscribedAt;\n\t\t\tcollectionSub.createdAt = item.createdAt;\n\t\t\treturn collectionSub;\n\t\t});\n\n\t\tawait dataSource.transaction(async transactionalEntityManager => {\n\t\t\ttransactionalEntityManager.save(customer);\n\t\t\ttransactionalEntityManager.save(collections);\n\t\t\ttransactionalEntityManager.save(bookmarks);\n\t\t\ttransactionalEntityManager.save(bookmarkParas);\n\t\t\ttransactionalEntityManager.save(collectionSubs);\n\t\t\ttransactionalEntityManager.remove(customerTemp);\n\t\t\ttransactionalEntityManager.remove(collectionsTemp);\n\t\t\ttransactionalEntityManager.remove(bookmarksTemp);\n\t\t\ttransactionalEntityManager.remove(bookmarkParasTemp);\n\t\t\ttransactionalEntityManager.remove(collectionSubTemp);\n\t\t});\n\t\treturn customer;\n\t}\n\n\tpublic async findCustomerByEmailId(email: string) {\n\t\tconst customer = await Customer.findOne({where: { email }});\n\t\treturn customer;\n\t}\n\n}"
  },
  {
    "path": "aquila/search/src/service/dto/AuthServiceDto.ts",
    "content": "export enum AccountStatus {\n\tTEMPORARY= 'TEMPORARY',\n\tPERMANENT = 'PERMANENT'\n}\n\nexport interface JwtPayload {\n\tcustomerId: string,\n\taccountStatus: AccountStatus\n}"
  },
  {
    "path": "aquila/search/src/service/dto/BookmarkServiceDto.ts",
    "content": "import { Bookmark } from \"../../entity/Bookmark\";\nimport { BookmarkTemp } from \"../../entity/BookmarkTemp\";\n\nexport interface AddBookmarkInputDto {\n\thtml?: string;\n\turl: string;\n\tcollectionId: string;\n}\n\nexport interface GetBookmarksByCollectionIdOptionsInputDto {\n\tlimit: number;\n\tpage: number;\n\tquery?: string;\n}\n\nexport type GetAllBookmarksByCollectionIdOptionsInputDto = Omit<GetBookmarksByCollectionIdOptionsInputDto, 'query'>;\n\nexport interface GetFeaturedBookmarksOptionsInputDto {\n\tlimit: number;\n\tpage: number;\n}\n\nexport interface BookmarkData {\n\tid: string;\n\tcollectionId: string;\n\turl: string;\n\ttitle: string;\n\tauthor: string;\n\tcoverImg: string;\n\tsummary: string\n\tdescription: string;\n}\n\nexport interface GetBookmarksByCollectionIdOutputDto {\n\ttotalPages: number;\n\ttotalRecords: number;\n\tcurrentPage: number;\t\n\tlimit: number;\n\tbookmarks: BookmarkData[] \n}\n\nexport interface GetFeaturedBookmarksOutputDto {\n\ttotalPages: number;\n\ttotalRecords: number;\n\tcurrentPage: number;\t\n\tlimit: number;\n\tbookmarks: BookmarkData[] \n}"
  },
  {
    "path": "aquila/search/src/service/dto/CollectionServiceDto.ts",
    "content": "import { Collection } from \"../../entity/Collection\";\nimport { CollectionTemp } from \"../../entity/CollectionTemp\";\n\nexport interface GetAllCollectionsInputOptionsDto {\n\tlimit: number;\n\tpage: number;\n\twhere?: {\n\t\tisShareable?: boolean;\n\t\tisFeatured?: boolean;\n\t}\n}\n\nexport interface GetAllCollectionsOutputDto {\n\ttotalRecords: number;\n\ttotalPages: number,\n\tcurrentPage: number,\n\tlimit: number,\n\tcollections: CollectionTemp[] | Collection[]\n}"
  },
  {
    "path": "aquila/search/src/service/dto/CollectionSubscriptionServiceDto.ts",
    "content": "export interface GetSubscriptionsByCustomerIdOptionsInputDto {\n\tlimit: number;\n\tpage: number;\n\tquery?: string;\n}\n\nexport interface BookmarkData {\n\tid: string;\n\tcollectionId: string;\n\turl: string;\n\ttitle: string;\n\tauthor: string;\n\tcoverImg: string;\n\tsummary: string\n\tdescription: string;\n}\n\nexport interface GetSubscriptionsByCustomerIdOutputDto {\n\ttotalPages: number;\n\ttotalRecords: number;\n\tcurrentPage: number;\t\n\tlimit: number;\n\tbookmarks: BookmarkData[] \n}"
  },
  {
    "path": "aquila/search/src/service/dto/CustomerServiceDto.ts",
    "content": "import { CollectionTemp } from \"../../entity/CollectionTemp\";\nimport { CustomerTemp } from \"../../entity/CustomerTemp\";\n\nexport interface CreateCustomerInputDataDto {\n\tfirstName: string;\n\tlastName: string;\n}\n\nexport interface CreateCustomerOutputDto {\n\tcustomer: CustomerTemp;\n\tcollection: CollectionTemp;\n}\n\nexport interface ActivateCustomerByIdInputDataDto {\n\tfirstName: string;\n\tlastName: string;\n\temail: string;\n\tdesc: string;\n\tlightningAddress: string;\n}\n\nexport interface UpdateCustomerByIdInputDataDto {\n\tfirstName: string;\n\tlastName: string;\n\temail: string;\n\tdesc: string;\n\tlightningAddress: string;\n}\n\nexport interface GetCustomerPublicInfoByIdOutputDto {\n\tid: string;\n\tfirstName: string;\n\tlastName: string;\n\tdesc: string;\n\tcustomerId: number;\n}\n\nexport interface GetRandomCustomerNameOutputDto {\n\tfirstName: string;\n\tlastName: string;\n}"
  },
  {
    "path": "aquila/search/src/utils/errors/ValidationError.ts",
    "content": "import { HttpError } from \"routing-controllers\";\n\nexport class ValidationError extends HttpError {\n\tconstructor(message: string, public errors: any ) {\n    super(400, message);\n\t\tthis.name = \"ValidationError\";\n\t\tObject.setPrototypeOf(this, ValidationError.prototype);\n  }\n}"
  },
  {
    "path": "aquila/search/src/utils/randomAnimals.ts",
    "content": "const adjectives = [\"furry\",\"ferocious\",\"dangerous\",\"tame\",\"agile\",\"clever\",\"aggressive\",\"tiny\",\"domestic\",\"wild\",\"herbivorous\",\"carnivorous\",\"Adorable\",\"Aggressive\",\"Agile\",\"Beautiful\",\"Bossy\",\"Candid\",\"Carnivorous\",\"Clever\",\"Cold\",\"Colorful\",\"Cuddly\",\"Curious\",\"Cute\",\"Dangerous\",\"Deadly\",\"Domestic\",\"Dominant\",\"Energetic\",\"Fast\",\"Feisty\",\"Ferocious\",\"Fierce\",\"Fluffy\",\"Friendly\",\"Furry\",\"Fuzzy\",\"Grumpy\",\"Hairy\",\"Heavy\",\"Herbivorous\",\"Large\",\"Lovable\",\"Loving\",\"Maternal\",\"Messy\",\"Noisy\",\"Nosy\",\"Picky\",\"Playful\",\"Quick\",\"Rough\",\"Sassy\",\"Scaly\",\"Short\",\"Shy\",\"Slimy\",\"Slow\",\"Small\",\"Smart\",\"Soft\",\"Spikey\",\"Stinky\",\"Strong\",\"Stubborn\",\"Submissive\",\"Tall\",\"Tame\",\"Tenacious\",\"Territorial\",\"Tiny\",\"Vicious\",\"Warm\",\"Wild\"];\nconst animals = [\"alligator\", \"anteater\", \"armadillo\", \"auroch\", \"axolotl\", \"badger\", \"bat\", \"bear\", \"beaver\", \"blobfish\", \"buffalo\", \"camel\", \"chameleon\", \"cheetah\", \"chipmunk\", \"chinchilla\", \"chupacabra\", \"cormorant\", \"coyote\", \"crow\", \"dingo\", \"dinosaur\", \"dog\", \"dolphin\", \"dragon\", \"duck\", \"dumbo octopus\", \"elephant\", \"ferret\", \"fox\", \"frog\", \"giraffe\", \"goose\", \"gopher\", \"grizzly\", \"hamster\", \"hedgehog\", \"hippo\", \"hyena\", \"jackal\", \"jackalope\", \"ibex\", \"ifrit\", \"iguana\", \"kangaroo\", \"kiwi\", \"koala\", \"kraken\", \"lemur\", \"leopard\", \"liger\", \"lion\", \"llama\", \"manatee\", \"mink\", \"monkey\", \"moose\", \"narwhal\", \"nyan cat\", \"orangutan\", \"otter\", \"panda\", \"penguin\", \"platypus\", \"python\", \"pumpkin\", \"quagga\", \"quokka\", \"rabbit\", \"raccoon\", \"rhino\", \"sheep\", \"shrew\", \"skunk\", \"slow loris\", \"squirrel\", \"tiger\", \"turtle\", \"unicorn\", \"walrus\", \"wolf\", \"wolverine\", \"wombat\", \"Aardvark\",\"Albatross\",\"Alligator\",\"Alpaca\",\"Ant\",\"Anteater\",\"Antelope\",\"Ape\",\"Armadillo\",\"Badger\",\"Barracuda\",\"Bat\",\"Bear\",\"Beaver\",\"Bee\",\"Bison\",\"Boar\",\"Buffalo\",\"Butterfly\",\"Camel\",\"Capybara\",\"Caribou\",\"Cassowary\",\"Cat\",\"Caterpillar\",\"Cattle\",\"Chamois\",\"Cheetah\",\"Chicken\",\"Chimpanzee\",\"Chinchilla\",\"Chough\",\"Clam\",\"Cobra\",\"Cockroach\",\"Cod\",\"Cormorant\",\"Coyote\",\"Crab\",\"Crane\",\"Crocodile\",\"Crow\",\"Curlew\",\"Deer\",\"Dinosaur\",\"Dog\",\"Dogfish\",\"Dolphin\",\"Dotterel\",\"Dove\",\"Dragonfly\",\"Duck\",\"Dugong\",\"Dunlin\",\"Eagle\",\"Echidna\",\"Eel\",\"Eland\",\"Elephant\",\"Elk\",\"Emu\",\"Falcon\",\"Ferret\",\"Finch\",\"Fish\",\"Flamingo\",\"Fly\",\"Fox\",\"Frog\",\"Gaur\",\"Gazelle\",\"Gerbil\",\"Giraffe\",\"Gnat\",\"Gnu\",\"Goat\",\"Goldfinch\",\"Goldfish\",\"Goose\",\"Gorilla\",\"Goshawk\",\"Grasshopper\",\"Grouse\",\"Guanaco\",\"Gull\",\"Hamster\",\"Hare\",\"Hawk\",\"Hedgehog\",\"Heron\",\"Herring\",\"Hippopotamus\",\"Hornet\",\"Horse\",\"Human\",\"Hummingbird\",\"Hyena\",\"Ibex\",\"Ibis\",\"Jackal\",\"Jaguar\",\"Jay\",\"Jellyfish\",\"Kangaroo\",\"Kingfisher\",\"Koala\",\"Kookabura\",\"Kouprey\",\"Kudu\",\"Lapwing\",\"Lark\",\"Lemur\",\"Leopard\",\"Lion\",\"Llama\",\"Lobster\",\"Locust\",\"Loris\",\"Louse\",\"Lyrebird\",\"Magpie\",\"Mallard\",\"Manatee\",\"Mandrill\",\"Mantis\",\"Marten\",\"Meerkat\",\"Mink\",\"Mole\",\"Mongoose\",\"Monkey\",\"Moose\",\"Mosquito\",\"Mouse\",\"Mule\",\"Narwhal\",\"Newt\",\"Nightingale\",\"Octopus\",\"Okapi\",\"Opossum\",\"Oryx\",\"Ostrich\",\"Otter\",\"Owl\",\"Oyster\",\"Panther\",\"Parrot\",\"Partridge\",\"Peafowl\",\"Pelican\",\"Penguin\",\"Pheasant\",\"Pig\",\"Pigeon\",\"Pony\",\"Porcupine\",\"Porpoise\",\"Quail\",\"Quelea\",\"Quetzal\",\"Rabbit\",\"Raccoon\",\"Rail\",\"Ram\",\"Rat\",\"Raven\",\"Red deer\",\"Red panda\",\"Reindeer\",\"Rhinoceros\",\"Rook\",\"Salamander\",\"Salmon\",\"Sand Dollar\",\"Sandpiper\",\"Sardine\",\"Scorpion\",\"Seahorse\",\"Seal\",\"Shark\",\"Sheep\",\"Shrew\",\"Skunk\",\"Snail\",\"Snake\",\"Sparrow\",\"Spider\",\"Spoonbill\",\"Squid\",\"Squirrel\",\"Starling\",\"Stingray\",\"Stinkbug\",\"Stork\",\"Swallow\",\"Swan\",\"Tapir\",\"Tarsier\",\"Termite\",\"Tiger\",\"Toad\",\"Trout\",\"Turkey\",\"Turtle\",\"Viper\",\"Vulture\",\"Wallaby\",\"Walrus\",\"Wasp\",\"Weasel\",\"Whale\",\"Wildcat\",\"Wolf\",\"Wolverine\",\"Wombat\",\"Woodcock\",\"Woodpecker\",\"Worm\",\"Wren\",\"Yak\",\"Zebra\"];\n\nexport default function randomAnimal(): [string, string] {\n\treturn [adjectives[Math.floor(Math.random()*adjectives.length)], animals[Math.floor(Math.random()*animals.length)]];\n}"
  },
  {
    "path": "aquila/search/src/utils/validate.ts",
    "content": "import { Request } from \"express\";\nimport { ValidationChain, validationResult } from \"express-validator\";\nimport { ValidationError } from \"./errors/ValidationError\";\n\nexport const validate = async (validations: ValidationChain[], req: Request) => {\n\tawait Promise.all(validations.map(validation => validation.run(req)));\n\n\tconst errors = validationResult(req);\n\tif (errors.isEmpty()) {\n\t\treturn;\n\t}\n\t// res.status(400).json({ errors: errors.array() });\n\tthrow new ValidationError(\"Invalid data\", errors.array())\n} "
  },
  {
    "path": "aquila/search/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig.json to read more about this file */\n\n    /* Projects */\n    // \"incremental\": true,                              /* Enable incremental compilation */\n    // \"composite\": true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */\n    // \"tsBuildInfoFile\": \"./\",                          /* Specify the folder for .tsbuildinfo incremental compilation files. */\n    // \"disableSourceOfProjectReferenceRedirect\": true,  /* Disable preferring source files instead of declaration files when referencing composite projects */\n    // \"disableSolutionSearching\": true,                 /* Opt a project out of multi-project reference checking when editing. */\n    // \"disableReferencedProjectLoad\": true,             /* Reduce the number of projects loaded automatically by TypeScript. */\n\n    /* Language and Environment */\n    \"target\": \"ES2016\",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */\n    // \"lib\": [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */\n    // \"jsx\": \"preserve\",                                /* Specify what JSX code is generated. */\n    \"experimentalDecorators\": true,                   /* Enable experimental support for TC39 stage 2 draft decorators. */\n    \"emitDecoratorMetadata\": true,                    /* Emit design-type metadata for decorated declarations in source files. */\n    // \"jsxFactory\": \"\",                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */\n    // \"jsxFragmentFactory\": \"\",                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */\n    // \"jsxImportSource\": \"\",                            /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */\n    // \"reactNamespace\": \"\",                             /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */\n    // \"noLib\": true,                                    /* Disable including any library files, including the default lib.d.ts. */\n    // \"useDefineForClassFields\": true,                  /* Emit ECMAScript-standard-compliant class fields. */\n\n    /* Modules */\n    \"module\": \"commonjs\",                                /* Specify what module code is generated. */\n    \"rootDir\": \"./src\",                                  /* Specify the root folder within your source files. */\n    // \"moduleResolution\": \"node\",                       /* Specify how TypeScript looks up a file from a given module specifier. */\n    // \"baseUrl\": \"./\",                                  /* Specify the base directory to resolve non-relative module names. */\n    // \"paths\": {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */\n    // \"rootDirs\": [],                                   /* Allow multiple folders to be treated as one when resolving modules. */\n    \"typeRoots\": [\n      \"src/@types\",\n      \"./node_modules/@types\",\n    ],                                  /* Specify multiple folders that act like `./node_modules/@types`. */\n    // \"types\": [],                                      /* Specify type package names to be included without being referenced in a source file. */\n    // \"allowUmdGlobalAccess\": true,                     /* Allow accessing UMD globals from modules. */\n    // \"resolveJsonModule\": true,                        /* Enable importing .json files */\n    // \"noResolve\": true,                                /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */\n\n    /* JavaScript Support */\n    // \"allowJs\": true,                                  /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */\n    // \"checkJs\": true,                                  /* Enable error reporting in type-checked JavaScript files. */\n    // \"maxNodeModuleJsDepth\": 1,                        /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */\n\n    /* Emit */\n    // \"declaration\": true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */\n    // \"declarationMap\": true,                           /* Create sourcemaps for d.ts files. */\n    // \"emitDeclarationOnly\": true,                      /* Only output d.ts files and not JavaScript files. */\n    \"sourceMap\": true,                                /* Create source map files for emitted JavaScript files. */\n    // \"outFile\": \"./\",                                  /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */\n    \"outDir\": \"./dist\",                                   /* Specify an output folder for all emitted files. */\n    // \"removeComments\": true,                           /* Disable emitting comments. */\n    // \"noEmit\": true,                                   /* Disable emitting files from a compilation. */\n    // \"importHelpers\": true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */\n    // \"importsNotUsedAsValues\": \"remove\",               /* Specify emit/checking behavior for imports that are only used for types */\n    // \"downlevelIteration\": true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */\n    // \"sourceRoot\": \"\",                                 /* Specify the root path for debuggers to find the reference source code. */\n    // \"mapRoot\": \"\",                                    /* Specify the location where debugger should locate map files instead of generated locations. */\n    // \"inlineSourceMap\": true,                          /* Include sourcemap files inside the emitted JavaScript. */\n    // \"inlineSources\": true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */\n    // \"emitBOM\": true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */\n    // \"newLine\": \"crlf\",                                /* Set the newline character for emitting files. */\n    // \"stripInternal\": true,                            /* Disable emitting declarations that have `@internal` in their JSDoc comments. */\n    // \"noEmitHelpers\": true,                            /* Disable generating custom helper functions like `__extends` in compiled output. */\n    // \"noEmitOnError\": true,                            /* Disable emitting files if any type checking errors are reported. */\n    // \"preserveConstEnums\": true,                       /* Disable erasing `const enum` declarations in generated code. */\n    // \"declarationDir\": \"./\",                           /* Specify the output directory for generated declaration files. */\n    // \"preserveValueImports\": true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */\n\n    /* Interop Constraints */\n    // \"isolatedModules\": true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */\n    // \"allowSyntheticDefaultImports\": true,             /* Allow 'import x from y' when a module doesn't have a default export. */\n    \"esModuleInterop\": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */\n    // \"preserveSymlinks\": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */\n    \"forceConsistentCasingInFileNames\": true,            /* Ensure that casing is correct in imports. */\n\n    /* Type Checking */\n    \"strict\": true,                                      /* Enable all strict type-checking options. */\n    // \"noImplicitAny\": true,                            /* Enable error reporting for expressions and declarations with an implied `any` type.. */\n    // \"strictNullChecks\": true,                         /* When type checking, take into account `null` and `undefined`. */\n    // \"strictFunctionTypes\": true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */\n    // \"strictBindCallApply\": true,                      /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */\n    \"strictPropertyInitialization\": false,             /* Check for class properties that are declared but not set in the constructor. */\n    // \"noImplicitThis\": true,                           /* Enable error reporting when `this` is given the type `any`. */\n    // \"useUnknownInCatchVariables\": true,               /* Type catch clause variables as 'unknown' instead of 'any'. */\n    // \"alwaysStrict\": true,                             /* Ensure 'use strict' is always emitted. */\n    // \"noUnusedLocals\": true,                           /* Enable error reporting when a local variables aren't read. */\n    // \"noUnusedParameters\": true,                       /* Raise an error when a function parameter isn't read */\n    // \"exactOptionalPropertyTypes\": true,               /* Interpret optional property types as written, rather than adding 'undefined'. */\n    // \"noImplicitReturns\": true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */\n    // \"noFallthroughCasesInSwitch\": true,               /* Enable error reporting for fallthrough cases in switch statements. */\n    // \"noUncheckedIndexedAccess\": true,                 /* Include 'undefined' in index signature results */\n    // \"noImplicitOverride\": true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */\n    // \"noPropertyAccessFromIndexSignature\": true,       /* Enforces using indexed accessors for keys declared using an indexed type */\n    // \"allowUnusedLabels\": true,                        /* Disable error reporting for unused labels. */\n    // \"allowUnreachableCode\": true,                     /* Disable error reporting for unreachable code. */\n\n    /* Completeness */\n    // \"skipDefaultLibCheck\": true,                      /* Skip type checking .d.ts files that are included with TypeScript. */\n    \"skipLibCheck\": true                                 /* Skip type checking all .d.ts files. */\n  }\n}\n"
  },
  {
    "path": "aquila/txt_transform/Dockerfile_mercury",
    "content": "FROM node:12.18.1\nENV NODE_ENV=production\n\nWORKDIR /app\n\nCOPY [\"package.json\", \"package-lock.json*\", \"./\"]\n\nRUN npm install --production\n\nCOPY . .\n\nCMD [ \"node\", \"server.js\" ]\n"
  },
  {
    "path": "aquila/txt_transform/Dockerfile_txtpick",
    "content": "FROM python:3.8-slim-buster\n\nWORKDIR /app\n\nCOPY requirements.txt requirements.txt\nRUN pip3 install -r requirements.txt\n\nCOPY . .\n\nCMD [ \"python3\", \"-m\" , \"flask\", \"run\", \"--host=0.0.0.0\", \"--port=5008\"]\n"
  },
  {
    "path": "aquila/txt_transform/app.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom __future__ import absolute_import\nfrom __future__ import division, print_function, unicode_literals\n\nimport logging\n\nimport re\n\nfrom flask import Flask, request\nfrom flask_cors import CORS\n\napp = Flask(__name__, instance_relative_config=True)\n\n# from sumy.parsers.html import HtmlParser\nfrom sumy.parsers.plaintext import PlaintextParser\nfrom sumy.nlp.tokenizers import Tokenizer\nfrom sumy.summarizers.lsa import LsaSummarizer as Summarizer\n# from sumy.summarizers.luhn import LuhnSummarizer as Summarizer\nfrom sumy.nlp.stemmers import Stemmer\nfrom sumy.utils import get_stop_words\nfrom bs4 import BeautifulSoup\n\nimport nltk\nnltk.download('punkt')\nLANGUAGE = \"english\"\n\ndef get_paragraphs(html_doc):\n    cleantext = BeautifulSoup(html_doc, \"lxml\").text\n    paras = []\n    counter = 0\n    \n    pattern_ = r\"\\n|(?<=[a-z]\\.)\\s+\"\n    result = re.split(pattern_, cleantext)\n    for para_ in result:\n        if para_ != None:\n            # remove citations\n            c_pattern_ = r\"\\[[^\\[]*?\\]\"\n            para = re.sub(c_pattern_, \"\", para_)\n            # remove special chars\n            sc_pattern = r\"[^A-Za-z0-9]+\"\n            para__ = re.sub(sc_pattern, \"\", para)\n            if para__.strip() != \"\":\n                # minimum 10 words in a sentance is needed\n                if len(para.split()) > 10:\n                    counter += 1\n                    paras.append(para.strip())\n\n    return paras, counter\n\ndef extract_request_params (request):\n    if not request.is_json:\n        logging.error(\"Cannot parse request parameters\")\n\n        # request is invalid\n        return {}\n\n    # Extract JSON data\n    data_ = request.get_json()\n\n    return data_\n\n@app.route(\"/process\", methods=['POST'])\ndef process ():\n    \"\"\"\n    Process html content\n    \"\"\"\n\n    # get parameters\n    html = None\n    \n    if extract_request_params(request).get(\"html\"):\n        html = extract_request_params(request)[\"html\"]\n\n    if not html:\n        # Build error response\n        return {\n                \"success\": False,\n                \"message\": \"Invalid parameters\"\n            }, 400\n\n    # process logic\n    text_in, nlines = get_paragraphs(html)\n    sentances_ret = []\n\n    parser = PlaintextParser.from_string(\"\\n\".join(text_in), Tokenizer(LANGUAGE))\n    stemmer = Stemmer(LANGUAGE)\n\n    summarizer = Summarizer(stemmer)\n    summarizer.stop_words = get_stop_words(LANGUAGE)\n\n    SENTENCES_COUNT = int(nlines * 0.2)\n    if SENTENCES_COUNT > 100:\n        SENTENCES_COUNT = 100\n    if SENTENCES_COUNT < 1:\n        SENTENCES_COUNT = nlines\n        \n    for sentence in summarizer(parser.document, SENTENCES_COUNT):\n        sentances_ret.append(sentence._text)\n\n    # Build response\n    return {\n            \"success\": True,\n            \"result\": sentances_ret\n        }, 200\n\n\n# Server starter\ndef flaskserver ():\n    \"\"\"\n    start server\n    \"\"\"\n    app.run(host='0.0.0.0', port=5008, debug=False)\n\n# Enable CORS\nCORS(app)\n\n\nif __name__ == \"__main__\":\n    flaskserver()\n"
  },
  {
    "path": "aquila/txt_transform/package.json",
    "content": "{\n  \"name\": \"mercury\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@postlight/mercury-parser\": \"^2.2.0\",\n    \"express\": \"^4.17.1\",\n    \"node-html-parser\": \"^3.3.4\"\n  }\n}\n"
  },
  {
    "path": "aquila/txt_transform/requirements.txt",
    "content": "sumy==0.9.0\nrequests==2.27.1\nFlask_Cors==3.0.10\nFlask==2.0.3\nbeautifulsoup4==4.10.0\nnumpy==1.22.2"
  },
  {
    "path": "aquila/txt_transform/server.js",
    "content": "import express from \"express\";\nvar app = express();\napp.use(express.json({limit: '50mb'}));\nconst port = 5009\n\nimport Mercury from \"@postlight/mercury-parser\";\n// import pkg from 'node-html-parser';\n// const { parse } = pkg;\n\napp.post('/process', function (req, res) {\n    if (req.body.url && req.body.html) {\n        Mercury.parse(req.body.url, {\n            html: req.body.html\n        }).then(result => {\n//             var root = parse(result.content);\n            res.send({\n                data: result\n            });\n        });\n    }\n    else {\n        res.sendStatus(400);\n    }\n});\n\napp.listen(port, () => {\n    console.log(`Example app listening at http://localhost:${port}`);\n});\n"
  },
  {
    "path": "aquila/txt_transform/test.html",
    "content": "<div><div id=\"mw-content-text\" class=\"mw-body-content mw-content-ltr\"><div class=\"mw-parser-output\"><div class=\"shortdescription nomobile noexcerpt noprint searchaux\">Decentralized cryptocurrency</div>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">&quot;&#x20BF;&quot; redirects here. It is not to be confused with &quot;&#xE3F;&quot; for <a href=\"https://en.wikipedia.org/wiki/Thai_baht\">Thai baht</a>.</div>\\n' +\n    '\\n' +\n    '<figure class=\"infobox\"><img alt=\"Prevailing bitcoin logo\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Bitcoin_logo.svg/252px-Bitcoin_logo.svg.png\" width=\"252\" height=\"53\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Bitcoin_logo.svg/378px-Bitcoin_logo.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Bitcoin_logo.svg/504px-Bitcoin_logo.svg.png 2x\"><tbody><tr><th class=\"infobox-above\">Bitcoin</th></tr><tr><td class=\"infobox-image\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_logo.svg\" class=\"image\"></a><div class=\"infobox-caption\">Prevailing bitcoin logo</div></td></tr><tr><th class=\"infobox-header\">Denominations</th></tr><tr><th class=\"infobox-label\">Plural</th><td class=\"infobox-data\">bitcoins</td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Currency_symbol\">Symbol</a></th><td class=\"infobox-data\">&#x20BF; (Unicode: <span class=\"nowrap\"><span class=\"monospaced\">U+20BF</span> </span><span>&#x20BF;</span> <span>BITCOIN SIGN</span> (HTML&#xA0;<code>&amp;#8383;</code>))<sup id=\"cite_ref-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-2\">[a]</a></sup></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Ticker_symbol\">Ticker symbol</a></th><td class=\"infobox-data\">BTC, XBT<sup id=\"cite_ref-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-3\">[b]</a></sup></td></tr><tr><th class=\"infobox-label\">Precision</th><td class=\"infobox-data\">10<sup>&#x2212;8</sup></td></tr><tr><th class=\"infobox-label\">Subunits</th><td class=\"infobox-data\"></td></tr><tr><th class=\"infobox-label\"><span class=\"nobold\">&#x2002;<span class=\"frac\"><span class=\"num\">1</span>&#x2044;<span class=\"den\">1000</span></span></span></th><td class=\"infobox-data\">millibitcoin</td></tr><tr><th class=\"infobox-label\"><span class=\"nobold\">&#x2002;<span class=\"frac\"><span class=\"num\">1</span>&#x2044;<span class=\"den\"><span class=\"nowrap\"><span></span>100<span>000</span><span>000</span></span></span></span></span></th><td class=\"infobox-data\"><span>satoshi</span><sup id=\"cite_ref-satoshi_unit_4-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-satoshi_unit-4\">[2]</a></sup></td></tr><tr><th class=\"infobox-header\">Development</th></tr><tr><th class=\"infobox-label\">Original author(s)</th><td class=\"infobox-data\"><span><a href=\"https://en.wikipedia.org/wiki/Satoshi_Nakamoto\">Satoshi Nakamoto</a></span></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/White_paper\">White paper</a></th><td class=\"infobox-data\"><a class=\"external text\" href=\"https://bitcoin.org/bitcoin.pdf\">&quot;Bitcoin: A Peer-to-Peer Electronic Cash System&quot;</a><sup id=\"cite_ref-paper_6-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-paper-6\">[4]</a></sup></td></tr><tr><th class=\"infobox-label\">Implementation(s)</th><td class=\"infobox-data\">Bitcoin Core</td></tr><tr><th class=\"infobox-label\">Initial release</th><td class=\"infobox-data\">0.1.0 / 9&#xA0;January 2009<span class=\"noprint\"> (12 years ago)</span><span>&#xA0;(<span class=\"bday dtstart published updated\">2009-01-09</span>)</span></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Software_release_life_cycle\">Latest release</a></th><td class=\"infobox-data\">0.21.1 / 2&#xA0;May 2021<span class=\"noprint\"> (25 days ago)</span><span>&#xA0;(<span class=\"bday dtstart published updated\">2021-05-02</span>)</span><sup id=\"cite_ref-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-5\">[3]</a></sup></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Repository_(version_control)\">Code repository</a></th><td class=\"infobox-data\"><a class=\"external free\" href=\"https://github.com/bitcoin/bitcoin\">https://github.com/bitcoin/bitcoin</a></td></tr><tr><th class=\"infobox-label\">Development status</th><td class=\"infobox-data\">Active</td></tr><tr><th class=\"infobox-label\">Website</th><td class=\"infobox-data\"><span class=\"url\"><a class=\"external text\" href=\"https://bitcoin.org/\">bitcoin<wbr>.org</a></span></td></tr><tr><th class=\"infobox-header\">Ledger</th></tr><tr><th class=\"infobox-label\">Ledger start</th><td class=\"infobox-data\">3&#xA0;January 2009<span class=\"noprint\"> (12 years ago)</span><span>&#xA0;(<span class=\"bday dtstart published updated\">2009-01-03</span>)</span></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Trusted_timestamping\">Timestamping scheme</a></th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/Proof-of-work_system\" class=\"mw-redirect\">Proof-of-work</a> (partial hash inversion)</td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Hash_function\">Hash function</a></th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/SHA-256\" class=\"mw-redirect\">SHA-256</a></td></tr><tr><th class=\"infobox-label\">Issuance schedule</th><td class=\"infobox-data\">Decentralized (block reward)<br>Initially &#x20BF;50 per block, halved every 210,000 blocks<sup id=\"cite_ref-JSC_11-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JSC-11\">[7]</a></sup></td></tr><tr><th class=\"infobox-label\">Block reward</th><td class=\"infobox-data\">&#x20BF;6.25<sup id=\"cite_ref-7\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-7\">[c]</a></sup></td></tr><tr><th class=\"infobox-label\">Block time</th><td class=\"infobox-data\">10 minutes</td></tr><tr><th class=\"infobox-label\">Block explorer</th><td class=\"infobox-data\">Many implementations</td></tr><tr><th class=\"infobox-label\">Circulating supply</th><td class=\"infobox-data\">&#x20BF;18,660,000 (as of 20&#xA0;March&#xA0;2021<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>)</td></tr><tr><th class=\"infobox-label\">Supply limit</th><td class=\"infobox-data\">&#x20BF;21,000,000<sup id=\"cite_ref-8\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-8\">[5]</a></sup><sup id=\"cite_ref-10\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-10\">[d]</a></sup></td></tr><tr><td class=\"infobox-below\"><div><div class=\"reflist reflist-lower-alpha\">\\n' +\n    '<div class=\"mw-references-wrap\"><ol class=\"references\">\\n' +\n    '<li id=\"cite_note-2\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-2\">^</a></b></span> <span class=\"reference-text\">The symbol was encoded in <a href=\"https://en.wikipedia.org/wiki/Unicode\">Unicode</a> version 10.0 at position <span class=\"nowrap\"><span class=\"monospaced\">U+20BF</span> </span><span>&#x20BF;</span> <span>BITCOIN SIGN</span> in the <a href=\"https://en.wikipedia.org/wiki/Currency_Symbols_(Unicode_block)\">Currency Symbols block</a> in June 2017.<sup id=\"cite_ref-unicode-10_1-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-unicode-10-1\">[1]</a></sup></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-3\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-3\">^</a></b></span> <span class=\"reference-text\">Compatible with ISO 4217.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-7\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-7\">^</a></b></span> <span class=\"reference-text\">May 2020 to approximately 2024, halved approximately every four years</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-10\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-10\">^</a></b></span> <span class=\"reference-text\">The supply will approach, but never reach, &#x20BF;21 million. Issuance will permanently halt <abbr>c.</abbr> 2140 at &#x20BF;20,999,999.9769.<sup id=\"cite_ref-Antonopoulos2014_9-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup></span>\\n' +\n    '</li>\\n' +\n    '</ol></div></div></div></td></tr></tbody></figure>\\n' +\n    '<table class=\"metadata mbox-small noprint selfref\">\\n' +\n    '<tbody><tr>\\n' +\n    '<td></td>\\n' +\n    '<td class=\"mbox-text plainlist\"><b>This article contains <a href=\"https://en.wikipedia.org/wiki/Help:Special_characters\">special characters</a>.</b> Without proper <a href=\"https://en.wikipedia.org/wiki/Help:Special_characters\">rendering support</a>, you may see <a href=\"https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character\">question marks, boxes, or other symbols</a>.</td></tr>\\n' +\n    '</tbody></table>\\n' +\n    '<p><b>Bitcoin</b> (<b>&#x20BF;</b>) is a decentralized <a href=\"https://en.wikipedia.org/wiki/Digital_currency\">digital currency</a>, without a <a href=\"https://en.wikipedia.org/wiki/Central_bank\">central bank</a> or single administrator, that can be sent from user to user on the <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network\">peer-to-peer bitcoin network</a> without the need for intermediaries.<sup id=\"cite_ref-JSC_11-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JSC-11\">[7]</a></sup> Transactions are verified by network <a href=\"https://en.wikipedia.org/wiki/Node_(networking)\">nodes</a> through <a href=\"https://en.wikipedia.org/wiki/Cryptography\">cryptography</a> and recorded in a public <a href=\"https://en.wikipedia.org/wiki/Distributed_ledger\">distributed ledger</a> called a <a href=\"https://en.wikipedia.org/wiki/Blockchain\">blockchain</a>. The <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency\">cryptocurrency</a> was invented in 2008 by an unknown person or group of people using the name <span><a href=\"https://en.wikipedia.org/wiki/Satoshi_Nakamoto\">Satoshi Nakamoto</a></span>.<sup id=\"cite_ref-whoissn_12-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-whoissn-12\">[8]</a></sup> The currency began use in 2009<sup id=\"cite_ref-NY2011_13-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NY2011-13\">[9]</a></sup> when its implementation was released as <a href=\"https://en.wikipedia.org/wiki/Open-source_software\">open-source software</a>.<sup id=\"cite_ref-Antonopoulos2014_9-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 1</span></sup>\\n' +\n    '</p><p>Bitcoins are created as a reward for a process known as <a href=\"https://en.wikipedia.org/wiki/Bitcoin#Mining\">mining</a>. They can be exchanged for other currencies, products, and services,<sup id=\"cite_ref-14\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-14\">[10]</a></sup> but the real-world value of the coins is extremely volatile.<sup id=\"cite_ref-:1_15-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-:1-15\">[11]</a></sup> Research produced by the <a href=\"https://en.wikipedia.org/wiki/University_of_Cambridge\">University of Cambridge</a> estimated that in 2017, there were 2.9 to 5.8 million unique users using a <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_wallet\">cryptocurrency wallet</a>, most of them using bitcoin.<sup id=\"cite_ref-CU2017_16-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-CU2017-16\">[12]</a></sup> Users choose to participate in the digital currency for a number of reasons: ideologies such as commitment to anarchism, decentralization and libertarianism, convenience, using the currency as an investment and pseudonymity of transactions. Increased use has led to a desire among governments for regulation in order to tax, facilitate legal use in trade and for other reasons (such as investigations for <a href=\"https://en.wikipedia.org/wiki/Money_laundering\">money laundering</a> and <a href=\"https://en.wikipedia.org/wiki/Market_manipulation\">price manipulation</a>).\\n' +\n    '</p><p>Bitcoin has been criticized for its use in illegal transactions, the large amount of electricity (and thus <a href=\"https://en.wikipedia.org/wiki/Carbon_footprint\">carbon footprint</a>) used by mining, <a href=\"https://en.wikipedia.org/wiki/Volatility_(finance)\">price volatility</a>, and thefts from exchanges. Some economists and commentators have characterized it as a <a href=\"https://en.wikipedia.org/wiki/Speculative_bubble\" class=\"mw-redirect\">speculative bubble</a> at various times. Bitcoin has also been used as an investment, although several regulatory agencies have issued investor alerts about bitcoin.<sup id=\"cite_ref-:1_15-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-:1-15\">[11]</a></sup><sup id=\"cite_ref-CFTC_bitcoin_17-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-CFTC_bitcoin-17\">[13]</a></sup><sup id=\"cite_ref-18\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-18\">[14]</a></sup>\\n' +\n    '</p><p>The word <i>bitcoin</i> was defined in a <a href=\"https://en.wikipedia.org/wiki/White_paper\">white paper</a> published on 31 October 2008.<sup id=\"cite_ref-paper_6-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-paper-6\">[4]</a></sup><sup id=\"cite_ref-ageofcr_19-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ageofcr-19\">[15]</a></sup> It is a <a href=\"https://en.wikipedia.org/wiki/Compound_(linguistics)\">compound</a> of the words <i><a href=\"https://en.wikipedia.org/wiki/Bit\">bit</a></i> and <i><a href=\"https://en.wikipedia.org/wiki/Coin\">coin</a></i>.<sup id=\"cite_ref-btox_20-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-btox-20\">[16]</a></sup> No uniform convention for <i>bitcoin</i> capitalization exists; some sources use <i>Bitcoin</i>, capitalized, to refer to the technology and <a href=\"https://en.wikipedia.org/wiki/Computer_network\">network</a> and <i>bitcoin</i>, lowercase, for the unit of account.<sup id=\"cite_ref-capitalization_21-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-capitalization-21\">[17]</a></sup> <i><a href=\"https://en.wikipedia.org/wiki/The_Wall_Street_Journal\">The Wall Street Journal</a></i>,<sup id=\"cite_ref-22\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-22\">[18]</a></sup> <i><a href=\"https://en.wikipedia.org/wiki/The_Chronicle_of_Higher_Education\">The Chronicle of Higher Education</a></i>,<sup id=\"cite_ref-23\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-23\">[19]</a></sup> and the <i><a href=\"https://en.wikipedia.org/wiki/Oxford_English_Dictionary\">Oxford English Dictionary</a></i><sup id=\"cite_ref-btox_20-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-btox-20\">[16]</a></sup> advocate the use of lowercase <i>bitcoin</i> in all cases.\\n' +\n    '</p>\\n' +\n    '\\n' +\n    '\\n' +\n    '<h2><span class=\"mw-headline\" id=\"History\">History</span></h2>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Main article: <a href=\"https://en.wikipedia.org/wiki/History_of_bitcoin\">History of bitcoin</a></div>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Creation\">Creation</span></h3>\\n' +\n    '<p>The domain name <i>bitcoin.org</i> was registered on 18 August 2008.<sup id=\"cite_ref-24\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-24\">[20]</a></sup> On 31 October 2008, a link to a paper authored by <a href=\"https://en.wikipedia.org/wiki/Satoshi_Nakamoto\">Satoshi Nakamoto</a> titled <i>Bitcoin: A Peer-to-Peer Electronic Cash System</i><sup id=\"cite_ref-paper_6-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-paper-6\">[4]</a></sup> was posted to a cryptography mailing list.<sup id=\"cite_ref-25\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-25\">[21]</a></sup> Nakamoto implemented the bitcoin software as <a href=\"https://en.wikipedia.org/wiki/Open-source_software\">open-source code</a> and released it in January 2009.<sup id=\"cite_ref-26\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-26\">[22]</a></sup><sup id=\"cite_ref-27\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-27\">[23]</a></sup><sup id=\"cite_ref-NY2011_13-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NY2011-13\">[9]</a></sup> Nakamoto&apos;s identity remains unknown.<sup id=\"cite_ref-whoissn_12-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-whoissn-12\">[8]</a></sup>\\n' +\n    '</p><p>On 3 January 2009, the bitcoin network was created when Nakamoto mined the starting block of the chain, known as the <i><a href=\"https://en.wikipedia.org/wiki/Genesis_(blockchain)\" class=\"mw-redirect\">genesis block</a></i>.<sup id=\"cite_ref-Wired:RFB_28-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Wired:RFB-28\">[24]</a></sup><sup id=\"cite_ref-29\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-29\">[25]</a></sup> Embedded in the <a href=\"https://en.wikipedia.org/wiki/Bitcoin#Supply\">coinbase</a> of this block was the text &quot;The Times 03/Jan/2009 Chancellor on brink of second bailout for banks&quot;.<sup id=\"cite_ref-NY2011_13-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NY2011-13\">[9]</a></sup> This note references a headline published by <i><a href=\"https://en.wikipedia.org/wiki/The_Times\">The Times</a></i> and has been interpreted as both a timestamp and a comment on the instability caused by <a href=\"https://en.wikipedia.org/wiki/Fractional-reserve_banking\">fractional-reserve banking</a>.<sup id=\"cite_ref-30\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-30\">[26]</a></sup><sup class=\"reference\">:<span>18</span></sup>\\n' +\n    '</p><p>The receiver of the first bitcoin transaction was <a href=\"https://en.wikipedia.org/wiki/Hal_Finney_(cypherpunk)\" class=\"mw-redirect\">cypherpunk Hal Finney</a>, who had created the first <a href=\"https://en.wikipedia.org/wiki/Proof-of-work_system#Reusable_proof-of-work_as_e-money\" class=\"mw-redirect\">reusable proof-of-work</a> system (RPoW) in 2004.<sup id=\"cite_ref-31\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-31\">[27]</a></sup> Finney downloaded the bitcoin software on its release date, and on 12 January 2009 received ten bitcoins from Nakamoto.<sup id=\"cite_ref-32\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-32\">[28]</a></sup><sup id=\"cite_ref-33\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-33\">[29]</a></sup> Other early cypherpunk supporters were creators of bitcoin predecessors: <a href=\"https://en.wikipedia.org/wiki/Wei_Dai\">Wei Dai</a>, creator of b-money, and <a href=\"https://en.wikipedia.org/wiki/Nick_Szabo\">Nick Szabo</a>, creator of <a href=\"https://en.wikipedia.org/wiki/Bit_gold\" class=\"mw-redirect\">bit gold</a>.<sup id=\"cite_ref-Wired:RFB_28-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Wired:RFB-28\">[24]</a></sup> In 2010, the first known <a href=\"https://en.wikipedia.org/wiki/Financial_transaction\">commercial transaction</a> using bitcoin occurred when programmer Laszlo Hanyecz bought two <a href=\"https://en.wikipedia.org/wiki/Papa_John%27s\" class=\"mw-redirect\">Papa John&apos;s</a> pizzas for &#x20BF;10,000.<sup id=\"cite_ref-34\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-34\">[30]</a></sup>\\n' +\n    '</p><p><a href=\"https://en.wikipedia.org/wiki/Blockchain#Blockchain_analysis\">Blockchain analysts</a> estimate that Nakamoto had mined about one million bitcoins<sup id=\"cite_ref-35\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-35\">[31]</a></sup> before disappearing in 2010 when he handed the network alert key and control of the code repository over to <a href=\"https://en.wikipedia.org/wiki/Gavin_Andresen\">Gavin Andresen</a>. Andresen later became lead developer at the <a href=\"https://en.wikipedia.org/wiki/Bitcoin_Foundation\">Bitcoin Foundation</a>.<sup id=\"cite_ref-36\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-36\">[32]</a></sup><sup id=\"cite_ref-governance_37-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-governance-37\">[33]</a></sup> Andresen then sought to decentralize control. This left opportunity for controversy to develop over the future development path of bitcoin, in contrast to the perceived authority of Nakamoto&apos;s contributions.<sup id=\"cite_ref-breakingup_38-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-breakingup-38\">[34]</a></sup><sup id=\"cite_ref-governance_37-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-governance-37\">[33]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span id=\"2011.E2.80.932012\"></span><span class=\"mw-headline\" id=\"2011&#x2013;2012\">2011&#x2013;2012</span></h3>\\n' +\n    '<p>After early &quot;<a href=\"https://en.wikipedia.org/wiki/Proof-of-concept\" class=\"mw-redirect\">proof-of-concept</a>&quot; transactions, the first major users of bitcoin were <a href=\"https://en.wikipedia.org/wiki/Black_market\">black markets</a>, such as <a href=\"https://en.wikipedia.org/wiki/Silk_Road_(marketplace)\">Silk Road</a>. During its 30 months of existence, beginning in February 2011, Silk Road exclusively accepted bitcoins as payment, transacting 9.9 million in bitcoins, worth about $214 million.<sup id=\"cite_ref-JEP_39-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup><sup class=\"reference\">:<span>222</span></sup>\\n' +\n    '</p><p>In 2011, the price started at $0.30 per bitcoin, growing to $5.27 for the year. The price rose to $31.50 on 8 June. Within a month, the price fell to $11.00. The next month it fell to $7.80, and in another month to $4.77.<sup id=\"cite_ref-Odata_40-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Odata-40\">[36]</a></sup>\\n' +\n    '</p><p>In 2012, bitcoin prices started at $5.27, growing to $13.30 for the year.<sup id=\"cite_ref-Odata_40-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Odata-40\">[36]</a></sup> By 9 January the price had risen to $7.38, but then crashed by 49% to $3.80 over the next 16 days. The price then rose to $16.41 on 17 August, but fell by 57% to $7.10 over the next three days.<sup id=\"cite_ref-MktWatch09022018_41-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-MktWatch09022018-41\">[37]</a></sup>\\n' +\n    '</p><p>The Bitcoin Foundation was founded in September 2012 to promote bitcoin&apos;s development and uptake.<sup id=\"cite_ref-42\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-42\">[38]</a></sup>\\n' +\n    '</p><p>On 1 November 2011, the <a href=\"https://en.wikipedia.org/wiki/Reference_implementation\">reference implementation</a> Bitcoin-Qt version 0.5.0 was released. It introduced a <a href=\"https://en.wikipedia.org/wiki/Front_and_back_ends\" class=\"mw-redirect\">front end</a> that used the <a href=\"https://en.wikipedia.org/wiki/Qt_(software)\">Qt user interface toolkit</a>.<sup id=\"cite_ref-bqt_43-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bqt-43\">[39]</a></sup> The software previously used <a href=\"https://en.wikipedia.org/wiki/Berkeley_DB\">Berkeley DB</a> for database management. Developers switched to <a href=\"https://en.wikipedia.org/wiki/LevelDB\">LevelDB</a> in release 0.8 in order to reduce blockchain <a href=\"https://en.wikipedia.org/wiki/Synchronization_(computer_science)\">synchronization</a> time.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> The update to this release resulted in a minor blockchain fork on 11 March 2013. The fork was resolved shortly afterwards.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> Seeding nodes through <a href=\"https://en.wikipedia.org/wiki/Internet_Relay_Chat\">IRC</a> was discontinued in version 0.8.2. From version 0.9.0 the software was renamed to Bitcoin Core. Transaction fees were reduced again by a factor of ten as a means to encourage <a href=\"https://en.wikipedia.org/wiki/Micropayment\">microtransactions</a>.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> Although Bitcoin Core does not use <a href=\"https://en.wikipedia.org/wiki/OpenSSL\">OpenSSL</a> for the operation of the network, the software did use OpenSSL for remote procedure calls. Version 0.9.1 was released to remove the network&apos;s vulnerability to the <a href=\"https://en.wikipedia.org/wiki/Heartbleed_bug\" class=\"mw-redirect\">Heartbleed bug</a>.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup>\\n' +\n    '</p>\\n' +\n    '<h3><span id=\"2013.E2.80.932016\"></span><span class=\"mw-headline\" id=\"2013&#x2013;2016\">2013&#x2013;2016</span></h3>\\n' +\n    '<p>In 2013, prices started at $13.30 rising to $770 by 1 January 2014.<sup id=\"cite_ref-Odata_40-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Odata-40\">[36]</a></sup>\\n' +\n    '</p><p>In March 2013 the <a href=\"https://en.wikipedia.org/wiki/Blockchain\">blockchain</a> temporarily split into two independent chains with different rules due to a bug in version 0.8 of the bitcoin software. The two blockchains operated simultaneously for six hours, each with its own version of the transaction history from the moment of the split. Normal operation was restored when the majority of the network downgraded to version 0.7 of the bitcoin software, selecting the backwards-compatible version of the blockchain. As a result, this blockchain became the longest chain and could be accepted by all participants, regardless of their bitcoin software version.<sup id=\"cite_ref-bug_events_44-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bug_events-44\">[40]</a></sup> During the split, the <a href=\"https://en.wikipedia.org/wiki/Mt._Gox\">Mt. Gox</a> exchange briefly halted bitcoin deposits and the price dropped by 23% to $37<sup id=\"cite_ref-bug_events_44-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bug_events-44\">[40]</a></sup><sup id=\"cite_ref-VergeFork_45-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-VergeFork-45\">[41]</a></sup> before recovering to the previous level of approximately $48 in the following hours.<sup id=\"cite_ref-46\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-46\">[42]</a></sup>\\n' +\n    '</p><p>The US <a href=\"https://en.wikipedia.org/wiki/Financial_Crimes_Enforcement_Network\">Financial Crimes Enforcement Network</a> (FinCEN) established regulatory guidelines for &quot;decentralized virtual currencies&quot; such as bitcoin, classifying American bitcoin miners who sell their generated bitcoins as Money Service Businesses (MSBs), that are subject to registration or other legal obligations.<sup id=\"cite_ref-ArsFinCEN_47-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ArsFinCEN-47\">[43]</a></sup><sup id=\"cite_ref-Finextra1_48-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Finextra1-48\">[44]</a></sup><sup id=\"cite_ref-FinCEN1_49-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-FinCEN1-49\">[45]</a></sup>\\n' +\n    '</p><p>In April, exchanges <a href=\"https://en.wikipedia.org/wiki/BitInstant\" class=\"mw-redirect\">BitInstant</a> and Mt. Gox experienced processing delays due to insufficient capacity<sup id=\"cite_ref-50\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-50\">[46]</a></sup> resulting in the bitcoin price dropping from $266 to $76 before returning to $160 within six hours.<sup id=\"cite_ref-51\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-51\">[47]</a></sup> The bitcoin price rose to $259 on 10 April, but then crashed by 83% to $45 over the next three days.<sup id=\"cite_ref-MktWatch09022018_41-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-MktWatch09022018-41\">[37]</a></sup>\\n' +\n    '</p><p>On 15 May 2013, US authorities seized accounts associated with Mt. Gox after discovering it had not registered as a <a href=\"https://en.wikipedia.org/wiki/Money_transmitter\">money transmitter</a> with FinCEN in the US.<sup id=\"cite_ref-52\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-52\">[48]</a></sup><sup id=\"cite_ref-ABA_FINCEN_53-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ABA_FINCEN-53\">[49]</a></sup> On 23 June 2013, the US <a href=\"https://en.wikipedia.org/wiki/Drug_Enforcement_Administration\">Drug Enforcement Administration</a> listed &#x20BF;11.02 as a seized asset in a <a href=\"https://en.wikipedia.org/wiki/United_States_Department_of_Justice\">United States Department of Justice</a> seizure notice pursuant to 21 U.S.C. &#xA7; 881. This marked the first time a government agency had seized bitcoin.<sup id=\"cite_ref-54\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-54\">[50]</a></sup> The FBI seized about &#x20BF;30,000<sup id=\"cite_ref-draper_55-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-draper-55\">[51]</a></sup> in October 2013 from the <a href=\"https://en.wikipedia.org/wiki/Dark_web\">dark web</a> website Silk Road, following the arrest of <a href=\"https://en.wikipedia.org/wiki/Ross_William_Ulbricht\" class=\"mw-redirect\">Ross William Ulbricht</a>.<sup id=\"cite_ref-56\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-56\">[52]</a></sup><sup id=\"cite_ref-57\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-57\">[53]</a></sup><sup id=\"cite_ref-58\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-58\">[54]</a></sup> These bitcoins were sold at <a href=\"https://en.wikipedia.org/wiki/First-price_sealed-bid_auction\">blind auction</a> by the <a href=\"https://en.wikipedia.org/wiki/United_States_Marshals_Service\">United States Marshals Service</a> to venture capital investor <a href=\"https://en.wikipedia.org/wiki/Tim_Draper\">Tim Draper</a>.<sup id=\"cite_ref-draper_55-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-draper-55\">[51]</a></sup> Bitcoin&apos;s price rose to $755 on 19 November and crashed by 50% to $378 the same day. On 30 November 2013, the price reached $1,163 before starting a long-term crash, declining by 87% to $152 in January 2015.<sup id=\"cite_ref-MktWatch09022018_41-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-MktWatch09022018-41\">[37]</a></sup>\\n' +\n    '</p><p>On 5 December 2013, the <a href=\"https://en.wikipedia.org/wiki/People%27s_Bank_of_China\">People&apos;s Bank of China</a> prohibited Chinese financial institutions from using bitcoins.<sup id=\"cite_ref-ccontrols_59-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ccontrols-59\">[55]</a></sup> After the announcement, the value of bitcoins dropped,<sup id=\"cite_ref-60\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-60\">[56]</a></sup> and <a href=\"https://en.wikipedia.org/wiki/Baidu\">Baidu</a> no longer accepted bitcoins for certain services.<sup id=\"cite_ref-bloomberg_61-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bloomberg-61\">[57]</a></sup> Buying real-world goods with any virtual currency had been illegal in China since at least 2009.<sup id=\"cite_ref-62\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-62\">[58]</a></sup>\\n' +\n    '</p><p>In 2014, prices started at $770 and fell to $314 for the year.<sup id=\"cite_ref-Odata_40-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Odata-40\">[36]</a></sup>  On 30 July 2014, the <a href=\"https://en.wikipedia.org/wiki/Wikimedia_Foundation\">Wikimedia Foundation</a> started accepting donations of bitcoin.<sup id=\"cite_ref-63\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-63\">[59]</a></sup>\\n' +\n    '</p><p>In 2015, prices started at $314 and rose to $434 for the year. In 2016, prices rose and climbed up to $998 by 1 January 2017.<sup id=\"cite_ref-Odata_40-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Odata-40\">[36]</a></sup>\\n' +\n    '</p><p>Release 0.10 of the software was made public on 16 February 2015. It introduced a consensus library which gave programmers easy access to the rules governing <a href=\"https://en.wikipedia.org/wiki/Consensus_decision-making\">consensus</a> on the network. In version 0.11.2 developers added a new feature which allowed transactions to be made unspendable until a specific time in the future.<sup id=\"cite_ref-v0.11.2_64-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-v0.11.2-64\">[60]</a></sup> Bitcoin Core 0.12.1 was released on 15 April 2016, and enabled multiple soft forks to occur concurrently.<sup id=\"cite_ref-0.12.1rel_65-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-0.12.1rel-65\">[61]</a></sup> Around 100 contributors worked on Bitcoin Core 0.13.0 which was released on 23 August 2016.\\n' +\n    '</p><p>In July 2016, the CheckSequenceVerify soft fork activated.<sup id=\"cite_ref-66\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-66\">[62]</a></sup>\\n' +\n    '</p><p>In October 2016, Bitcoin Core&apos;s 0.13.1 release featured the &quot;<a href=\"https://en.wikipedia.org/wiki/Segwit\" class=\"mw-redirect\">Segwit</a>&quot; soft fork that included a scaling improvement aiming to optimize the bitcoin blocksize.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> The patch which was originally finalised in April, and 35 developers were engaged to deploy it.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> This release featured Segregated Witness (<a href=\"https://en.wikipedia.org/wiki/SegWit\">SegWit</a>) which aimed to place downward pressure on transaction fees as well as increase the maximum transaction capacity of the network.<sup id=\"cite_ref-rel13.1_67-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-rel13.1-67\">[63]</a></sup><sup class=\"noprint Inline-Template noprint Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:No_original_research#Primary,_secondary_and_tertiary_sources\"><span>non-primary source needed</span></a></i>]</sup> The 0.13.1 release endured extensive testing and research leading to some delays in its release date.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> SegWit prevents various forms of transaction <a href=\"https://en.wikipedia.org/wiki/Malleability_(cryptography)\">malleability</a>.<sup id=\"cite_ref-swb_68-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-swb-68\">[64]</a></sup><sup class=\"noprint Inline-Template noprint Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:No_original_research#Primary,_secondary_and_tertiary_sources\"><span>non-primary source needed</span></a></i>]</sup>\\n' +\n    '</p>\\n' +\n    '<h3><span id=\"2017.E2.80.932019\"></span><span class=\"mw-headline\" id=\"2017&#x2013;2019\">2017&#x2013;2019</span></h3>\\n' +\n    '<p>On 15 July 2017, the controversial <a href=\"https://en.wikipedia.org/wiki/Segregated_Witness\" class=\"mw-redirect\">Segregated Witness</a> [SegWit] software upgrade was approved (&quot;locked-in&quot;). Segwit was intended to support the <a href=\"https://en.wikipedia.org/wiki/Lightning_Network\">Lightning Network</a> as well as improve scalability.<sup id=\"cite_ref-wsjsegwit_69-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-wsjsegwit-69\">[65]</a></sup> SegWit was subsequently activated on the network on 24 August 2017. The bitcoin price rose almost 50% in the week following SegWit&apos;s approval.<sup id=\"cite_ref-wsjsegwit_69-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-wsjsegwit-69\">[65]</a></sup> On 21 July 2017, bitcoin was trading at $2,748, up 52% from 14 July 2017&apos;s $1,835.<sup id=\"cite_ref-wsjsegwit_69-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-wsjsegwit-69\">[65]</a></sup> Supporters of large blocks who were dissatisfied with the activation of SegWit forked the software on 1 August 2017 to create <a href=\"https://en.wikipedia.org/wiki/Bitcoin_Cash\">Bitcoin Cash</a>, becoming one of many <a href=\"https://en.wikipedia.org/wiki/List_of_bitcoin_forks\">forks of bitcoin</a> such as <a href=\"https://en.wikipedia.org/wiki/Bitcoin_Gold\">Bitcoin Gold</a>.<sup id=\"cite_ref-bsit_70-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bsit-70\">[66]</a></sup> \\n' +\n    '</p><p>Prices started at $998 in 2017 and rose to $13,412.44 on 1 January 2018,<sup id=\"cite_ref-Odata_40-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Odata-40\">[36]</a></sup> after reaching its all-time high of $19,783.06 on 17 December 2017.<sup id=\"cite_ref-71\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-71\">[67]</a></sup>\\n' +\n    '</p><p>China banned trading in bitcoin, with first steps taken in September 2017, and a complete ban that started on 1 February 2018. Bitcoin prices then fell from $9,052 to $6,914 on 5 February 2018.<sup id=\"cite_ref-MktWatch09022018_41-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-MktWatch09022018-41\">[37]</a></sup> The percentage of bitcoin trading in the Chinese <a href=\"https://en.wikipedia.org/wiki/Renminbi\">renminbi</a> fell from over 90% in September 2017 to less than 1% in June 2018.<sup id=\"cite_ref-rmbXinhua_72-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-rmbXinhua-72\">[68]</a></sup>\\n' +\n    '</p><p>Throughout the rest of the first half of 2018, bitcoin&apos;s price fluctuated between $11,480 and $5,848. On 1 July 2018, bitcoin&apos;s price was $6,343.<sup id=\"cite_ref-YahooFin_73-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-YahooFin-73\">[69]</a></sup><sup id=\"cite_ref-Xpress10072018_74-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Xpress10072018-74\">[70]</a></sup> The price on 1 January 2019 was $3,747, down 72% for 2018 and down 81% since the all-time high.<sup id=\"cite_ref-YahooFin_73-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-YahooFin-73\">[69]</a></sup><sup id=\"cite_ref-75\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-75\">[71]</a></sup>\\n' +\n    '</p><p>In September 2018, an anonymous party discovered and reported an invalid-block denial-of-server vulnerability to developers of Bitcoin Core, Bitcoin ABC and Bitcoin Unlimited. Further analysis by bitcoin developers showed the issue could also allow the creation of blocks violating the 21 million coin limit and <a href=\"https://en.wikipedia.org/wiki/CVE_(identifier)\" class=\"mw-redirect\">CVE</a>-<a class=\"external text\" href=\"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-17144\">2018-17144</a> was assigned and the issue resolved.<sup id=\"cite_ref-76\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-76\">[72]</a></sup><sup class=\"noprint Inline-Template noprint Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:No_original_research#Primary,_secondary_and_tertiary_sources\"><span>non-primary source needed</span></a></i>]</sup>\\n' +\n    '</p><p>Bitcoin prices were negatively affected by several hacks or thefts from cryptocurrency exchanges, including thefts from <a href=\"https://en.wikipedia.org/wiki/Coincheck\">Coincheck</a> in January 2018, <a href=\"https://en.wikipedia.org/wiki/Bithumb\">Bithumb</a> in June, and Bancor in July. For the first six months of 2018, $761 million worth of cryptocurrencies was reported stolen from exchanges.<sup id=\"cite_ref-Roy3072018_77-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Roy3072018-77\">[73]</a></sup> Bitcoin&apos;s price was affected even though other cryptocurrencies were stolen at Coinrail and Bancor as investors worried about the security of cryptocurrency exchanges.<sup id=\"cite_ref-BloomFort_78-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BloomFort-78\">[74]</a></sup><sup id=\"cite_ref-CNNhack_79-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-CNNhack-79\">[75]</a></sup><sup id=\"cite_ref-TCBancor_80-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-TCBancor-80\">[76]</a></sup> In September 2019 the <a href=\"https://en.wikipedia.org/wiki/Intercontinental_Exchange#Bakkt\">Intercontinental Exchange</a> (the owner of the <a href=\"https://en.wikipedia.org/wiki/NYSE\" class=\"mw-redirect\">NYSE</a>) began trading of bitcoin futures on its exchange called Bakkt.<sup id=\"cite_ref-WSJBakkt_81-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-WSJBakkt-81\">[77]</a></sup> Bakkt also announced that it would launch options on bitcoin in December 2019.<sup id=\"cite_ref-bakkt20191024_82-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bakkt20191024-82\">[78]</a></sup> In December 2019, <a href=\"https://en.wikipedia.org/wiki/YouTube\">YouTube</a> removed bitcoin and cryptocurrency videos, but later restored the content after judging they had &quot;made the wrong call.&quot;<sup id=\"cite_ref-YoutubeBBC-Block_83-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-YoutubeBBC-Block-83\">[79]</a></sup>\\n' +\n    '</p><p>In February 2019, Canadian cryptocurrency exchange <a href=\"https://en.wikipedia.org/wiki/Quadriga_Fintech_Solutions\">Quadriga Fintech Solutions</a> failed with approximately $200 million missing.<sup id=\"cite_ref-Quadriga-Bloomberg_84-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Quadriga-Bloomberg-84\">[80]</a></sup> By June 2019 the price had recovered to $13,000.<sup id=\"cite_ref-ForbesCorona_85-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ForbesCorona-85\">[81]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span id=\"2020.E2.80.93present\"></span><span class=\"mw-headline\" id=\"2020&#x2013;present\">2020&#x2013;present</span></h3>\\n' +\n    '<p>According to <i>CoinMetrics</i> and <i>Forbes</i>, on 11 March 281,000 bitcoins were sold by owners who held them for only thirty days. This compared to &#x20BF;4,131 that had laid dormant for a year or more, indicating that the vast majority of the bitcoin volatility on that day was from recent buyers.<sup id=\"cite_ref-ForbesCorona_85-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ForbesCorona-85\">[81]</a></sup>  During the week of 11 March 2020 as a result of the <a href=\"https://en.wikipedia.org/wiki/COVID-19_pandemic\">COVID-19 pandemic</a>, cryptocurrency exchange <a href=\"https://en.wikipedia.org/wiki/Kraken_(company)\">Kraken</a> experienced an 83% increase in the number of account signups over the week of bitcoin&apos;s price collapse, a result of buyers looking to capitalize on the low price.<sup id=\"cite_ref-ForbesCorona_85-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ForbesCorona-85\">[81]</a></sup> On 13 March 2020, bitcoin fell below $4000 during a broad <a href=\"https://en.wikipedia.org/wiki/COVID-19_pandemic\">COVID-19 pandemic</a> related market selloff, after trading above $10,000 in February 2020.<sup id=\"cite_ref-86\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-86\">[82]</a></sup>\\n' +\n    '</p><p>In August 2020, <a href=\"https://en.wikipedia.org/wiki/MicroStrategy\">MicroStrategy</a> invested $250 million in bitcoin as a treasury reserve asset.<sup id=\"cite_ref-87\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-87\">[83]</a></sup> In October 2020, <a href=\"https://en.wikipedia.org/wiki/Square,_Inc.\">Square, Inc.</a> put approximately 1% of their total assets ($50 million) in bitcoin.<sup id=\"cite_ref-88\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-88\">[84]</a></sup> In November 2020, <a href=\"https://en.wikipedia.org/wiki/PayPal\">PayPal</a> announced that all users in the US could buy, hold, or sell bitcoin using PayPal.<sup id=\"cite_ref-89\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-89\">[85]</a></sup> On 30 November 2020, bitcoin hit a new all-time high of $19,860 topping the previous high from December 2017.<sup id=\"cite_ref-90\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-90\">[86]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Alexander_Vinnik\">Alexander Vinnik</a>, founder of <a href=\"https://en.wikipedia.org/wiki/BTC-e\">BTC-e</a>, was convicted and sentenced to 5 years in prison for money laundering in France while refusing to testify during his trial.<sup id=\"cite_ref-zdnetfrance_91-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-zdnetfrance-91\">[87]</a></sup> In December 2020 <a href=\"https://en.wikipedia.org/wiki/Massachusetts_Mutual_Life_Insurance_Company\" class=\"mw-redirect\">Massachusetts Mutual Life Insurance Company</a> announced it has purchased $100 million in bitcoin, or roughly 0.04% of its general investment account.<sup id=\"cite_ref-MM2020_92-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-MM2020-92\">[88]</a></sup>\\n' +\n    '</p><p>On 19 January 2021, <a href=\"https://en.wikipedia.org/wiki/Elon_Musk\">Elon Musk</a> placed #Bitcoin in his <a href=\"https://en.wikipedia.org/wiki/Twitter\">Twitter</a> profile tweeting &quot;In retrospect, it was inevitable&quot;, which caused the price to briefly rise about $5000 in an hour to $37,299.<sup id=\"cite_ref-CNBCMusk_93-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-CNBCMusk-93\">[89]</a></sup> On 25 January 2021 Microstrategy announced it continued to buy bitcoin and as of the same date it had holdings of &#x20BF;70,784 worth $2.38 billion.<sup id=\"cite_ref-BIMS_94-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BIMS-94\">[90]</a></sup> On 8 February 2021 <a href=\"https://en.wikipedia.org/wiki/Tesla,_Inc.\">Tesla&apos;s</a> announcement that it had purchased $1.5 billion in bitcoin and planned to start accepting bitcoin as payment for vehicles pushed the bitcoin price to an all-time high of $44,141.<sup id=\"cite_ref-TeslaCNBCbitcoinATH_95-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-TeslaCNBCbitcoinATH-95\">[91]</a></sup> On 18 February 2021, Elon Musk said that &quot;owning bitcoin was only a little better than holding conventional cash, but that the slight difference made it a better asset to hold&quot;.<sup id=\"cite_ref-96\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-96\">[92]</a></sup>\\n' +\n    '</p><p>It was announced in September 2020, that the <a href=\"https://en.wikipedia.org/wiki/Canton_of_Zug\">Canton of Zug</a> (in <a href=\"https://en.wikipedia.org/wiki/Switzerland\">Switzerland</a>) will start to accept tax payments in bitcoin from February 2021.<sup id=\"cite_ref-97\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-97\">[93]</a></sup><sup id=\"cite_ref-98\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-98\">[94]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Design\">Design</span></h2>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Secp256k1.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Secp256k1.png/220px-Secp256k1.png\" width=\"220\" height=\"220\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Secp256k1.png/330px-Secp256k1.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Secp256k1.png/440px-Secp256k1.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Secp256k1.png\" class=\"internal\"></a></div>Graph of the elliptic curve named secp256k1 over the <a href=\"https://en.wikipedia.org/wiki/Algebraic_number_field\">algebraic number field</a> of real numbers, <span class=\"mwe-math-element\"><span class=\"mwe-math-mathml-inline mwe-math-mathml-a11y\"><math>\\n' +\n    '  <semantics>\\n' +\n    '    <mrow class=\"MJX-TeXAtom-ORD\">\\n' +\n    '      <mstyle>\\n' +\n    '        <mi>R</mi>\\n' +\n    '      </mstyle>\\n' +\n    '    </mrow>\\n' +\n    '    <annotation>{\\\\displaystyle R}</annotation>\\n' +\n    '  </semantics>\\n' +\n    '</math></span><img src=\"https://wikimedia.org/api/rest_v1/media/math/render/svg/4b0bfb3769bf24d80e15374dc37b0441e2616e33\" class=\"mwe-math-fallback-image-inline\" alt=\"R\"></span><sup>2</sup></div></div></div>\\n' +\n    '<p>Bitcoin is based on an <a href=\"https://en.wikipedia.org/wiki/Elliptic_curve\">elliptic curve</a> called <a href=\"https://en.wikipedia.org/w/index.php?title=Secp256k1&amp;action=edit&amp;redlink=1\" class=\"new\">secp256k1</a> and encrypted with the <a href=\"https://en.wikipedia.org/wiki/ECDSA\" class=\"mw-redirect\">ECDSA</a> algorithm.<sup id=\"cite_ref-bwiki_99-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bwiki-99\">[95]</a></sup><sup class=\"noprint Inline-Template noprint noexcerpt Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:NOTRS\" class=\"mw-redirect\"><span>better&#xA0;source&#xA0;needed</span></a></i>]</sup> The equation for the Bitcoin secp256k1 curve is <span class=\"mwe-math-element\"><span class=\"mwe-math-mathml-inline mwe-math-mathml-a11y\"><math>\\n' +\n    '  <semantics>\\n' +\n    '    <mrow class=\"MJX-TeXAtom-ORD\">\\n' +\n    '      <mstyle>\\n' +\n    '        <mi>y</mi>\\n' +\n    '      </mstyle>\\n' +\n    '    </mrow>\\n' +\n    '    <annotation>{\\\\displaystyle y}</annotation>\\n' +\n    '  </semantics>\\n' +\n    '</math></span><img src=\"https://wikimedia.org/api/rest_v1/media/math/render/svg/b8a6208ec717213d4317e666f1ae872e00620a0d\" class=\"mwe-math-fallback-image-inline\" alt=\"y\"></span><sup>2</sup>=<span class=\"mwe-math-element\"><span class=\"mwe-math-mathml-inline mwe-math-mathml-a11y\"><math>\\n' +\n    '  <semantics>\\n' +\n    '    <mrow class=\"MJX-TeXAtom-ORD\">\\n' +\n    '      <mstyle>\\n' +\n    '        <mi>x</mi>\\n' +\n    '      </mstyle>\\n' +\n    '    </mrow>\\n' +\n    '    <annotation>{\\\\displaystyle x}</annotation>\\n' +\n    '  </semantics>\\n' +\n    '</math></span><img src=\"https://wikimedia.org/api/rest_v1/media/math/render/svg/87f9e315fd7e2ba406057a97300593c4802b53e4\" class=\"mwe-math-fallback-image-inline\" alt=\"x\"></span><sup>3</sup>+7.<sup id=\"cite_ref-hnhk_100-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-hnhk-100\">[96]</a></sup><sup class=\"noprint Inline-Template noprint noexcerpt Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:NOTRS\" class=\"mw-redirect\"><span>better&#xA0;source&#xA0;needed</span></a></i>]</sup> Bitcoin has a proposed Bitcoin Improvement Proposal (BIP) that would add support for <a href=\"https://en.wikipedia.org/wiki/Schnorr_signature\">Schnorr signatures</a>.<sup id=\"cite_ref-BP_A_Look_101-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BP_A_Look-101\">[97]</a></sup><sup class=\"reference\">:<span>101</span></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Units_and_divisibility\">Units and divisibility</span></h3>\\n' +\n    '<p>The <a href=\"https://en.wikipedia.org/wiki/Unit_of_account\">unit of account</a> of the bitcoin system is a <i>bitcoin</i>. <a href=\"https://en.wikipedia.org/wiki/Ticker_symbol\">Ticker symbols</a> used to represent bitcoin are BTC<sup id=\"cite_ref-BTCcode_102-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BTCcode-102\">[a]</a></sup> and XBT.<sup id=\"cite_ref-XBTcode_106-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-XBTcode-106\">[b]</a></sup><sup id=\"cite_ref-btcregs_107-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-btcregs-107\">[101]</a></sup><sup class=\"reference\">:<span>2</span></sup> Its <a href=\"https://en.wikipedia.org/wiki/Unicode\">Unicode</a> character is &#x20BF;.<sup id=\"cite_ref-unicode-10_1-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-unicode-10-1\">[1]</a></sup> Small amounts of bitcoin used as alternative units are millibitcoin (mBTC), and <i>satoshi</i> (sat). Named in homage to bitcoin&apos;s creator, a <i>satoshi</i> is the smallest amount within bitcoin representing <span class=\"frac\"><span class=\"num\">1</span>&#x2044;<span class=\"den\"><span class=\"nowrap\"><span></span>100<span>000</span><span>000</span></span></span></span> bitcoins, one hundred millionth of a bitcoin.<sup id=\"cite_ref-satoshi_unit_4-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-satoshi_unit-4\">[2]</a></sup> A millibitcoin equals <span class=\"frac\"><span class=\"num\">1</span>&#x2044;<span class=\"den\">1000</span></span> bitcoins; one thousandth of a bitcoin or 100,000 <i>satoshis</i>.<sup id=\"cite_ref-108\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-108\">[102]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Blockchain\">Blockchain</span></h3>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_Block_Data.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Bitcoin_Block_Data.png/220px-Bitcoin_Block_Data.png\" width=\"220\" height=\"85\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Bitcoin_Block_Data.png/330px-Bitcoin_Block_Data.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Bitcoin_Block_Data.png/440px-Bitcoin_Block_Data.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_Block_Data.png\" class=\"internal\"></a></div>Data structure of blocks in the ledger.</div></div></div>\\n' +\n    '<div class=\"thumb tmulti tright\"><div class=\"thumbinner\"><div class=\"trow\"><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:BTC_number_of_transactions_per_month.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/BTC_number_of_transactions_per_month.svg/200px-BTC_number_of_transactions_per_month.svg.png\" width=\"200\" height=\"113\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/BTC_number_of_transactions_per_month.svg/300px-BTC_number_of_transactions_per_month.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/BTC_number_of_transactions_per_month.svg/400px-BTC_number_of_transactions_per_month.svg.png 2x\"></a></div><div class=\"thumbcaption\">Number of bitcoin transactions per month, semilogarithmic plot<sup id=\"cite_ref-Blockchair.com_109-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchair.com-109\">[103]</a></sup></div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Utxo-count.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Utxo-count.svg/200px-Utxo-count.svg.png\" width=\"200\" height=\"113\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Utxo-count.svg/300px-Utxo-count.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Utxo-count.svg/400px-Utxo-count.svg.png 2x\"></a></div><div class=\"thumbcaption\">Number of <a href=\"https://en.wikipedia.org/wiki/Unspent_transaction_output\">unspent transaction outputs</a><sup id=\"cite_ref-Blockchain.info_110-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchain.info-110\">[104]</a></sup></div></div></div></div></div>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">For broader coverage of this topic, see <a href=\"https://en.wikipedia.org/wiki/Blockchain\">Blockchain</a>.</div>\\n' +\n    '<p>The bitcoin <a href=\"https://en.wikipedia.org/wiki/Blockchain\">blockchain</a> is a public <a href=\"https://en.wikipedia.org/wiki/Ledger\">ledger</a> that records bitcoin transactions.<sup id=\"cite_ref-econbc_111-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econbc-111\">[105]</a></sup> It is implemented as a chain of <i>blocks</i>, each block containing a hash of the previous block up to the genesis block<sup id=\"cite_ref-112\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-112\">[c]</a></sup> of the chain. A <a href=\"https://en.wikipedia.org/wiki/Computer_network\">network</a> of communicating nodes running bitcoin software maintains the blockchain.<sup id=\"cite_ref-JEP_39-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup><sup class=\"reference\">:<span>215&#x2013;219</span></sup> Transactions of the form <i>payer X sends Y bitcoins to payee Z</i> are <a href=\"https://en.wikipedia.org/wiki/Broadcasting_(networking)\">broadcast</a> to this network using readily available software applications.\\n' +\n    '</p><p>Network nodes can validate transactions, add them to their copy of the ledger, and then broadcast these ledger additions to other nodes. To achieve independent verification of the chain of ownership each network node stores its own copy of the blockchain.<sup id=\"cite_ref-f_c2_113-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-f_c2-113\">[106]</a></sup> At varying intervals of time averaging to every 10 minutes, a new group of accepted transactions, called a block, is created, added to the blockchain, and quickly published to all nodes, without requiring central oversight. This allows bitcoin software to determine when a particular bitcoin was spent, which is needed to prevent <a href=\"https://en.wikipedia.org/wiki/Double-spending\">double-spending</a>. A conventional ledger records the transfers of actual <a href=\"https://en.wikipedia.org/wiki/Banknote\">bills</a> or <a href=\"https://en.wikipedia.org/wiki/Promissory_note\">promissory notes</a> that exist apart from it, but the blockchain is the only place that bitcoins can be said to exist in the form of <a href=\"https://en.wikipedia.org/wiki/Unspent_outputs_of_transactions\" class=\"mw-redirect\">unspent outputs of transactions</a>.<sup id=\"cite_ref-Antonopoulos2014_9-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 5</span></sup>\\n' +\n    '</p><p>Individual blocks, public addresses and transactions within blocks can be examined using a blockchain explorer.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Supply\">Supply</span></h3>\\n' +\n    '<table class=\"box-More_citations_needed_section plainlinks metadata ambox ambox-content ambox-Refimprove\"><tbody><tr><td class=\"mbox-image\"><div><a href=\"https://en.wikipedia.org/wiki/File:Question_book-new.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/50px-Question_book-new.svg.png\" width=\"50\" height=\"39\" srcset=\"https://upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/75px-Question_book-new.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/en/thumb/9/99/Question_book-new.svg/100px-Question_book-new.svg.png 2x\"></a></div></td><td class=\"mbox-text\"><div class=\"mbox-text-span\">This section <b>needs additional citations for <a href=\"https://en.wikipedia.org/wiki/Wikipedia:Verifiability\">verification</a></b>.<span class=\"hide-when-compact\"> Please help <a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">improve this article</a> by <a href=\"https://en.wikipedia.org/wiki/Help:Referencing_for_beginners\">adding citations to reliable sources</a>. Unsourced material may be challenged and removed.</span>  <small class=\"date-container\"><i>(<span class=\"date\">May 2021</span>)</i></small><small class=\"hide-when-compact\"><i> (<a href=\"https://en.wikipedia.org/wiki/Help:Maintenance_template_removal\">Learn how and when to remove this template message</a>)</i></small></div></td></tr></tbody></table><div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Total-bitcoins.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Total-bitcoins.svg/220px-Total-bitcoins.svg.png\" width=\"220\" height=\"124\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Total-bitcoins.svg/330px-Total-bitcoins.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Total-bitcoins.svg/440px-Total-bitcoins.svg.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Total-bitcoins.svg\" class=\"internal\"></a></div>Total bitcoins in circulation.<sup id=\"cite_ref-Blockchain.info_110-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchain.info-110\">[104]</a></sup></div></div></div>\\n' +\n    '<p>The successful miner finding the new block is allowed by the rest of the network to reward themselves with newly created bitcoins and transaction fees.<sup id=\"cite_ref-bloombergvance111413_114-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bloombergvance111413-114\">[107]</a></sup> As of 11&#xA0;May&#xA0;2020<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>,<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> the reward amounted to 6.25 newly created bitcoins per block added to the blockchain,<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> plus any transaction fees from payments processed by the block. To mine half of the supply of bitcoins took four years but the remainder will take another 120 years, because of an artificial process called &quot;bitcoin halving&quot; according to which miners are compensated by fewer BTC as time goes on.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> To claim the reward, a special transaction called a <i>coinbase</i> is included with the processed payments.<sup id=\"cite_ref-Antonopoulos2014_9-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup> All bitcoins in existence have been created in such coinbase transactions. The <a href=\"https://en.wikipedia.org/wiki/Bitcoin_protocol\" class=\"mw-redirect\">bitcoin protocol</a> specifies that the reward for adding a block will be halved every 210,000 blocks (approximately every four years). Eventually, the reward will decrease to zero, and the limit of 21 million bitcoins<sup id=\"cite_ref-115\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-115\">[d]</a></sup> will be reached <abbr>c.</abbr> 2140; the record keeping will then be rewarded solely by transaction fees.<sup id=\"cite_ref-KWY_116-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-KWY-116\">[108]</a></sup>\\n' +\n    '</p><p>In other words, Nakamoto set a <a href=\"https://en.wikipedia.org/wiki/Monetary_policy\">monetary policy</a> based on <a href=\"https://en.wikipedia.org/wiki/Artificial_scarcity\">artificial scarcity</a> at bitcoin&apos;s inception that the total number of bitcoins could never exceed 21&#xA0;million. New bitcoins are created roughly every ten minutes and the rate at which they are generated drops by half about every four years until all will be in <a href=\"https://en.wikipedia.org/wiki/Circulation_(currency)\" class=\"mw-redirect\">circulation</a>.<sup id=\"cite_ref-117\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-117\">[109]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Transactions\">Transactions</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">See also: <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network\">Bitcoin network</a></div>\\n' +\n    '<p>Transactions are defined using a <a href=\"https://en.wikipedia.org/wiki/Forth_(programming_language)\">Forth</a>-like scripting language.<sup id=\"cite_ref-Antonopoulos2014_9-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 5</span></sup> Transactions consist of one or more <i>inputs</i> and one or more <i>outputs</i>. When a user sends bitcoins, the user designates each address and the amount of bitcoin being sent to that address in an output. To prevent double spending, each input must refer to a previous unspent output in the blockchain.<sup id=\"cite_ref-EconOfBTC_118-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-EconOfBTC-118\">[110]</a></sup> The use of multiple inputs corresponds to the use of multiple coins in a cash transaction. Since transactions can have multiple outputs, users can send bitcoins to multiple recipients in one transaction. As in a cash transaction, the sum of inputs (coins used to pay) can exceed the intended sum of payments. In such a case, an additional output is used, returning the change back to the payer.<sup id=\"cite_ref-EconOfBTC_118-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-EconOfBTC-118\">[110]</a></sup> Any input <i>satoshis</i> not accounted for in the transaction outputs become the transaction fee.<sup id=\"cite_ref-EconOfBTC_118-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-EconOfBTC-118\">[110]</a></sup>\\n' +\n    '</p><p>Though transaction fees are optional, miners can choose which transactions to process and prioritize those that pay higher fees.<sup id=\"cite_ref-EconOfBTC_118-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-EconOfBTC-118\">[110]</a></sup> Miners may choose transactions based on the fee paid relative to their storage size, not the absolute amount of money paid as a fee. These fees are generally measured in <i>satoshis per byte (sat/b)</i>. The size of transactions is dependent on the number of inputs used to create the transaction, and the number of outputs.<sup id=\"cite_ref-Antonopoulos2014_9-6\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup>\\n' +\n    '</p><p>The blocks in the blockchain were originally limited to 32 <a href=\"https://en.wikipedia.org/wiki/Megabyte\">megabytes</a> in size. The block size limit of one <a href=\"https://en.wikipedia.org/wiki/Megabyte\">megabyte</a> was introduced by Satoshi Nakamoto in 2010. Eventually the block size limit of one megabyte created <a href=\"https://en.wikipedia.org/wiki/Bitcoin_scalability_problem\">problems</a> for transaction processing, such as increasing transaction fees and delayed processing of transactions.<sup id=\"cite_ref-119\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-119\">[111]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Andreas_Antonopoulos\">Andreas Antonopoulos</a> has stated <a href=\"https://en.wikipedia.org/wiki/Lightning_Network\">Lightning Network</a> is a potential scaling solution and referred to lightning as a second layer routing network.<sup id=\"cite_ref-Antonopoulos2014_9-7\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Ownership\">Ownership</span></h3>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_Transaction_Visual.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Bitcoin_Transaction_Visual.svg/220px-Bitcoin_Transaction_Visual.svg.png\" width=\"220\" height=\"138\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Bitcoin_Transaction_Visual.svg/330px-Bitcoin_Transaction_Visual.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Bitcoin_Transaction_Visual.svg/440px-Bitcoin_Transaction_Visual.svg.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_Transaction_Visual.svg\" class=\"internal\"></a></div>Simplified chain of ownership as illustrated in the bitcoin whitepaper.<sup id=\"cite_ref-paper_6-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-paper-6\">[4]</a></sup> In practice, a transaction can have more than one input and more than one output.<sup id=\"cite_ref-EconOfBTC_118-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-EconOfBTC-118\">[110]</a></sup></div></div></div>\\n' +\n    '<p>In the blockchain, bitcoins are registered to bitcoin addresses. Creating a bitcoin address requires nothing more than picking a random valid private key and computing the corresponding bitcoin address. This computation can be done in a split second. But the reverse, computing the private key of a given bitcoin address, is practically unfeasible.<sup id=\"cite_ref-Antonopoulos2014_9-8\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 4</span></sup> Users can tell others or make public a bitcoin address without compromising its corresponding private key. Moreover, the number of valid private keys is so vast that it is extremely unlikely someone will compute a key-pair that is already in use and has funds. The vast number of valid private keys makes it unfeasible that brute force could be used to compromise a private key. To be able to spend their bitcoins, the owner must know the corresponding <a href=\"https://en.wikipedia.org/wiki/Private_key\" class=\"mw-redirect\">private key</a> and <a href=\"https://en.wikipedia.org/wiki/Digital_signature\">digitally sign</a> the transaction. The network verifies the signature using the <a href=\"https://en.wikipedia.org/wiki/Public_key\" class=\"mw-redirect\">public key</a>; the private key is never revealed.<sup id=\"cite_ref-Antonopoulos2014_9-9\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 5</span></sup>\\n' +\n    '</p><p>If the private key is lost, the <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network\">bitcoin network</a> will not recognize any other evidence of ownership;<sup id=\"cite_ref-JEP_39-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup> the coins are then unusable, and effectively lost. For example, in 2013 one user claimed to have lost 7,500 bitcoins, worth $7.5 million at the time, when he accidentally discarded a hard drive containing his private key.<sup id=\"cite_ref-120\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-120\">[112]</a></sup> About 20% of all bitcoins are believed to be lost -they would have had a market value of about $20 billion at July 2018 prices.<sup id=\"cite_ref-wsjlost_121-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-wsjlost-121\">[113]</a></sup>\\n' +\n    '</p><p>To ensure the security of bitcoins, the private key must be kept secret.<sup id=\"cite_ref-Antonopoulos2014_9-10\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 10</span></sup> If the private key is revealed to a third party, e.g. through a <a href=\"https://en.wikipedia.org/wiki/Data_breach\">data breach</a>, the third party can use it to <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_and_security#Bitcoin\" class=\"mw-redirect\">steal any associated bitcoins</a>.<sup id=\"cite_ref-122\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-122\">[114]</a></sup> As of December&#xA0;2017<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, around 980,000 bitcoins have been stolen from <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_exchange\">cryptocurrency exchanges</a>.<sup id=\"cite_ref-harney_123-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-harney-123\">[115]</a></sup>\\n' +\n    '</p><p>Regarding ownership distribution, as of 16 March 2018, 0.5% of bitcoin wallets own 87% of all bitcoins ever mined.<sup id=\"cite_ref-124\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-124\">[116]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Mining\">Mining</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">See also: <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network#Mining\">Bitcoin network &#xA7;&#xA0;Mining</a></div>\\n' +\n    '<div class=\"thumb tmulti tright\"><div class=\"thumbinner\"><div class=\"trow\"><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Minage_de_crypto-monnaie_(2).jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Minage_de_crypto-monnaie_%282%29.jpg/137px-Minage_de_crypto-monnaie_%282%29.jpg\" width=\"137\" height=\"103\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Minage_de_crypto-monnaie_%282%29.jpg/206px-Minage_de_crypto-monnaie_%282%29.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Minage_de_crypto-monnaie_%282%29.jpg/274px-Minage_de_crypto-monnaie_%282%29.jpg 2x\"></a></div><div class=\"thumbcaption\">Early bitcoin miners used <a href=\"https://en.wikipedia.org/wiki/Graphics_processing_unit\">GPUs</a> for mining, as they were better suited to the <a href=\"https://en.wikipedia.org/wiki/Proof-of-work\" class=\"mw-redirect\">proof-of-work</a> algorithm than <a href=\"https://en.wikipedia.org/wiki/Central_processing_unit\">CPUs</a>.<sup id=\"cite_ref-125\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-125\">[117]</a></sup></div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:USB_Erupter.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/USB_Erupter.jpg/139px-USB_Erupter.jpg\" width=\"139\" height=\"103\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/USB_Erupter.jpg/209px-USB_Erupter.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/USB_Erupter.jpg/278px-USB_Erupter.jpg 2x\"></a></div><div class=\"thumbcaption\">Later amateurs mined bitcoins with specialized <a href=\"https://en.wikipedia.org/wiki/Field-programmable_gate_array\">FPGA</a> and <a href=\"https://en.wikipedia.org/wiki/Application-specific_integrated_circuit\">ASIC</a> chips. The chips pictured have become obsolete due to increasing difficulty.</div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Cryptocurrency_Mining_Farm.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Cryptocurrency_Mining_Farm.jpg/183px-Cryptocurrency_Mining_Farm.jpg\" width=\"183\" height=\"103\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Cryptocurrency_Mining_Farm.jpg/275px-Cryptocurrency_Mining_Farm.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Cryptocurrency_Mining_Farm.jpg/366px-Cryptocurrency_Mining_Farm.jpg 2x\"></a></div><div class=\"thumbcaption\">Today, bitcoin mining companies dedicate facilities to housing and operating large amounts of high-performance mining hardware.<sup id=\"cite_ref-126\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-126\">[118]</a></sup></div></div></div></div></div>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:History_of_Bitcoin_difficulty.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/History_of_Bitcoin_difficulty.svg/220px-History_of_Bitcoin_difficulty.svg.png\" width=\"220\" height=\"124\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/History_of_Bitcoin_difficulty.svg/330px-History_of_Bitcoin_difficulty.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/History_of_Bitcoin_difficulty.svg/440px-History_of_Bitcoin_difficulty.svg.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:History_of_Bitcoin_difficulty.svg\" class=\"internal\"></a></div><a href=\"https://en.wikipedia.org/wiki/Semi-log_plot\">Semi-log plot</a> of relative mining difficulty<sup id=\"cite_ref-127\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-127\">[e]</a></sup><sup id=\"cite_ref-Blockchain.info_110-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchain.info-110\">[104]</a></sup></div></div></div>\\n' +\n    '<p><i>Mining</i> is a record-keeping service done through the use of computer <a href=\"https://en.wikipedia.org/wiki/Processing_power\" class=\"mw-redirect\">processing power</a>.<sup id=\"cite_ref-129\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-129\">[f]</a></sup> Miners keep the blockchain consistent, complete, and unalterable by repeatedly grouping newly broadcast transactions into a <i>block</i>, which is then broadcast to the network and verified by recipient nodes.<sup id=\"cite_ref-econbc_111-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econbc-111\">[105]</a></sup> Each block contains a <a href=\"https://en.wikipedia.org/wiki/SHA-256\" class=\"mw-redirect\">SHA-256</a> <a href=\"https://en.wikipedia.org/wiki/Cryptographic_hash\" class=\"mw-redirect\">cryptographic hash</a> of the previous block,<sup id=\"cite_ref-econbc_111-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econbc-111\">[105]</a></sup> thus linking it to the previous block and giving the blockchain its name.<sup id=\"cite_ref-Antonopoulos2014_9-11\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 7</span></sup><sup id=\"cite_ref-econbc_111-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econbc-111\">[105]</a></sup>\\n' +\n    '</p><p>To be accepted by the rest of the network, a new block must contain a <i><a href=\"https://en.wikipedia.org/wiki/Proof-of-work_system#Bitcoin-type_proof_of_work\" class=\"mw-redirect\">proof-of-work</a></i> (PoW).<sup id=\"cite_ref-econbc_111-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econbc-111\">[105]</a></sup> The system used is based on <a href=\"https://en.wikipedia.org/wiki/Adam_Back\">Adam Back</a>&apos;s 1997 anti-<a href=\"https://en.wikipedia.org/wiki/Email_spam\">spam</a> scheme, <a href=\"https://en.wikipedia.org/wiki/Hashcash\">Hashcash</a>.<sup id=\"cite_ref-130\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-130\">[120]</a></sup><sup class=\"noprint Inline-Template\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Verifiability\"><span>failed verification</span></a></i>]</sup><sup id=\"cite_ref-paper_6-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-paper-6\">[4]</a></sup> The PoW requires miners to find a number called a <i><a href=\"https://en.wikipedia.org/wiki/Cryptographic_nonce\">nonce</a></i>, such that when the block content is <a href=\"https://en.wikipedia.org/wiki/Cryptographic_hash\" class=\"mw-redirect\">hashed</a> along with the nonce, the result is numerically smaller than the network&apos;s difficulty target.<sup id=\"cite_ref-Antonopoulos2014_9-12\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup> This proof is easy for any node in the network to verify, but extremely time-consuming to generate, as for a secure cryptographic hash, miners must try many different nonce values (usually the sequence of tested values is the ascending natural numbers: 0, 1, 2, 3, ...<sup id=\"cite_ref-Antonopoulos2014_9-13\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup>) before meeting the difficulty target.\\n' +\n    '</p><p>Every 2,016 blocks (approximately 14 days at roughly 10 min per block), the difficulty target is adjusted based on the network&apos;s recent performance, with the aim of keeping the average time between new blocks at ten minutes. In this way the system automatically adapts to the total amount of mining power on the network.<sup id=\"cite_ref-Antonopoulos2014_9-14\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference\">:<span>ch. 8</span></sup> Between 1 March 2014 and 1 March 2015, the average number of nonces miners had to try before creating a new block increased from 16.4 quintillion to 200.5 quintillion.<sup id=\"cite_ref-diffhistory_131-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-diffhistory-131\">[121]</a></sup>\\n' +\n    '</p><p>The proof-of-work system, alongside the chaining of blocks, makes modifications of the blockchain extremely hard, as an attacker must modify all subsequent blocks in order for the modifications of one block to be accepted.<sup id=\"cite_ref-132\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-132\">[122]</a></sup> As new blocks are mined all the time, the difficulty of modifying a block increases as time passes and the number of subsequent blocks (also called <i>confirmations</i> of the given block) increases.<sup id=\"cite_ref-econbc_111-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econbc-111\">[105]</a></sup>\\n' +\n    '</p><p>Computing power is often bundled together by a <a href=\"https://en.wikipedia.org/wiki/Mining_pool\">Mining pool</a> to reduce variance in miner income. Individual mining rigs often have to wait for long periods to confirm a block of transactions and receive payment. In a pool, all participating miners get paid every time a participating server solves a block. This payment depends on the amount of work an individual miner contributed to help find that block.<sup id=\"cite_ref-Techcrunch12_133-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Techcrunch12-133\">[123]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Wallets\">Wallets</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">For broader coverage of this topic, see <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_wallet\">Cryptocurrency wallet</a>.</div>\\n' +\n    '<div class=\"thumb tmulti tright\"><div class=\"thumbinner\"><div class=\"trow\"><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Screenshot_of_Bitcoin-qt-0.5.2.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Screenshot_of_Bitcoin-qt-0.5.2.png/191px-Screenshot_of_Bitcoin-qt-0.5.2.png\" width=\"191\" height=\"117\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Screenshot_of_Bitcoin-qt-0.5.2.png/287px-Screenshot_of_Bitcoin-qt-0.5.2.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Screenshot_of_Bitcoin-qt-0.5.2.png/382px-Screenshot_of_Bitcoin-qt-0.5.2.png 2x\"></a></div><div class=\"thumbcaption\">Bitcoin Core, a full client</div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Electrum_Bitcoin_Wallet.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Electrum_Bitcoin_Wallet.png/209px-Electrum_Bitcoin_Wallet.png\" width=\"209\" height=\"117\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/Electrum_Bitcoin_Wallet.png/314px-Electrum_Bitcoin_Wallet.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/1/16/Electrum_Bitcoin_Wallet.png 2x\"></a></div><div class=\"thumbcaption\">Electrum, a lightweight client</div></div></div></div></div>\\n' +\n    '<p>The first wallet program, simply named <i>Bitcoin</i>, and sometimes referred to as the <i>Satoshi client</i>, was released in 2009 by Satoshi Nakamoto as <a href=\"https://en.wikipedia.org/wiki/Open-source_software\">open-source software</a>.<sup id=\"cite_ref-NY2011_13-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NY2011-13\">[9]</a></sup> In version 0.5 the client moved from the <a href=\"https://en.wikipedia.org/wiki/WxWidgets\">wxWidgets</a> user interface toolkit to <a href=\"https://en.wikipedia.org/wiki/Qt_(software)\">Qt</a>, and the whole bundle was referred to as <i>Bitcoin-Qt</i>.<sup id=\"cite_ref-Bitcoin_Clients_134-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Bitcoin_Clients-134\">[124]</a></sup> After the release of version 0.9, the software bundle was renamed <i>Bitcoin Core</i> to distinguish itself from the underlying network.<sup id=\"cite_ref-135\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-135\">[125]</a></sup><sup id=\"cite_ref-136\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-136\">[126]</a></sup> Bitcoin Core is, perhaps, the best known implementation or client. Alternative clients (<a href=\"https://en.wikipedia.org/wiki/Fork_(software_development)\">forks</a> of Bitcoin Core) exist, such as <a href=\"https://en.wikipedia.org/wiki/Bitcoin_XT\" class=\"mw-redirect\">Bitcoin XT</a>, <a href=\"https://en.wikipedia.org/wiki/Bitcoin_Unlimited\">Bitcoin Unlimited</a>,<sup id=\"cite_ref-breakingup_38-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-breakingup-38\">[34]</a></sup> and Parity Bitcoin.<sup id=\"cite_ref-137\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-137\">[127]</a></sup>\\n' +\n    'List of bitcoin forks\\n' +\n    '</p><p>A wallet stores the information necessary to transact bitcoins. While wallets are often described as a place to hold<sup id=\"cite_ref-138\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-138\">[128]</a></sup> or store bitcoins, due to the nature of the system, bitcoins are inseparable from the blockchain transaction ledger. A wallet is more correctly defined as something that &quot;stores the digital credentials for your bitcoin holdings&quot; and allows one to access (and spend) them.<sup id=\"cite_ref-Antonopoulos2014_9-15\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1, glossary</span></sup> Bitcoin uses <a href=\"https://en.wikipedia.org/wiki/Public-key_cryptography\">public-key cryptography</a>, in which two cryptographic keys, one public and one private, are generated.<sup id=\"cite_ref-Economist113013Pressure_139-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Economist113013Pressure-139\">[129]</a></sup> At its most basic, a wallet is a collection of these keys.\\n' +\n    '</p><p>There are several modes which wallets can operate in. They have an inverse relationship with regards to trustlessness and computational requirements.\\n' +\n    '</p>\\n' +\n    '<ul><li><i>Full clients</i> verify transactions directly by downloading a full copy of the blockchain (over 150&#xA0;GB as of January&#xA0;2018<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>).<sup id=\"cite_ref-140\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-140\">[130]</a></sup> They are the most secure and reliable way of using the network, as trust in external parties is not required. Full clients check the validity of mined blocks, preventing them from transacting on a chain that breaks or alters network rules.<sup id=\"cite_ref-Antonopoulos2014_9-16\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1</span></sup> Because of its size and complexity, downloading and verifying the entire blockchain is not suitable for all computing devices.</li>\\n' +\n    '<li><i>Lightweight clients</i> consult full nodes to send and receive transactions without requiring a local copy of the entire blockchain (see <i><a href=\"https://en.wikipedia.org/wiki/Bitcoin_network#Payment_verification\">simplified payment verification</a></i> &#x2013; <i>SPV</i>). This makes lightweight clients much faster to set up and allows them to be used on low-power, low-bandwidth devices such as smartphones. When using a lightweight wallet, however, the user must trust full nodes, as it can report faulty values back to the user. Lightweight clients follow the longest blockchain and do not ensure it is valid, requiring trust in full nodes.<sup id=\"cite_ref-LBC_141-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-LBC-141\">[131]</a></sup></li></ul>\\n' +\n    '<p>Third-party internet services called <i>online wallets</i> offer similar functionality but may be easier to use. In this case, credentials to access funds are stored with the online wallet provider rather than on the user&apos;s hardware.<sup id=\"cite_ref-142\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-142\">[132]</a></sup> As a result, the user must have complete trust in the online wallet provider. A malicious provider or a breach in server security may cause entrusted bitcoins to be stolen. An example of such a security breach occurred with Mt. Gox in 2011.<sup id=\"cite_ref-mtgoxdetails_143-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-mtgoxdetails-143\">[133]</a></sup>\\n' +\n    '</p>\\n' +\n    '<div class=\"thumb tmulti tright\"><div class=\"thumbinner\"><div class=\"trow\"><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_paper_wallet_generated_at_bitaddress.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Bitcoin_paper_wallet_generated_at_bitaddress.jpg/195px-Bitcoin_paper_wallet_generated_at_bitaddress.jpg\" width=\"195\" height=\"104\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Bitcoin_paper_wallet_generated_at_bitaddress.jpg/293px-Bitcoin_paper_wallet_generated_at_bitaddress.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Bitcoin_paper_wallet_generated_at_bitaddress.jpg/390px-Bitcoin_paper_wallet_generated_at_bitaddress.jpg 2x\"></a></div><div class=\"thumbcaption\">A paper wallet with a <a href=\"https://en.wikipedia.org/wiki/Banknote\">banknote</a>-like design. Both the private key and the address are visible in <a href=\"https://en.wikipedia.org/wiki/Human-readable_medium\">text form</a> and as <a href=\"https://en.wikipedia.org/wiki/2D_barcode\" class=\"mw-redirect\">2D barcodes</a>.</div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Sample_Bitcoin_paper_wallet.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Sample_Bitcoin_paper_wallet.png/205px-Sample_Bitcoin_paper_wallet.png\" width=\"205\" height=\"104\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Sample_Bitcoin_paper_wallet.png/308px-Sample_Bitcoin_paper_wallet.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/a/ab/Sample_Bitcoin_paper_wallet.png 2x\"></a></div><div class=\"thumbcaption\">A paper wallet with the address visible for adding or checking stored funds. The part of the page containing the private key is folded over and sealed.</div></div></div><div class=\"trow\"><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Casascius_coin.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Casascius_coin.jpg/171px-Casascius_coin.jpg\" width=\"171\" height=\"129\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Casascius_coin.jpg/257px-Casascius_coin.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/Casascius_coin.jpg/342px-Casascius_coin.jpg 2x\"></a></div><div class=\"thumbcaption\">A brass <a href=\"https://en.wikipedia.org/wiki/Token_coin\">token</a> with a private key hidden beneath a <a href=\"https://en.wikipedia.org/wiki/Tamper-evident_technology#Seals_and_signatures\">tamper-evident</a> <a href=\"https://en.wikipedia.org/wiki/Security_hologram\">security hologram</a>. A part of the address is visible through a transparent part of the hologram.</div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:10elqpi.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/10elqpi.jpg/229px-10elqpi.jpg\" width=\"229\" height=\"129\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/10elqpi.jpg/344px-10elqpi.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/10elqpi.jpg/458px-10elqpi.jpg 2x\"></a></div><div class=\"thumbcaption\">A hardware wallet <a href=\"https://en.wikipedia.org/wiki/Peripheral\">peripheral</a> which processes bitcoin payments without exposing any credentials to the computer.</div></div></div></div></div>\\n' +\n    '<p>Physical wallets store the credentials necessary to spend bitcoins offline and can be as simple as a paper printout of the private key:<sup id=\"cite_ref-Antonopoulos2014_9-17\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 10</span></sup> a <i>paper wallet</i> or more advanced such as a <i>hardware wallet</i>. A paper wallet is created with a keypair generated on a <a href=\"https://en.wikipedia.org/wiki/Air_gap_(networking)\">computer with no internet connection</a>; the private key is written or printed onto the paper<sup id=\"cite_ref-144\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-144\">[g]</a></sup> and then erased from the computer. The paper wallet can then be stored in a safe physical location for later retrieval. Bitcoins stored using a paper wallet are said to be in <i>cold storage</i>.<sup id=\"cite_ref-befuddled_145-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-befuddled-145\">[134]</a></sup><sup class=\"reference\">:<span>39</span></sup>\\n' +\n    '</p><p><a href=\"https://en.wikipedia.org/wiki/Cameron_Winklevoss\">Cameron</a> and <a href=\"https://en.wikipedia.org/wiki/Tyler_Winklevoss\">Tyler Winklevoss</a>, the founders of the <a href=\"https://en.wikipedia.org/wiki/Gemini_(company)\">Gemini Trust Co.</a> exchange, reported that they had cut their paper wallets into pieces and stored them in envelopes distributed to safe deposit boxes across the United States.<sup id=\"cite_ref-146\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-146\">[135]</a></sup> Through this system, the theft of one envelope would neither allow the thief to steal any bitcoins nor deprive the rightful owners of their access to them.<sup id=\"cite_ref-alexander_147-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-alexander-147\">[136]</a></sup>\\n' +\n    '</p><p>Physical wallets can also take the form of metal <a href=\"https://en.wikipedia.org/wiki/Token_coin\">token coins</a><sup id=\"cite_ref-theverge_148-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-theverge-148\">[137]</a></sup> with a private key accessible under a <a href=\"https://en.wikipedia.org/wiki/Security_hologram\">security hologram</a> in a recess struck on the <a href=\"https://en.wikipedia.org/wiki/Obverse_and_reverse\">reverse side</a>.<sup id=\"cite_ref-Ahonen2016_149-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ahonen2016-149\">[138]</a></sup><sup class=\"reference\">:<span>38</span></sup> The security hologram <a href=\"https://en.wikipedia.org/wiki/Tamper-evident_technology\">self-destructs when removed</a> from the token, showing that the private key has been accessed.<sup id=\"cite_ref-150\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-150\">[139]</a></sup> Originally, these tokens were struck in brass and other <a href=\"https://en.wikipedia.org/wiki/Base_metal\">base metals</a>, but later used <a href=\"https://en.wikipedia.org/wiki/Precious_metal\">precious metals</a> as bitcoin grew in value and popularity.<sup id=\"cite_ref-Ahonen2016_149-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ahonen2016-149\">[138]</a></sup><sup class=\"reference nowrap\">:<span>80</span></sup> Coins with stored face value as high as &#x20BF;1000 have been struck in gold.<sup id=\"cite_ref-Ahonen2016_149-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ahonen2016-149\">[138]</a></sup><sup class=\"reference nowrap\">:<span>102&#x2013;104</span></sup> The <a href=\"https://en.wikipedia.org/wiki/British_Museum\">British Museum</a>&apos;s <a href=\"https://en.wikipedia.org/wiki/British_Museum_Department_of_Coins_and_Medals\">coin collection</a> includes four specimens from the earliest series<sup id=\"cite_ref-Ahonen2016_149-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ahonen2016-149\">[138]</a></sup><sup class=\"reference nowrap\">:<span>83</span></sup> of funded bitcoin tokens; one is currently on display in the museum&apos;s money gallery.<sup id=\"cite_ref-151\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-151\">[140]</a></sup> In 2013, a <a href=\"https://en.wikipedia.org/wiki/Utah\">Utahn</a> manufacturer of these tokens was ordered by the <a href=\"https://en.wikipedia.org/wiki/Financial_Crimes_Enforcement_Network\">Financial Crimes Enforcement Network</a> (FinCEN) to register as a <a href=\"https://en.wikipedia.org/wiki/Money_services_business\">money services business</a> before producing any more funded bitcoin tokens.<sup id=\"cite_ref-theverge_148-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-theverge-148\">[137]</a></sup><sup id=\"cite_ref-Ahonen2016_149-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ahonen2016-149\">[138]</a></sup><sup class=\"reference nowrap\">:<span>80</span></sup>\\n' +\n    '</p><p>Another type of physical wallet called a <i>hardware wallet</i> keeps credentials offline while facilitating transactions.<sup id=\"cite_ref-152\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-152\">[141]</a></sup> The hardware wallet acts as a computer <a href=\"https://en.wikipedia.org/wiki/Peripheral\">peripheral</a> and signs transactions as requested by the user, who must press a button on the wallet to confirm that they intended to make the transaction. Hardware wallets never expose their private keys, keeping bitcoins in cold storage even when used with computers that may be compromised by malware.<sup id=\"cite_ref-befuddled_145-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-befuddled-145\">[134]</a></sup><sup class=\"reference nowrap\">:<span>42&#x2013;45</span></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Decentralization\">Decentralization</span></h3>\\n' +\n    '<p>Bitcoin is decentralized thus:<sup id=\"cite_ref-JSC_11-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JSC-11\">[7]</a></sup>\\n' +\n    '</p>\\n' +\n    '<ul><li>Bitcoin does not have a central authority.<sup id=\"cite_ref-JSC_11-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JSC-11\">[7]</a></sup></li>\\n' +\n    '<li>There is no central server; the bitcoin network is peer-to-peer.<sup id=\"cite_ref-NY2011_13-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NY2011-13\">[9]</a></sup></li>\\n' +\n    '<li>There is no central storage; the bitcoin ledger is distributed.<sup id=\"cite_ref-DLT_153-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-DLT-153\">[142]</a></sup></li>\\n' +\n    '<li>The ledger is public; anybody can store it on their computer.<sup id=\"cite_ref-Antonopoulos2014_9-18\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1</span></sup></li>\\n' +\n    '<li>There is no single administrator;<sup id=\"cite_ref-JSC_11-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JSC-11\">[7]</a></sup> the ledger is maintained by a network of equally privileged miners.<sup id=\"cite_ref-Antonopoulos2014_9-19\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1</span></sup></li>\\n' +\n    '<li>Anybody can become a miner.<sup id=\"cite_ref-Antonopoulos2014_9-20\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1</span></sup></li>\\n' +\n    '<li>The additions to the ledger are maintained through competition. Until a new block is added to the ledger, it is not known which miner will create the block.<sup id=\"cite_ref-Antonopoulos2014_9-21\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1</span></sup></li>\\n' +\n    '<li>The issuance of bitcoins is decentralized. They are issued as a reward for the creation of a new block.<sup id=\"cite_ref-bloombergvance111413_114-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bloombergvance111413-114\">[107]</a></sup></li>\\n' +\n    '<li>Anybody can create a new bitcoin address (a bitcoin counterpart of a bank account) without needing any approval.<sup id=\"cite_ref-Antonopoulos2014_9-22\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 1</span></sup></li>\\n' +\n    '<li>Anybody can send a transaction to the network without needing any approval; the network merely confirms that the transaction is legitimate.<sup id=\"cite_ref-primer_154-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-primer-154\">[143]</a></sup><sup class=\"reference\">:<span>32</span></sup></li></ul>\\n' +\n    '<p>Conversely, researchers have pointed out at a &quot;trend towards centralization&quot;. Although bitcoin can be sent directly from user to user, in practice intermediaries are widely used.<sup id=\"cite_ref-JEP_39-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup><sup class=\"reference nowrap\">:<span>220&#x2013;222</span></sup> Bitcoin miners join large <a href=\"https://en.wikipedia.org/wiki/Mining_pool\">mining pools</a> to minimize the variance of their income.<sup id=\"cite_ref-JEP_39-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup><sup class=\"reference\">:<span>215, 219&#x2013;222</span></sup><sup id=\"cite_ref-ieeesurvey_155-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ieeesurvey-155\">[144]</a></sup><sup class=\"reference\">:<span>3</span></sup><sup id=\"cite_ref-156\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-156\">[145]</a></sup> Because transactions on the network are confirmed by miners, decentralization of the network requires that no single miner or mining pool obtains 51% of the hashing power, which would allow them to <a href=\"https://en.wikipedia.org/wiki/Double-spending\">double-spend</a> coins, prevent certain transactions from being verified and prevent other miners from earning income.<sup id=\"cite_ref-:0_157-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-:0-157\">[146]</a></sup> As of 2013<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup> just six mining pools controlled 75% of overall bitcoin hashing power.<sup id=\"cite_ref-:0_157-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-:0-157\">[146]</a></sup> In 2014 mining pool <a href=\"https://en.wikipedia.org/wiki/Ghash.io\" class=\"mw-redirect\">Ghash.io</a> obtained 51% hashing power which raised significant controversies about the safety of the network. The pool has voluntarily capped their hashing power at 39.99% and requested other pools to act responsibly for the benefit of the whole network.<sup id=\"cite_ref-158\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-158\">[147]</a></sup> Around the year 2017, over 70% of the hashing power and 90% of transactions were operating from China.<sup id=\"cite_ref-159\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-159\">[148]</a></sup>\\n' +\n    '</p><p>According to researchers, other parts of the ecosystem are also &quot;controlled by a small set of entities&quot;, notably the maintenance of the client software, online wallets and simplified payment verification (SPV) clients.<sup id=\"cite_ref-:0_157-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-:0-157\">[146]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span id=\"Privacy_.26_Fungibility\"></span><span class=\"mw-headline\" id=\"Privacy_&amp;_Fungibility\">Privacy &amp; Fungibility</span></h3>\\n' +\n    '<p>Bitcoin is <a href=\"https://en.wikipedia.org/wiki/Pseudonymous\" class=\"mw-redirect\">pseudonymous</a>, meaning that funds are not tied to real-world entities but rather bitcoin addresses. Owners of bitcoin addresses are not explicitly identified, but all transactions on the blockchain are public. In addition, transactions can be linked to individuals and companies through &quot;idioms of use&quot; (e.g., transactions that spend coins from multiple inputs indicate that the inputs may have a common owner) and corroborating public transaction data with known information on owners of certain addresses.<sup id=\"cite_ref-160\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-160\">[149]</a></sup> Additionally, bitcoin exchanges, where bitcoins are traded for traditional currencies, may be required by law to collect personal information.<sup id=\"cite_ref-5facts_161-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-5facts-161\">[150]</a></sup> To heighten financial privacy, a new bitcoin address can be generated for each transaction.<sup id=\"cite_ref-162\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-162\">[151]</a></sup>\\n' +\n    '</p><p>Wallets and similar software technically handle all bitcoins as equivalent, establishing the basic level of <a href=\"https://en.wikipedia.org/wiki/Fungibility\">fungibility</a>. Researchers have pointed out that the history of each bitcoin is registered and publicly available in the blockchain ledger, and that some users may refuse to accept bitcoins coming from controversial transactions, which would harm bitcoin&apos;s fungibility.<sup id=\"cite_ref-163\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-163\">[152]</a></sup> For example, in 2012, Mt. Gox froze accounts of users who deposited bitcoins that were known to have just been stolen.<sup id=\"cite_ref-164\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-164\">[153]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Ideology\">Ideology</span></h2>\\n' +\n    '<p>Satoshi Nakamoto stated in his white paper that: &quot;The root problem with conventional currencies is all the trust that&apos;s required to make it work. The central bank must be trusted not to debase the currency, but the history of fiat currencies is full of breaches of that trust.&quot;<sup id=\"cite_ref-BitIdeo_165-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BitIdeo-165\">[154]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Austrian_economics_roots\">Austrian economics roots</span></h3>\\n' +\n    '<p>According to the <a href=\"https://en.wikipedia.org/wiki/European_Central_Bank\">European Central Bank</a>, the decentralization of money offered by bitcoin has its theoretical roots in the <a href=\"https://en.wikipedia.org/wiki/Austrian_school_of_economics\" class=\"mw-redirect\">Austrian school of economics</a>, especially with <a href=\"https://en.wikipedia.org/wiki/Friedrich_von_Hayek\" class=\"mw-redirect\">Friedrich von Hayek</a> in his book <i>Denationalisation of Money: The Argument Refined</i>,<sup id=\"cite_ref-166\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-166\">[155]</a></sup> in which Hayek advocates a complete <a href=\"https://en.wikipedia.org/wiki/Free_market\">free market</a> in the production, distribution and management of money to end the monopoly of <a href=\"https://en.wikipedia.org/wiki/Central_banks\" class=\"mw-redirect\">central banks</a>.<sup id=\"cite_ref-ECB_167-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ECB-167\">[156]</a></sup><sup class=\"reference\">:<span>22</span></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Anarchism_and_libertarianism\">Anarchism and libertarianism</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Further information: <a href=\"https://en.wikipedia.org/wiki/Crypto-anarchism\">Crypto-anarchism</a></div>\\n' +\n    '<p>According to <i><a href=\"https://en.wikipedia.org/wiki/The_New_York_Times\">The New York Times</a></i>, <a href=\"https://en.wikipedia.org/wiki/Libertarian\" class=\"mw-redirect\">libertarians</a> and <a href=\"https://en.wikipedia.org/wiki/Anarchist\" class=\"mw-redirect\">anarchists</a> were attracted to the philosophical idea behind bitcoin. Early bitcoin supporter <a href=\"https://en.wikipedia.org/wiki/Roger_Ver\">Roger Ver</a> said: &quot;At first, almost everyone who got involved did so for philosophical reasons. We saw bitcoin as a great idea, as a way to separate money from the state.&quot;<sup id=\"cite_ref-BitIdeo_165-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BitIdeo-165\">[154]</a></sup> <i><a href=\"https://en.wikipedia.org/wiki/The_Economist\">The Economist</a></i> describes bitcoin as &quot;a techno-anarchist project to create an online version of cash, a way for people to transact without the possibility of interference from malicious governments or banks&quot;.<sup id=\"cite_ref-30082018Economist_168-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-30082018Economist-168\">[157]</a></sup> Economist <a href=\"https://en.wikipedia.org/wiki/Paul_Krugman\">Paul Krugman</a> argues that cryptocurrencies like bitcoin are &quot;something of a cult&quot; based in &quot;paranoid fantasies&quot; of government power.<sup id=\"cite_ref-Krugman_169-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Krugman-169\">[158]</a></sup>\\n' +\n    '</p>\\n' +\n    '<figure class=\"infobox\"><img alt=\"video icon\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Nuvola_apps_kaboodle.svg/16px-Nuvola_apps_kaboodle.svg.png\" width=\"16\" height=\"16\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Nuvola_apps_kaboodle.svg/24px-Nuvola_apps_kaboodle.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Nuvola_apps_kaboodle.svg/32px-Nuvola_apps_kaboodle.svg.png 2x\"><tbody><tr><th class=\"infobox-above\">External video</th></tr><tr><td class=\"infobox-full-data\"> <a class=\"external text\" href=\"https://www.youtube.com/watch?v=XQqZ9b0S0BY\">The Declaration Of Bitcoin&apos;s Independence</a>, BraveTheWorld, 4:38<sup id=\"cite_ref-DecInd_170-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-DecInd-170\">[159]</a></sup></td></tr></tbody></figure><p> Nigel Dodd argues in <i>The Social Life of Bitcoin</i> that the essence of the bitcoin ideology is to remove money from social, as well as governmental, control.<sup id=\"cite_ref-DoddLSE_171-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-DoddLSE-171\">[160]</a></sup> Dodd quotes a <a href=\"https://en.wikipedia.org/wiki/YouTube\">YouTube</a> video, with <a href=\"https://en.wikipedia.org/wiki/Roger_Ver\">Roger Ver</a>, <a href=\"https://en.wikipedia.org/wiki/Jeff_Berwick\">Jeff Berwick</a>, <a href=\"https://en.wikipedia.org/wiki/Charlie_Shrem\">Charlie Shrem</a>, <a href=\"https://en.wikipedia.org/wiki/Andreas_Antonopoulos\">Andreas Antonopoulos</a>, <a href=\"https://en.wikipedia.org/wiki/Gavin_Wood\">Gavin Wood</a>, Trace Meyer and other proponents of bitcoin reading <i>The Declaration of Bitcoin&apos;s Independence.</i> The declaration includes a message of crypto-anarchism with the words: &quot;Bitcoin is inherently anti-establishment, anti-system, and anti-state. Bitcoin undermines governments and disrupts institutions because bitcoin is fundamentally humanitarian.&quot;<sup id=\"cite_ref-DoddLSE_171-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-DoddLSE-171\">[160]</a></sup><sup id=\"cite_ref-DecInd_170-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-DecInd-170\">[159]</a></sup>\\n' +\n    '</p><p>David Golumbia says that the ideas influencing bitcoin advocates emerge from right-wing extremist movements such as the <a href=\"https://en.wikipedia.org/wiki/Liberty_Lobby\">Liberty Lobby</a> and the <a href=\"https://en.wikipedia.org/wiki/John_Birch_Society\">John Birch Society</a> and their anti-Central Bank rhetoric, or, more recently, <a href=\"https://en.wikipedia.org/wiki/Ron_Paul\">Ron Paul</a> and <a href=\"https://en.wikipedia.org/wiki/Tea_Party_movement\">Tea Party</a>-style libertarianism.<sup id=\"cite_ref-Golumbia1_172-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Golumbia1-172\">[161]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Steve_Bannon\">Steve Bannon</a>, who owns a &quot;good stake&quot; in bitcoin, considers it to be &quot;disruptive populism. It takes control back from central authorities. It&apos;s revolutionary.&quot;<sup id=\"cite_ref-NYTBannon_173-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NYTBannon-173\">[162]</a></sup>\\n' +\n    '</p><p>A 2014 study of <a href=\"https://en.wikipedia.org/wiki/Google_Trends\">Google Trends</a> data found correlations between bitcoin-related searches and ones related to computer programming and illegal activity, but not libertarianism or investment topics.<sup id=\"cite_ref-uok_174-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-uok-174\">[163]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Economics\">Economics</span></h2>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Main article: <a href=\"https://en.wikipedia.org/wiki/Economics_of_bitcoin\">Economics of bitcoin</a></div>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Estimated-transaction-volume-usd.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/Estimated-transaction-volume-usd.svg/220px-Estimated-transaction-volume-usd.svg.png\" width=\"220\" height=\"124\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/Estimated-transaction-volume-usd.svg/330px-Estimated-transaction-volume-usd.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/Estimated-transaction-volume-usd.svg/440px-Estimated-transaction-volume-usd.svg.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Estimated-transaction-volume-usd.svg\" class=\"internal\"></a></div><a href=\"https://en.wikipedia.org/wiki/Market_liquidity\">Liquidity</a>,<sup id=\"cite_ref-LinUSD_175-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-LinUSD-175\">[h]</a></sup> semilogarithmic plot.<sup id=\"cite_ref-Blockchain.info_110-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchain.info-110\">[104]</a></sup></div></div></div>\\n' +\n    '<p>Bitcoin is a <a href=\"https://en.wikipedia.org/wiki/Digital_asset\">digital asset</a> designed to work in peer-to-peer transactions as a <a href=\"https://en.wikipedia.org/wiki/Currency\">currency</a>.<sup id=\"cite_ref-paper_6-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-paper-6\">[4]</a></sup><sup id=\"cite_ref-Monetarists_176-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Monetarists-176\">[164]</a></sup> Bitcoins have three qualities useful in a currency, according to <i>The Economist</i> in January 2015: they are &quot;hard to earn, limited in supply and easy to verify.&quot;<sup id=\"cite_ref-ec1305_177-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ec1305-177\">[165]</a></sup> Per some researchers, as of 2015<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, bitcoin functions more as a <a href=\"https://en.wikipedia.org/wiki/Payment_system\">payment system</a> than as a currency.<sup id=\"cite_ref-JEP_39-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup>\\n' +\n    '</p><p>Economists define <a href=\"https://en.wikipedia.org/wiki/Money\">money</a> as serving the following three purposes: a <a href=\"https://en.wikipedia.org/wiki/Store_of_value\">store of value</a>, a <a href=\"https://en.wikipedia.org/wiki/Medium_of_exchange\">medium of exchange</a>, and a <a href=\"https://en.wikipedia.org/wiki/Unit_of_account\">unit of account</a>.<sup id=\"cite_ref-econ315_178-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econ315-178\">[166]</a></sup> According to <i>The Economist</i> in 2014, bitcoin functions best as a medium of exchange.<sup id=\"cite_ref-econ315_178-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-econ315-178\">[166]</a></sup> However, this is debated, and a 2018 assessment by <i>The Economist</i> stated that cryptocurrencies met none of these three criteria.<sup id=\"cite_ref-30082018Economist_168-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-30082018Economist-168\">[157]</a></sup>\\n' +\n    'Yale economist <a href=\"https://en.wikipedia.org/wiki/Robert_J._Shiller\">Robert J. Shiller</a> writes that bitcoin has potential as a unit of account for measuring the relative value of goods, as with Chile&apos;s <a href=\"https://en.wikipedia.org/wiki/Unidad_de_Fomento\">Unidad de Fomento</a>, but that &quot;Bitcoin in its present form [...] doesn&apos;t really solve any sensible economic problem&quot;.<sup id=\"cite_ref-Shiller_179-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Shiller-179\">[167]</a></sup>\\n' +\n    '</p><p>According to research by <a href=\"https://en.wikipedia.org/wiki/Cambridge_University\" class=\"mw-redirect\">Cambridge University</a>, between 2.9 million and 5.8 million unique users used a <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_wallet\">cryptocurrency wallet</a> in 2017, most of them for bitcoin. The number of users has grown significantly since 2013, when there were 300,000&#x2013;1.3 million users.<sup id=\"cite_ref-CU2017_16-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-CU2017-16\">[12]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Acceptance_by_merchants\">Acceptance by merchants</span></h3>\\n' +\n    '<p>The overwhelming majority of bitcoin transactions take place on a <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_exchange\">cryptocurrency exchange</a>, rather than being used in transactions with merchants.<sup id=\"cite_ref-FT08062018_180-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-FT08062018-180\">[168]</a></sup> Delays processing payments through the blockchain of about ten minutes make bitcoin use very difficult in a retail setting. Prices are not usually quoted in units of bitcoin and many trades involve one, or sometimes two, conversions into conventional currencies.<sup id=\"cite_ref-JEP_39-6\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup> Merchants that do accept bitcoin payments may use payment service providers to perform the conversions.<sup id=\"cite_ref-181\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-181\">[169]</a></sup>\\n' +\n    '</p><p>In 2017 and 2018 bitcoin&apos;s acceptance among major online retailers included only three of the top 500 U.S. online merchants, down from five in 2016.<sup id=\"cite_ref-FT08062018_180-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-FT08062018-180\">[168]</a></sup> Reasons for this decline include high transaction fees due to bitcoin&apos;s scalability issues and long transaction times.<sup id=\"cite_ref-182\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-182\">[170]</a></sup>\\n' +\n    '</p><p><i>Bloomberg</i> reported that the largest 17 crypto merchant-processing services handled $69 million in June 2018, down from $411 million in September 2017. Bitcoin is &quot;not actually usable&quot; for retail transactions because of high costs and the inability to process <a href=\"https://en.wikipedia.org/wiki/Chargeback\">chargebacks</a>, according to Nicholas Weaver, a researcher quoted by <i>Bloomberg</i>. High price volatility and transaction fees make paying for small retail purchases with bitcoin impractical, according to economist Kim Grauer. However, bitcoin continues to be used for large-item purchases on sites such as <a href=\"https://en.wikipedia.org/wiki/Overstock.com\">Overstock.com</a>, and for cross-border payments to <a href=\"https://en.wikipedia.org/wiki/Freelancer\">freelancers</a> and other vendors.<sup id=\"cite_ref-impractical_183-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-impractical-183\">[171]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Financial_institutions\">Financial institutions</span></h3>\\n' +\n    '<p>Bitcoins can be bought on <a href=\"https://en.wikipedia.org/wiki/Digital_currency_exchange\" class=\"mw-redirect\">digital currency exchanges</a>.\\n' +\n    '</p><p>Per researchers, &quot;there is little sign of bitcoin use&quot; in international remittances despite high fees charged by banks and <a href=\"https://en.wikipedia.org/wiki/Western_Union\">Western Union</a> who compete in this market.<sup id=\"cite_ref-JEP_39-7\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JEP-39\">[35]</a></sup> The <i><a href=\"https://en.wikipedia.org/wiki/South_China_Morning_Post\">South China Morning Post</a></i>, however, mentions the use of bitcoin by Hong Kong workers to transfer money home.<sup id=\"cite_ref-184\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-184\">[172]</a></sup>\\n' +\n    '</p><p>In 2014, the <a href=\"https://en.wikipedia.org/wiki/National_Australia_Bank\">National Australia Bank</a> closed accounts of businesses with ties to bitcoin,<sup id=\"cite_ref-185\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-185\">[173]</a></sup> and <a href=\"https://en.wikipedia.org/wiki/HSBC\">HSBC</a> refused to serve a hedge fund with links to bitcoin.<sup id=\"cite_ref-186\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-186\">[174]</a></sup> Australian banks in general have been reported as closing down bank accounts of operators of businesses involving the currency.<sup id=\"cite_ref-afr.com_187-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-afr.com-187\">[175]</a></sup>\\n' +\n    '</p><p>On 10 December 2017, the <a href=\"https://en.wikipedia.org/wiki/Chicago_Board_Options_Exchange\">Chicago Board Options Exchange</a> started trading bitcoin futures,<sup id=\"cite_ref-188\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-188\">[176]</a></sup> followed by the <a href=\"https://en.wikipedia.org/wiki/Chicago_Mercantile_Exchange\">Chicago Mercantile Exchange</a>, which started trading bitcoin futures on 17 December 2017.<sup id=\"cite_ref-189\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-189\">[177]</a></sup>\\n' +\n    '</p><p>In September 2019 the <a href=\"https://en.wikipedia.org/wiki/Central_Bank_of_Venezuela\">Central Bank of Venezuela</a>, at the request of <a href=\"https://en.wikipedia.org/wiki/PDVSA\">PDVSA</a>, ran tests to determine if bitcoin and <a href=\"https://en.wikipedia.org/wiki/Ethereum\">ether</a> could be held in central bank&apos;s reserves. The request was motivated by oil company&apos;s goal to pay its suppliers.<sup id=\"cite_ref-190\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-190\">[178]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"As_an_investment\">As an investment</span></h3>\\n' +\n    '<p>The Winklevoss twins have purchased bitcoin. In 2013, <i>The Washington Post</i> reported a claim that they owned 1% of all the bitcoins in existence at the time.<sup id=\"cite_ref-191\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-191\">[179]</a></sup>\\n' +\n    '</p><p>Other methods of investment are bitcoin funds. The first regulated bitcoin fund was established in <a href=\"https://en.wikipedia.org/wiki/Jersey\">Jersey</a> in July 2014 and approved by the Jersey Financial Services Commission.<sup id=\"cite_ref-BitcoinJersey_192-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-BitcoinJersey-192\">[180]</a></sup>\\n' +\n    '</p><p><i>Forbes</i> named bitcoin the best investment of 2013.<sup id=\"cite_ref-193\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-193\">[181]</a></sup> In 2014, Bloomberg named bitcoin one of its worst investments of the year.<sup id=\"cite_ref-worst_194-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-worst-194\">[182]</a></sup> In 2015, bitcoin topped Bloomberg&apos;s currency tables.<sup id=\"cite_ref-195\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-195\">[183]</a></sup>\\n' +\n    '</p><p>According to bitinfocharts.com, in 2017 there are 9,272 bitcoin wallets with more than $1 million worth of bitcoins.<sup id=\"cite_ref-196\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-196\">[184]</a></sup> The exact number of bitcoin millionaires is uncertain as a single person can have more than one bitcoin wallet.\\n' +\n    '</p><p>In August 2020, <a href=\"https://en.wikipedia.org/wiki/MicroStrategy\">MicroStrategy</a> invested in Bitcoin.<sup id=\"cite_ref-197\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-197\">[185]</a></sup><sup id=\"cite_ref-198\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-198\">[186]</a></sup>\\n' +\n    '</p><p>In May 2021, the Bitcoin&apos;s market share on exchanges dropped from 70% to 45% as investors pursued altcoins.<sup id=\"cite_ref-199\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-199\">[187]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Venture_capital\">Venture capital</span></h3>\\n' +\n    '<p><a href=\"https://en.wikipedia.org/wiki/Peter_Thiel\">Peter Thiel</a>&apos;s <a href=\"https://en.wikipedia.org/wiki/Founders_Fund\">Founders Fund</a> invested <a href=\"https://en.wikipedia.org/wiki/United_States_dollar\">US$</a>3 million in <a href=\"https://en.wikipedia.org/wiki/BitPay\">BitPay</a>.<sup id=\"cite_ref-mtr20130612_200-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-mtr20130612-200\">[188]</a></sup> In 2012, an incubator for bitcoin-focused start-ups was founded by Adam Draper, with financing help from his father, venture capitalist <a href=\"https://en.wikipedia.org/wiki/Timothy_C._Draper\" class=\"mw-redirect\">Tim Draper</a>, one of the largest bitcoin holders after winning an auction of 30,000 bitcoins,<sup id=\"cite_ref-wsj1214_201-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-wsj1214-201\">[189]</a></sup> at the time called &quot;mystery buyer&quot;.<sup id=\"cite_ref-guard714_202-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-guard714-202\">[190]</a></sup> The company&apos;s goal is to fund 100 bitcoin businesses within 2&#x2013;3 years with $10,000 to $20,000 for a 6% stake.<sup id=\"cite_ref-wsj1214_201-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-wsj1214-201\">[189]</a></sup> Investors also invest in bitcoin mining.<sup id=\"cite_ref-203\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-203\">[191]</a></sup> According to a 2015 study by Paolo Tasca, bitcoin startups raised almost $1 billion in three years (Q1 2012 &#x2013; Q1 2015).<sup id=\"cite_ref-Tasca_204-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Tasca-204\">[192]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Price_and_volatility\">Price and volatility</span></h3>\\n' +\n    '<div class=\"thumb tmulti tright\"><div class=\"thumbinner\"><div class=\"trow\"><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_price_and_volatility.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Bitcoin_price_and_volatility.svg/200px-Bitcoin_price_and_volatility.svg.png\" width=\"200\" height=\"113\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Bitcoin_price_and_volatility.svg/300px-Bitcoin_price_and_volatility.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Bitcoin_price_and_volatility.svg/400px-Bitcoin_price_and_volatility.svg.png 2x\"></a></div><div class=\"thumbcaption\">Price in US$, semilogarithmic plot.<sup id=\"cite_ref-Blockchain.info_110-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchain.info-110\">[104]</a></sup></div></div><div class=\"tsingle\"><div class=\"thumbimage\"><a href=\"https://en.wikipedia.org/wiki/File:BTCvolatility.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/BTCvolatility.svg/200px-BTCvolatility.svg.png\" width=\"200\" height=\"113\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/BTCvolatility.svg/300px-BTCvolatility.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/2/25/BTCvolatility.svg/400px-BTCvolatility.svg.png 2x\"></a></div><div class=\"thumbcaption\">Annual volatility<sup id=\"cite_ref-Blockchair.com_109-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Blockchair.com-109\">[103]</a></sup></div></div></div></div></div>\\n' +\n    '<p>The price of bitcoins has gone through cycles of appreciation and depreciation referred to by some as <a href=\"https://en.wikipedia.org/wiki/Economic_bubble\">bubbles</a> and busts.<sup id=\"cite_ref-205\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-205\">[193]</a></sup> In 2011, the value of one bitcoin rapidly rose from about US$0.30 to US$32 before returning to US$2.<sup id=\"cite_ref-Leebubble_206-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Leebubble-206\">[194]</a></sup> In the latter half of 2012 and during the <a href=\"https://en.wikipedia.org/wiki/2012%E2%80%9313_Cypriot_financial_crisis\" class=\"mw-redirect\">2012&#x2013;13 Cypriot financial crisis</a>, the bitcoin price began to rise,<sup id=\"cite_ref-207\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-207\">[195]</a></sup> reaching a high of US$266 on 10 April 2013, before crashing to around US$50. On 29 November 2013, the cost of one bitcoin rose to a peak of US$1,242.<sup id=\"cite_ref-208\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-208\">[196]</a></sup> In 2014, the price fell sharply, and as of April remained depressed at little more than half 2013 prices. As of August&#xA0;2014<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup> it was under US$600.<sup id=\"cite_ref-209\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-209\">[197]</a></sup>\\n' +\n    '</p><p>According to <a href=\"https://en.wikipedia.org/wiki/Mark_T._Williams\">Mark T. Williams</a>, as of 30&#xA0;September&#xA0;2014<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, bitcoin has <a href=\"https://en.wikipedia.org/wiki/Volatility_(finance)\">volatility</a> seven times greater than gold, eight times greater than the <a href=\"https://en.wikipedia.org/wiki/S%26P_500\">S&amp;P 500</a>, and 18 times greater than the US dollar.<sup id=\"cite_ref-210\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-210\">[198]</a></sup> Hodl is a meme created in reference to holding (as opposed to selling) during periods of volatility. Unusual for an asset, bitcoin weekend trading during December 2020 was higher than for weekdays.<sup id=\"cite_ref-211\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-211\">[199]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Hedge_fund\">Hedge funds</a> (using high <a href=\"https://en.wikipedia.org/wiki/Leverage_(finance)\">leverage</a> and <a href=\"https://en.wikipedia.org/wiki/Derivative_(finance)\">derivates</a>)<sup id=\"cite_ref-212\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-212\">[200]</a></sup> have attempted to use the volatility to <a href=\"https://en.wikipedia.org/wiki/Short_(finance)\">profit from downward price movements</a>. At the end of January 2021, such positions were over $1 billion, their highest of all time.<sup id=\"cite_ref-213\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-213\">[201]</a></sup><sup id=\"cite_ref-214\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-214\">[202]</a></sup>\\n' +\n    'As of 8&#xA0;February&#xA0;2021<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, the closing price of bitcoin equals US$44,797.<sup id=\"cite_ref-215\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-215\">[203]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span id=\"Legal_status.2C_tax_and_regulation\"></span><span class=\"mw-headline\" id=\"Legal_status,_tax_and_regulation\">Legal status, tax and regulation</span></h2>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Further information: <a href=\"https://en.wikipedia.org/wiki/Legality_of_bitcoin_by_country_or_territory\">Legality of bitcoin by country or territory</a></div>\\n' +\n    '<p>Because of bitcoin&apos;s decentralized nature and its trading on online exchanges located in many countries, regulation of bitcoin has been difficult. However, the use of bitcoin can be criminalized, and shutting down exchanges and the peer-to-peer economy in a given country would constitute a <a href=\"https://en.wikipedia.org/wiki/De_facto\">de facto</a> ban.<sup id=\"cite_ref-216\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-216\">[204]</a></sup> The legal status of bitcoin varies substantially from country to country and is still undefined or changing in many of them. Regulations and bans that apply to bitcoin probably extend to similar cryptocurrency systems.<sup id=\"cite_ref-Tasca_204-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Tasca-204\">[192]</a></sup>\\n' +\n    '</p><p>According to the <a href=\"https://en.wikipedia.org/wiki/Library_of_Congress\">Library of Congress</a>, an &quot;absolute ban&quot; on trading or using cryptocurrencies applies in nine countries: Algeria, Bolivia, Egypt, Iraq, Morocco, Nepal, Pakistan, Vietnam, and the United Arab Emirates. An &quot;implicit ban&quot; applies in another 15 countries, which include Bahrain, Bangladesh, China, Colombia, the Dominican Republic, Indonesia, Kuwait, Lesotho, Lithuania, Macau, Oman, Qatar, Saudi Arabia and Taiwan.<sup id=\"cite_ref-RCAWJune2018LOC_217-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-RCAWJune2018LOC-217\">[205]</a></sup>\\n' +\n    '</p><p>In October 2020, the <a href=\"https://en.wikipedia.org/wiki/Islamic_Republic_News_Agency\">Islamic Republic News Agency</a> announced pending regulations that would require bitcoin miners in Iran to sell bitcoin to the <a href=\"https://en.wikipedia.org/wiki/Central_Bank_of_Iran\">Central Bank of Iran</a>, and the central bank would use it for imports.<sup id=\"cite_ref-aawsat202011_218-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-aawsat202011-218\">[206]</a></sup> Iran, as of October 2020, had issued over 1,000 bitcoin mining licenses.<sup id=\"cite_ref-aawsat202011_218-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-aawsat202011-218\">[206]</a></sup> The Iranian government initially took a stance against cryptocurrency, but later changed it after seeing that digital currency could be used to circumvent sanctions.<sup id=\"cite_ref-ViceIran_219-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ViceIran-219\">[207]</a></sup> The US <a href=\"https://en.wikipedia.org/wiki/Office_of_Foreign_Assets_Control\">Office of Foreign Assets Control</a> listed two Iranians and their bitcoin addresses as part of its <a href=\"https://en.wikipedia.org/wiki/Specially_Designated_Nationals_and_Blocked_Persons_List\">Specially Designated Nationals and Blocked Persons List</a> for their role in the <a href=\"https://en.wikipedia.org/wiki/2018_Atlanta_cyberattack\">2018 Atlanta cyberattack</a> whose ransom was paid in bitcoin.<sup id=\"cite_ref-FPIran_220-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-FPIran-220\">[208]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Regulatory_warnings\">Regulatory warnings</span></h3>\\n' +\n    '<p>The <a href=\"https://en.wikipedia.org/wiki/U.S._Commodity_Futures_Trading_Commission\" class=\"mw-redirect\">U.S. Commodity Futures Trading Commission</a> has issued four &quot;Customer Advisories&quot; for bitcoin and related investments.<sup id=\"cite_ref-CFTC_bitcoin_17-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-CFTC_bitcoin-17\">[13]</a></sup> A July 2018 warning emphasized that trading in any cryptocurrency is often <a href=\"https://en.wikipedia.org/wiki/Speculation\">speculative</a>, and there is a risk of theft from hacking, and fraud.<sup id=\"cite_ref-JulyCFTC_221-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JulyCFTC-221\">[209]</a></sup> In May 2014 the <a href=\"https://en.wikipedia.org/wiki/U.S._Securities_and_Exchange_Commission\">U.S. Securities and Exchange Commission</a> warned that investments involving bitcoin might have high rates of fraud, and that investors might be solicited on social media sites.<sup id=\"cite_ref-SECMay2014_222-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-SECMay2014-222\">[210]</a></sup> An earlier &quot;Investor Alert&quot; warned about the use of bitcoin in <a href=\"https://en.wikipedia.org/wiki/Ponzi_scheme\">Ponzi schemes</a>.<sup id=\"cite_ref-SEC2_223-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-SEC2-223\">[211]</a></sup>\\n' +\n    '</p><p>The <a href=\"https://en.wikipedia.org/wiki/European_Banking_Authority\">European Banking Authority</a> issued a warning in 2013 focusing on the lack of regulation of bitcoin, the chance that exchanges would be hacked, the volatility of bitcoin&apos;s price, and general fraud.<sup id=\"cite_ref-ebawarn_224-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ebawarn-224\">[212]</a></sup> <a href=\"https://en.wikipedia.org/wiki/FINRA\" class=\"mw-redirect\">FINRA</a> and the <a href=\"https://en.wikipedia.org/wiki/North_American_Securities_Administrators_Association\">North American Securities Administrators Association</a> have both issued investor alerts about bitcoin.<sup id=\"cite_ref-225\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-225\">[213]</a></sup><sup id=\"cite_ref-226\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-226\">[214]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Price_manipulation_investigation\">Price manipulation investigation</span></h3>\\n' +\n    '<p>An official investigation into bitcoin traders was reported in May 2018.<sup id=\"cite_ref-Times05252018_227-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Times05252018-227\">[215]</a></sup> The U.S. Justice Department launched an investigation into possible price manipulation, including the techniques of <a href=\"https://en.wikipedia.org/wiki/Spoofing_(finance)\">spoofing</a> and <a href=\"https://en.wikipedia.org/wiki/Wash_trade\">wash trades</a>.<sup id=\"cite_ref-chloeFT_228-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-chloeFT-228\">[216]</a></sup><sup id=\"cite_ref-Bloom052418_229-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Bloom052418-229\">[217]</a></sup><sup id=\"cite_ref-USAT05242018_230-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-USAT05242018-230\">[218]</a></sup>\\n' +\n    '</p><p>The U.S. federal investigation was prompted by concerns of possible manipulation during futures settlement dates. The final settlement price of CME bitcoin futures is determined by prices on four exchanges, <a href=\"https://en.wikipedia.org/wiki/Bitstamp\">Bitstamp</a>, <a href=\"https://en.wikipedia.org/wiki/Coinbase\">Coinbase</a>, itBit and <a href=\"https://en.wikipedia.org/wiki/Kraken_(bitcoin_exchange)\" class=\"mw-redirect\">Kraken</a>. Following the first delivery date in January 2018, the CME requested extensive detailed trading information but several of the exchanges refused to provide it and later provided only limited data. The <a href=\"https://en.wikipedia.org/wiki/Commodity_Futures_Trading_Commission\">Commodity Futures Trading Commission</a> then subpoenaed the data from the exchanges.<sup id=\"cite_ref-MWmanipulation_231-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-MWmanipulation-231\">[219]</a></sup><sup id=\"cite_ref-WSJmanipulation_232-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-WSJmanipulation-232\">[220]</a></sup>\\n' +\n    '</p><p>State and provincial securities regulators, coordinated through the <a href=\"https://en.wikipedia.org/wiki/North_American_Securities_Administrators_Association\">North American Securities Administrators Association</a>, are investigating &quot;bitcoin scams&quot; and <a href=\"https://en.wikipedia.org/wiki/Initial_coin_offering\">ICOs</a> in 40 jurisdictions.<sup id=\"cite_ref-WaPo52118_233-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-WaPo52118-233\">[221]</a></sup>\\n' +\n    '</p><p>Academic research published in the <i><a href=\"https://en.wikipedia.org/wiki/Journal_of_Monetary_Economics\">Journal of Monetary Economics</a></i> concluded that price manipulation occurred during the Mt Gox bitcoin theft and that the market remains vulnerable to manipulation.<sup id=\"cite_ref-JME_234-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-JME-234\">[222]</a></sup> The history of hacks, fraud and theft involving bitcoin dates back to at least 2011.<sup id=\"cite_ref-235\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-235\">[223]</a></sup>\\n' +\n    '</p><p>Research by John M. Griffin and Amin Shams in 2018 suggests that trading associated with increases in the amount of the <a href=\"https://en.wikipedia.org/wiki/Tether_(cryptocurrency)\">Tether cryptocurrency</a> and associated trading at the <a href=\"https://en.wikipedia.org/wiki/Bitfinex\">Bitfinex</a> exchange account for about half of the price increase in bitcoin in late 2017.<sup id=\"cite_ref-untethered_236-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-untethered-236\">[224]</a></sup><sup id=\"cite_ref-Artynyt_237-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Artynyt-237\">[225]</a></sup>\\n' +\n    '</p><p>J.L. van der Velde, CEO of both Bitfinex and Tether, denied the claims of price manipulation: &quot;Bitfinex nor Tether is, or has ever, engaged in any sort of market or price manipulation. Tether issuances cannot be used to prop up the price of bitcoin or any other coin/token on Bitfinex.&quot;<sup id=\"cite_ref-WaPoVdV_238-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-WaPoVdV-238\">[226]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Analysis\">Analysis</span></h2>\\n' +\n    '<figure class=\"infobox\"><img alt=\"video icon\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Nuvola_apps_kaboodle.svg/16px-Nuvola_apps_kaboodle.svg.png\" width=\"16\" height=\"16\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Nuvola_apps_kaboodle.svg/24px-Nuvola_apps_kaboodle.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Nuvola_apps_kaboodle.svg/32px-Nuvola_apps_kaboodle.svg.png 2x\"><tbody><tr><th class=\"infobox-above\">External video</th></tr><tr><td class=\"infobox-full-data\"> <a class=\"external text\" href=\"https://www.youtube.com/watch?v=vo6s1mUjxQQ\">Cryptocurrencies: looking beyond the hype</a>, <a href=\"https://en.wikipedia.org/wiki/Hyun_Song_Shin\" class=\"mw-redirect\">Hyun Song Shin</a>, <a href=\"https://en.wikipedia.org/wiki/Bank_for_International_Settlements\">Bank for International Settlements</a>, 2:48<sup id=\"cite_ref-bis_report_239-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bis_report-239\">[227]</a></sup></td></tr></tbody></figure>\\n' +\n    '<p>The <a href=\"https://en.wikipedia.org/wiki/Bank_for_International_Settlements\">Bank for International Settlements</a> summarized several criticisms of bitcoin in Chapter V of their 2018 annual report. The criticisms include the lack of stability in bitcoin&apos;s price, the high energy consumption, high and variable transactions costs, the poor security and fraud at cryptocurrency exchanges, vulnerability to debasement (from forking), and the influence of miners.<sup id=\"cite_ref-bis_report_239-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bis_report-239\">[227]</a></sup><sup id=\"cite_ref-chapterV_240-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-chapterV-240\">[228]</a></sup><sup id=\"cite_ref-LATHiltzik_241-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-LATHiltzik-241\">[229]</a></sup>\\n' +\n    '</p><p>Fran&#xE7;ois R. Velde, Senior Economist at the <a href=\"https://en.wikipedia.org/wiki/Chicago_Fed\" class=\"mw-redirect\">Chicago Fed</a>, described bitcoin as &quot;an elegant solution to the problem of creating a digital currency&quot;.<sup id=\"cite_ref-242\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-242\">[230]</a></sup> David Andolfatto, Vice President at the <a href=\"https://en.wikipedia.org/wiki/Federal_Reserve_Bank_of_St._Louis\">Federal Reserve Bank of St. Louis</a>, stated that bitcoin is a threat to the establishment, which he argues is a good thing for the <a href=\"https://en.wikipedia.org/wiki/Federal_Reserve_System\" class=\"mw-redirect\">Federal Reserve System</a> and other <a href=\"https://en.wikipedia.org/wiki/Central_bank\">central banks</a>, because it prompts these institutions to operate sound policies.<sup id=\"cite_ref-Andolfatto2014-03_128-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Andolfatto2014-03-128\">[119]</a></sup><sup class=\"reference\">:<span>33</span></sup><sup id=\"cite_ref-243\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-243\">[231]</a></sup><sup id=\"cite_ref-244\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-244\">[232]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Economic_concerns\">Economic concerns</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Further information: <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_bubble\">Cryptocurrency bubble</a> and <a href=\"https://en.wikipedia.org/wiki/Economics_of_bitcoin\">Economics of bitcoin</a></div>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin-bubble-chart-history-2017.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/03/Bitcoin-bubble-chart-history-2017.png/220px-Bitcoin-bubble-chart-history-2017.png\" width=\"220\" height=\"100\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/03/Bitcoin-bubble-chart-history-2017.png/330px-Bitcoin-bubble-chart-history-2017.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/0/03/Bitcoin-bubble-chart-history-2017.png/440px-Bitcoin-bubble-chart-history-2017.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin-bubble-chart-history-2017.png\" class=\"internal\"></a></div>Bitcoin price bubbles in 2011, 2013 and 2017</div></div></div>\\n' +\n    '<p>Bitcoin, along with other cryptocurrencies, has been described as an <a href=\"https://en.wikipedia.org/wiki/Economic_bubble\">economic bubble</a> by at least eight <a href=\"https://en.wikipedia.org/wiki/Nobel_Memorial_Prize_in_Economic_Sciences\">Nobel Memorial Prize in Economic Sciences</a> laureates at various times, including <a href=\"https://en.wikipedia.org/wiki/Robert_Shiller\" class=\"mw-redirect\">Robert Shiller</a> on 1 March 2014,<sup id=\"cite_ref-Shiller_179-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Shiller-179\">[167]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Joseph_Stiglitz\">Joseph Stiglitz</a> on 29 November 2017,<sup id=\"cite_ref-Stiglitz_245-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Stiglitz-245\">[233]</a></sup> and <a href=\"https://en.wikipedia.org/wiki/Richard_Thaler\">Richard Thaler</a> on 21 December 2017.<sup id=\"cite_ref-Thaler_246-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Thaler-246\">[234]</a></sup><sup id=\"cite_ref-4Nobels_247-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-4Nobels-247\">[235]</a></sup> On 29 January 2018, a noted Keynesian economist <a href=\"https://en.wikipedia.org/wiki/Paul_Krugman\">Paul Krugman</a> has described bitcoin as &quot;a bubble wrapped in techno-mysticism inside a cocoon of libertarian ideology&quot;,<sup id=\"cite_ref-Krugman_169-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Krugman-169\">[158]</a></sup> on 2 February 2018, professor <a href=\"https://en.wikipedia.org/wiki/Nouriel_Roubini\">Nouriel Roubini</a> of New York University has called bitcoin the &quot;mother of all bubbles&quot;,<sup id=\"cite_ref-248\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-248\">[236]</a></sup> and on 27 April 2018, a University of Chicago economist <a href=\"https://en.wikipedia.org/wiki/James_Heckman\">James Heckman</a> has compared it to the 17th-century <a href=\"https://en.wikipedia.org/wiki/Tulip_mania\">tulip mania</a>.<sup id=\"cite_ref-4Nobels_247-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-4Nobels-247\">[235]</a></sup>\\n' +\n    '</p><p>Journalists, economists, investors, and the <a href=\"https://en.wikipedia.org/wiki/Bank_of_Estonia\">central bank of Estonia</a> have voiced concerns that bitcoin is a <a href=\"https://en.wikipedia.org/wiki/Ponzi_scheme\">Ponzi scheme</a>.<sup id=\"cite_ref-249\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-249\">[237]</a></sup><sup id=\"cite_ref-250\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-250\">[238]</a></sup><sup id=\"cite_ref-251\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-251\">[239]</a></sup><sup id=\"cite_ref-Ott_Ummelas_and_Milda_Seputyte_252-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ott_Ummelas_and_Milda_Seputyte-252\">[240]</a></sup> In April 2013, <a href=\"https://en.wikipedia.org/wiki/Eric_Posner\">Eric Posner</a>, a law professor at the <a href=\"https://en.wikipedia.org/wiki/University_of_Chicago\">University of Chicago</a>, stated that &quot;a real Ponzi scheme takes fraud; bitcoin, by contrast, seems more like a collective delusion.&quot;<sup id=\"cite_ref-Posner,_Eric_253-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Posner,_Eric-253\">[241]</a></sup> A July 2014 report by the <a href=\"https://en.wikipedia.org/wiki/World_Bank\">World Bank</a> concluded that bitcoin was not a deliberate Ponzi scheme.<sup id=\"cite_ref-254\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-254\">[242]</a></sup><sup class=\"reference\">:<span>7</span></sup> In June 2014, the <a href=\"https://en.wikipedia.org/wiki/Federal_Council_(Switzerland)\">Swiss Federal Council</a> examined concerns that bitcoin might be a pyramid scheme, and concluded that &quot;since in the case of bitcoin the typical promises of profits are lacking, it cannot be assumed that bitcoin is a pyramid scheme.&quot;<sup id=\"cite_ref-FC20140625_255-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-FC20140625-255\">[243]</a></sup><sup class=\"reference\">:<span>21</span></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Energy_consumption_and_carbon_footprint\">Energy consumption and carbon footprint</span></h3>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_electricity_consumption.png\" class=\"image\"><img alt=\"Bitcoin electricity consumption\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Bitcoin_electricity_consumption.png/512px-Bitcoin_electricity_consumption.png\" width=\"512\" height=\"275\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Bitcoin_electricity_consumption.png/768px-Bitcoin_electricity_consumption.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Bitcoin_electricity_consumption.png/1024px-Bitcoin_electricity_consumption.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin_electricity_consumption.png\" class=\"internal\"></a></div>Electricity consumption of the bitcoin network since 2016 (annualized) and comparison with the electricity consumption of various countries in 2019. The upper and lower bounds (grey traces) are based on worst-case and best-case scenario assumptions, respectively. The red trace indicates an intermediate best-guess estimate. (data sources: <a class=\"external text\" href=\"https://cbeci.org/\">Cambridge Bitcoin Electricity Consumption Index</a>, <a class=\"external text\" href=\"https://www.eia.gov/international/data/world/electricity/electricity-consumption?pd=2&amp;p=0000002&amp;u=0&amp;f=A&amp;v=mapbubble&amp;a=-&amp;i=none&amp;vo=value&amp;t=C&amp;g=00000000000000000000000000000000000000000000000001&amp;l=249-ruvvvvvfvtvnvv1vrvvvvfvvvvvvfvvvou20evvvvvvvvvvnvvvs0008&amp;s=315532800000&amp;e=1546300800000&amp;\">US Energy Information Administration</a>; for details, see <a class=\"external text\" href=\"https://cbeci.org/cbeci/methodology\">methodology</a>)</div></div></div>\\n' +\n    '<p>Bitcoin has been criticized for the amount of electricity consumed by mining.\\n' +\n    '</p><p>As of 2015<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>,  estimated combined electricity consumption attributed to mining was 166.7 megawatts and by 2017, was estimated to be between one and four gigawatts of electricity.<sup id=\"cite_ref-256\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-256\">[244]</a></sup><sup id=\"cite_ref-ec1305_177-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-ec1305-177\">[165]</a></sup> In 2018, bitcoin was estimated by to use 2.55 to 3.572 <a href=\"https://en.wikipedia.org/wiki/Gigawatt\" class=\"mw-redirect\">GW</a>, or around 6% of the total power consumed by the global banking sector.<sup id=\"cite_ref-politico201804_257-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-politico201804-257\">[245]</a></sup><sup id=\"cite_ref-258\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-258\">[246]</a></sup><sup id=\"cite_ref-Kohler_259-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Kohler-259\">[247]</a></sup> In July 2019 BBC reported bitcoin consumes about 7 gigawatts, 0.2% of the global total, or equivalent to that of Switzerland.<sup id=\"cite_ref-260\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-260\">[248]</a></sup> A 2021 estimate from the <a href=\"https://en.wikipedia.org/wiki/University_of_Cambridge\">University of Cambridge</a> suggests bitcoin consumes more than 178 (TWh) annually, ranking it in the top 30 energy consumers if it were a country.<sup id=\"cite_ref-Independent_261-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Independent-261\">[249]</a></sup>\\n' +\n    '</p><p>Bitcoin is mined in places like Iceland where <a href=\"https://en.wikipedia.org/wiki/Geothermal_energy\">geothermal energy</a> is cheap and cooling <a href=\"https://en.wikipedia.org/wiki/Arctic\">Arctic</a> air is free.<sup id=\"cite_ref-dh150613_262-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-dh150613-262\">[250]</a></sup> Bitcoin miners are known to use <a href=\"https://en.wikipedia.org/wiki/Hydroelectric_power\" class=\"mw-redirect\">hydroelectric power</a> in <a href=\"https://en.wikipedia.org/wiki/Tibet\">Tibet</a>, <a href=\"https://en.wikipedia.org/wiki/Quebec\">Quebec</a>, <a href=\"https://en.wikipedia.org/wiki/Washington_(state)\">Washington (state)</a>, and <a href=\"https://en.wikipedia.org/wiki/Austria\">Austria</a> to reduce electricity costs.<sup id=\"cite_ref-politico201804_257-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-politico201804-257\">[245]</a></sup><sup id=\"cite_ref-verge20171221_263-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-verge20171221-263\">[251]</a></sup> Miners are attracted to suppliers such as <a href=\"https://en.wikipedia.org/wiki/Hydro_Quebec\" class=\"mw-redirect\">Hydro Quebec</a> that have energy surpluses.<sup id=\"cite_ref-hydro2018_264-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-hydro2018-264\">[252]</a></sup> \\n' +\n    '</p><p>According to a <a href=\"https://en.wikipedia.org/wiki/University_of_Cambridge\">University of Cambridge</a> study, much of bitcoin mining is done in China, where electricity is subsidized by the government.<sup id=\"cite_ref-265\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-265\">[253]</a></sup><sup id=\"cite_ref-266\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-266\">[254]</a></sup> A significant part of Bitcoin mining is powered by cheap electricity in <a href=\"https://en.wikipedia.org/wiki/Xinjiang\">Xinjiang</a>, which mostly comes from <a href=\"https://en.wikipedia.org/wiki/Coal_power\" class=\"mw-redirect\">coal power</a>.<sup id=\"cite_ref-Ponciano_267-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ponciano-267\">[255]</a></sup><sup id=\"cite_ref-268\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-268\">[256]</a></sup> In April 2021 a coal mine explosion in the province coincided with a 35% drop in hashing power and a <a href=\"https://en.wikipedia.org/wiki/Flash_crash\">flash crash</a> in price.<sup id=\"cite_ref-fortuneChina2021_269-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-fortuneChina2021-269\">[257]</a></sup><sup id=\"cite_ref-Ponciano_267-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Ponciano-267\">[255]</a></sup> In other provinces, such as <a href=\"https://en.wikipedia.org/wiki/Hunan\">Hunan</a> and <a href=\"https://en.wikipedia.org/wiki/Sichuan\">Sichuan</a>, mining farms use more <a href=\"https://en.wikipedia.org/wiki/Hydropower\">hydropower</a>, however these account for at most 4% of hash power. According to Alex de Vries, renewable energy is not a good match for Bitcoin mining as 24/7 operations are best for <a href=\"https://en.wikipedia.org/wiki/Return_on_investment\">ROI</a> on mining devices.<sup id=\"cite_ref-fortuneChina2021_269-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-fortuneChina2021-269\">[257]</a></sup> In 2021, a US company purchased the Greenidge coal power plant and converted it to burn natural gas for the sole purpose of mining bitcoin, which has proven to be highly profitable, in spite of protests of local residents against <a href=\"https://en.wikipedia.org/wiki/Air_pollution\">air pollution</a> and <a href=\"https://en.wikipedia.org/wiki/Thermal_pollution\">thermal pollution</a>.<sup id=\"cite_ref-270\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-270\">[258]</a></sup>\\n' +\n    '</p><p>Concerns about bitcoin&apos;s environmental impact relate bitcoin&apos;s energy consumption to carbon emissions.<sup id=\"cite_ref-271\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-271\">[259]</a></sup><sup id=\"cite_ref-272\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-272\">[260]</a></sup> The difficulty of translating the energy consumption into carbon emissions lies in the decentralized nature of bitcoin impeding the localization of miners to examine the electricity mix used. The results of recent studies analyzing bitcoin&apos;s carbon footprint vary.<sup id=\"cite_ref-273\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-273\">[261]</a></sup><sup id=\"cite_ref-274\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-274\">[262]</a></sup><sup id=\"cite_ref-Mora_275-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Mora-275\">[263]</a></sup><sup id=\"cite_ref-Stoll_276-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Stoll-276\">[264]</a></sup> A study published in <i><a href=\"https://en.wikipedia.org/wiki/Nature_Climate_Change\">Nature Climate Change</a></i> in 2018 claims that bitcoin &quot;could alone produce enough <span class=\"nowrap\"><span class=\"chemf nowrap\">CO<span><br>2</span></span></span> emissions to push warming above 2&#xA0;&#xB0;C within less than three decades.&quot;<sup id=\"cite_ref-Mora_275-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Mora-275\">[263]</a></sup> However, other researchers criticized this analysis, arguing the underlying scenarios were inadequate, leading to overestimations.<sup id=\"cite_ref-277\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-277\">[265]</a></sup><sup id=\"cite_ref-278\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-278\">[266]</a></sup><sup id=\"cite_ref-279\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-279\">[267]</a></sup> According to studies published in <i>Joule</i> and <i><a href=\"https://en.wikipedia.org/wiki/American_Chemical_Society\">American Chemical Society</a></i> in 2019, bitcoin&apos;s annual energy consumption results in annual carbon emission ranging from 17<sup id=\"cite_ref-Kohler_259-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Kohler-259\">[247]</a></sup> to 22.9&#xA0;Mt<span class=\"nowrap\"><span class=\"chemf nowrap\">CO<span><br>2</span></span></span> which is comparable to the level of emissions of countries as <a href=\"https://en.wikipedia.org/wiki/Jordan\">Jordan</a> and <a href=\"https://en.wikipedia.org/wiki/Sri_Lanka\">Sri Lanka</a> or <a href=\"https://en.wikipedia.org/wiki/Kansas_City,_Missouri\">Kansas City</a>.<sup id=\"cite_ref-Stoll_276-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Stoll-276\">[264]</a></sup> George Kamiya, writing for the <a href=\"https://en.wikipedia.org/wiki/International_Energy_Agency\">International Energy Agency</a>, says that &quot;predictions about bitcoin consuming the entire world&apos;s electricity&quot; are sensational, but that the area &quot;requires careful monitoring and rigorous analysis&quot;.<sup id=\"cite_ref-280\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-280\">[268]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Use_in_illegal_transactions\">Use in illegal transactions</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Further information: <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_and_crime\">Cryptocurrency and crime</a> and <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network#Alleged_criminal_activity\">Bitcoin network &#xA7;&#xA0;Alleged criminal activity</a></div>\\n' +\n    '<p>Bitcoin held at exchanges are vulnerable to theft through <a href=\"https://en.wikipedia.org/wiki/Phishing\">phishing</a>, <a href=\"https://en.wikipedia.org/wiki/Scamming\" class=\"mw-redirect\">scamming</a>, and <a href=\"https://en.wikipedia.org/wiki/Security_hacker\">hacking</a>. As of December&#xA0;2017<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, around 980,000 bitcoins have been stolen from <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_exchange\">cryptocurrency exchanges</a>.<sup id=\"cite_ref-harney_123-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-harney-123\">[115]</a></sup>\\n' +\n    '</p><p>The use of bitcoin by criminals has attracted the attention of financial regulators, legislative bodies, law enforcement, and the media.<sup id=\"cite_ref-Lavin,_Tim_281-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Lavin,_Tim-281\">[269]</a></sup> Bitcoin gained early notoriety for its use on the <a href=\"https://en.wikipedia.org/wiki/Silk_Road_(marketplace)\">Silk Road</a>. The <a href=\"https://en.wikipedia.org/wiki/United_States_Senate\">U.S. Senate</a> held a hearing on virtual currencies in November 2013.<sup id=\"cite_ref-USoff_282-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-USoff-282\">[270]</a></sup> The U.S. government claimed that bitcoin was used to facilitate payments related to <a href=\"https://en.wikipedia.org/wiki/Russian_interference_in_the_2016_United_States_elections\">Russian interference in the 2016 United States elections</a>.<sup id=\"cite_ref-nytspy2018_283-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-nytspy2018-283\">[271]</a></sup> However, a 2021 study led by former <a href=\"https://en.wikipedia.org/wiki/CIA\" class=\"mw-redirect\">CIA</a> director <a href=\"https://en.wikipedia.org/wiki/Michael_Morell\">Michael Morell</a> showed that broad generalizations about the use of bitcoin in illicit finance are significantly overstated and that blockchain analysis is an effective crime fighting and intelligence gathering tool.<sup id=\"cite_ref-284\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-284\">[272]</a></sup>\\n' +\n    '</p><p>Several news outlets have asserted that the popularity of bitcoins hinges on the ability to use them to purchase illegal goods.<sup id=\"cite_ref-Monetarists_176-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Monetarists-176\">[164]</a></sup><sup id=\"cite_ref-285\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-285\">[273]</a></sup> Nobel-prize winning economist Joseph Stiglitz says that bitcoin&apos;s anonymity encourages money laundering and other crimes.<sup id=\"cite_ref-Hammer_286-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Hammer-286\">[274]</a></sup><sup id=\"cite_ref-FN_287-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-FN-287\">[275]</a></sup>\\n' +\n    '</p><p>In 2014, researchers at the <a href=\"https://en.wikipedia.org/wiki/University_of_Kentucky\">University of Kentucky</a> found &quot;robust evidence that computer programming enthusiasts and illegal activity drive interest in bitcoin, and find limited or no support for political and investment motives&quot;.<sup id=\"cite_ref-uok_174-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-uok-174\">[163]</a></sup> Australian researchers have estimated that 25% of all bitcoin users and 44% of all bitcoin transactions are associated with illegal activity as of April&#xA0;2017<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>. There were an estimated 24 million bitcoin users primarily using bitcoin for illegal activity. They held $8 billion worth of bitcoin, and made 36 million transactions valued at $72 billion.<sup id=\"cite_ref-SDB1_288-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-SDB1-288\">[276]</a></sup><sup id=\"cite_ref-SDB2_289-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-SDB2-289\">[277]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Software_implementation\">Software implementation</span></h2>\\n' +\n    '<figure class=\"infobox\"><img alt=\"Bitcoin-core-v0.10.0.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Bitcoin-core-v0.10.0.png/300px-Bitcoin-core-v0.10.0.png\" width=\"300\" height=\"208\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Bitcoin-core-v0.10.0.png/450px-Bitcoin-core-v0.10.0.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/7c/Bitcoin-core-v0.10.0.png/600px-Bitcoin-core-v0.10.0.png 2x\"><figcaption class=\"infobox-title\">Bitcoin Core</figcaption><tbody><tr><td class=\"infobox-image\"><a href=\"https://en.wikipedia.org/wiki/File:Bitcoin-core-v0.10.0.png\" class=\"image\"></a><div class=\"infobox-caption\">The start screen under <a href=\"https://en.wikipedia.org/wiki/Fedora_(operating_system)\">Fedora</a></div></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Software_developer\" class=\"mw-redirect\">Original author(s)</a></th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/Satoshi_Nakamoto\">Satoshi Nakamoto</a></td></tr><tr><th class=\"infobox-label\">Initial release</th><td class=\"infobox-data\">2009</td></tr><tr><td class=\"infobox-full-data\"></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Software_release_life_cycle\">Stable release</a></th><td class=\"infobox-data\">0.20.1 (2&#xA0;August 2020<span class=\"noprint\">; 9 months ago</span><span>&#xA0;(<span class=\"bday dtstart published updated\">2020-08-02</span>)</span>) <span class=\"plainlinks\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Template:Latest_stable_software_release/Bitcoin_Core&amp;action=edit\">[&#xB1;]</a></span></td></tr><tr><td>\\n' +\n    '</td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Repository_(version_control)\">Repository</a></th><td class=\"infobox-data\"><span class=\"url\"><a class=\"external text\" href=\"https://github.com/bitcoin/bitcoin\">github<wbr>.com<wbr>/bitcoin<wbr>/bitcoin</a></span></td></tr><tr><th class=\"infobox-label\">Written in</th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/C%2B%2B\">C++</a></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Operating_system\">Operating system</a></th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/Linux\">Linux</a>, <a href=\"https://en.wikipedia.org/wiki/Windows\" class=\"mw-redirect\">Windows</a>, <a href=\"https://en.wikipedia.org/wiki/MacOS\">macOS</a></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Software_categories#Categorization_approaches\">Type</a></th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/Cryptocurrency\">Cryptocurrency</a></td></tr><tr><th class=\"infobox-label\"><a href=\"https://en.wikipedia.org/wiki/Software_license\">License</a></th><td class=\"infobox-data\"><a href=\"https://en.wikipedia.org/wiki/MIT_License\">MIT License</a></td></tr><tr><th class=\"infobox-label\">Website</th><td class=\"infobox-data\"><span class=\"url\"><a class=\"external text\" href=\"https://bitcoincore.org/\">bitcoincore<wbr>.org</a></span></td></tr></tbody></figure>\\n' +\n    '<p><i>Bitcoin Core</i> is <a href=\"https://en.wikipedia.org/wiki/Free_and_open-source_software\">free and open-source software</a> that serves as a bitcoin <a href=\"https://en.wikipedia.org/wiki/Node_(networking)\">node</a> (the set of which form the <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network\">bitcoin network</a>) and provides a <a href=\"https://en.wikipedia.org/wiki/Bitcoin#Wallets\">bitcoin wallet</a> which fully verifies payments. It is considered to be bitcoin&apos;s <a href=\"https://en.wikipedia.org/wiki/Reference_implementation\">reference implementation</a>.<sup id=\"cite_ref-Antonopoulos_290-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos-290\">[278]</a></sup> Initially, the software was published by <a href=\"https://en.wikipedia.org/wiki/Satoshi_Nakamoto\">Satoshi Nakamoto</a> under the name &quot;Bitcoin&quot;, and later renamed to &quot;Bitcoin Core&quot; to distinguish it from the <a href=\"https://en.wikipedia.org/wiki/Bitcoin_network\">network</a>.<sup id=\"cite_ref-291\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-291\">[279]</a></sup> It is also known as the <i>Satoshi client</i>.<sup id=\"cite_ref-mastbit_292-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-mastbit-292\">[280]</a></sup>\\n' +\n    '</p><p>The <a href=\"https://en.wikipedia.org/wiki/Massachusetts_Institute_of_Technology\">MIT</a> Digital Currency Initiative funds some of the development of Bitcoin Core.<sup id=\"cite_ref-blad_293-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-blad-293\">[281]</a></sup> The project also maintains the cryptography library libsecp256k1.<sup id=\"cite_ref-about_294-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-about-294\">[282]</a></sup>\\n' +\n    '</p><p>Bitcoin Core includes a transaction verification engine and connects to the bitcoin network as a full <a href=\"https://en.wikipedia.org/wiki/Node_(networking)\">node</a>.<sup id=\"cite_ref-mastbit_292-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-mastbit-292\">[280]</a></sup> Moreover, a <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency_wallet\">cryptocurrency wallet</a>, which can be used to transfer funds, is included by default.<sup id=\"cite_ref-about_294-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-about-294\">[282]</a></sup>  The wallet allows for the sending and receiving of bitcoins. It does not facilitate the buying or selling of bitcoin. It allows users to generate <a href=\"https://en.wikipedia.org/wiki/QR_codes\" class=\"mw-redirect\">QR codes</a> to receive payment.\\n' +\n    '</p><p>The software validates the entire <a href=\"https://en.wikipedia.org/wiki/Blockchain_(database)\" class=\"mw-redirect\">blockchain</a>, which includes all bitcoin transactions ever. This <a href=\"https://en.wikipedia.org/wiki/Distributed_ledger\">distributed ledger</a> which has reached more than 235 gigabytes in size as of Jan 2019, must be downloaded or synchronized before full participation of the client may occur.<sup id=\"cite_ref-mastbit_292-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-mastbit-292\">[280]</a></sup> Although the complete blockchain is not needed all at once since it is possible to run in pruning mode. A <a href=\"https://en.wikipedia.org/wiki/Command-line_interface\">command line</a>-based <a href=\"https://en.wikipedia.org/wiki/Daemon_(computing)\">daemon</a> with a <a href=\"https://en.wikipedia.org/wiki/JSON-RPC\">JSON-RPC</a> interface, bitcoind, is bundled with Bitcoin Core. It also provides access to testnet, a global testing environment that imitates the bitcoin main network using an alternative blockchain where valueless &quot;test bitcoins&quot; are used. Regtest or Regression Test Mode creates a private blockchain which is used as a local testing environment.<sup id=\"cite_ref-bde_295-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-bde-295\">[283]</a></sup> Finally, bitcoin-cli, a simple program which allows users to send <a href=\"https://en.wikipedia.org/wiki/Remote_procedure_call\">RPC</a> commands to bitcoind, is also included.\\n' +\n    '</p><p>Checkpoints which have been hard coded into the client are used only to prevent Denial of Service attacks against nodes which are initially syncing the chain. For this reason the checkpoints included are only as of several years ago.<sup id=\"cite_ref-check_296-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-check-296\">[284]</a></sup><sup id=\"cite_ref-297\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-297\">[285]</a></sup><sup class=\"noprint Inline-Template\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Verifiability\"><span>failed verification</span></a></i>]</sup> A one megabyte block size limit was added in 2010 by Satoshi Nakamoto. This limited the maximum network capacity to about three transactions per second.<sup id=\"cite_ref-leadbit_298-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-leadbit-298\">[286]</a></sup> Since then, network capacity has been improved incrementally both through block size increases and improved wallet behavior. A network alert system was included by Satoshi Nakamoto as a way of informing users of important news regarding bitcoin.<sup id=\"cite_ref-asr_299-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-asr-299\">[287]</a></sup> In November 2016 it was retired. It had become obsolete as news on bitcoin is now widely disseminated.\\n' +\n    '</p><p>Bitcoin Core includes a scripting language inspired by <a href=\"https://en.wikipedia.org/wiki/Forth_(programming_language)\">Forth</a> that can define transactions and specify parameters.<sup id=\"cite_ref-mpapi_300-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-mpapi-300\">[288]</a></sup> ScriptPubKey is used to &quot;lock&quot; transactions based on a set of future conditions. scriptSig is used to meet these conditions or &quot;unlock&quot; a transaction. <a href=\"https://en.wikipedia.org/wiki/Instruction_set\" class=\"mw-redirect\">Operations</a> on the data are performed by various OP_Codes. Two <a href=\"https://en.wikipedia.org/wiki/Stack_(abstract_data_type)\">stacks</a> are used - main and alt. <a href=\"https://en.wikipedia.org/wiki/Control_flow#Loops\">Looping</a> is forbidden.\\n' +\n    '</p><p>Bitcoin Core uses <a href=\"https://en.wikipedia.org/wiki/OpenTimestamps\">OpenTimestamps</a> to timestamp merge commits.<sup id=\"cite_ref-301\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-301\">[289]</a></sup>\\n' +\n    '</p><p>The original creator of the bitcoin client has described their approach to the software&apos;s authorship as it being written first to prove to themselves that the concept of purely peer-to-peer electronic cash was valid and that a paper with solutions could be written. The lead developer is Wladimir J. van der Laan, who took over the role on 8 April 2014.<sup id=\"cite_ref-hunt_302-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-hunt-302\">[290]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Gavin_Andresen\">Gavin Andresen</a> was the former lead maintainer for the software client. Andresen left the role of lead developer for bitcoin to work on the strategic development of its technology.<sup id=\"cite_ref-hunt_302-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-hunt-302\">[290]</a></sup> Bitcoin Core in 2015 was central to a dispute with <a href=\"https://en.wikipedia.org/wiki/Bitcoin_XT\" class=\"mw-redirect\">Bitcoin XT</a>, a competing client that sought to increase the blocksize.<sup id=\"cite_ref-NewYorker_303-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-NewYorker-303\">[291]</a></sup> Over a dozen different companies and industry groups fund the development of Bitcoin Core.\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"In_popular_culture\">In popular culture</span></h2>\\n' +\n    '<h3><span id=\"Term_.22HODL.22\"></span><span class=\"mw-headline\" id=\"Term_&quot;HODL&quot;\">Term &quot;HODL&quot;</span></h3>\\n' +\n    '<p>Hodl (<span class=\"rt-commentedText nowrap\"><span class=\"IPA nopopups noexcerpt\"><a href=\"https://en.wikipedia.org/wiki/Help:IPA/English\">/<span><span>&#x2C8;</span><span>h</span><span>&#x252;</span><span>d</span><span>&#x259;l</span></span>/</a></span></span> <a href=\"https://en.wikipedia.org/wiki/Help:Pronunciation_respelling_key\"><i><span>HOD</span>-&#x259;l</i></a>; often written <b>HODL</b>) is slang in the <a href=\"https://en.wikipedia.org/wiki/Cryptocurrency\">cryptocurrency</a> community for <a href=\"https://en.wikipedia.org/wiki/Buy_and_hold\">holding</a> a cryptocurrency rather than selling it.<sup id=\"cite_ref-304\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-304\">[292]</a></sup> A person who does this is known as a Hodler. It originated in a December 2013 post on the Bitcoin Forum message board by an apparently inebriated user who posted with a typo in the subject, &quot;I AM HODLING.&quot;<sup id=\"cite_ref-305\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-305\">[293]</a></sup> It is often humorously suggested to be a <a href=\"https://en.wikipedia.org/wiki/Backronym\">backronym</a> to &quot;hold on for dear life&quot;.<sup id=\"cite_ref-306\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-306\">[294]</a></sup> In 2017, <a href=\"https://en.wikipedia.org/wiki/Quartz_(publication)\"><i>Quartz</i></a> listed it as one of the essential slang terms in Bitcoin culture, and described it as a stance, &quot;to stay invested in bitcoin and not to capitulate in the face of plunging prices.&quot;<sup id=\"cite_ref-307\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-307\">[295]</a></sup> <i><a href=\"https://en.wikipedia.org/wiki/TheStreet.com\" class=\"mw-redirect\">TheStreet.com</a></i> referred to it as the &quot;favorite mantra&quot; of Bitcoin holders.<sup id=\"cite_ref-308\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-308\">[296]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Bloomberg_News\">Bloomberg News</a> referred to it as a &quot;mantra&quot; for holders during market routs.<sup id=\"cite_ref-309\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-309\">[297]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Literature\">Literature</span></h3>\\n' +\n    '<p>In <a href=\"https://en.wikipedia.org/wiki/Charles_Stross\">Charles Stross</a>&apos; 2013 science fiction novel, <i><a href=\"https://en.wikipedia.org/wiki/Neptune%27s_Brood\">Neptune&apos;s Brood</a></i>, the universal <a href=\"https://en.wikipedia.org/wiki/Interstellar_travel\">interstellar</a> payment system is known as &quot;bitcoin&quot; and operates using cryptography.<sup id=\"cite_ref-310\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-310\">[298]</a></sup> Stross later blogged that the reference was intentional, saying &quot;I wrote <i>Neptune&apos;s Brood</i> in 2011. Bitcoin was obscure back then, and I figured had just enough name recognition to be a useful term for an interstellar currency: it&apos;d clue people in that it was a networked digital currency.&quot;<sup id=\"cite_ref-311\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-311\">[299]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Film\">Film</span></h3>\\n' +\n    '<p>The 2014 documentary <i><a href=\"https://en.wikipedia.org/wiki/The_Rise_and_Rise_of_Bitcoin\">The Rise and Rise of Bitcoin</a></i> portrays the diversity of motives behind the use of bitcoin by interviewing people who use it. These include a computer programmer and a drug dealer.<sup id=\"cite_ref-312\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-312\">[300]</a></sup> The 2016 documentary <i>Banking on Bitcoin</i> is an introduction to the beginnings of bitcoin and the ideas behind cryptocurrency today.<sup id=\"cite_ref-313\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-313\">[301]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Academia\">Academia</span></h3>\\n' +\n    '<p>In September 2015, the establishment of the <a href=\"https://en.wikipedia.org/wiki/Peer-reviewed\" class=\"mw-redirect\">peer-reviewed</a> <a href=\"https://en.wikipedia.org/wiki/Academic_journal\">academic journal</a> <i><a href=\"https://en.wikipedia.org/wiki/Ledger_(journal)\">Ledger</a></i> (<a href=\"https://en.wikipedia.org/wiki/ISSN_(identifier)\" class=\"mw-redirect\">ISSN</a>&#xA0;<a class=\"external text\" href=\"https://www.worldcat.org/search?fq=x0:jrnl&amp;q=n2:2379-5980\">2379-5980</a>) was announced. It covers studies of cryptocurrencies and related technologies, and is published by the <a href=\"https://en.wikipedia.org/wiki/University_of_Pittsburgh\">University of Pittsburgh</a>.<sup id=\"cite_ref-314\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-314\">[302]</a></sup> The journal encourages authors to <a href=\"https://en.wikipedia.org/wiki/Digital_signature\">digitally sign</a> a <a href=\"https://en.wikipedia.org/wiki/Hash_function\">file hash</a> of submitted papers, which will then be <a href=\"https://en.wikipedia.org/wiki/Trusted_timestamping\">timestamped</a> into the bitcoin <a href=\"https://en.wikipedia.org/wiki/Blockchain\">blockchain</a>. Authors are also asked to include a personal bitcoin address in the first page of their papers.<sup id=\"cite_ref-315\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-315\">[303]</a></sup><sup id=\"cite_ref-316\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-316\">[304]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"See_also\">See also</span></h2>\\n' +\n    '<div class=\"div-col\">\\n' +\n    '<ul><li><a href=\"https://en.wikipedia.org/wiki/Alternative_currency\" class=\"mw-redirect\">Alternative currency</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Base58\" class=\"mw-redirect\">Base58</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Crypto-anarchism\">Crypto-anarchism</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/List_of_bitcoin_companies\">List of bitcoin companies</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/List_of_bitcoin_organizations\">List of bitcoin organizations</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/List_of_SHA-256_crypto_currencies\" class=\"mw-redirect\">SHA-256 crypto currencies</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Virtual_currency_law_in_the_United_States\">Virtual currency law in the United States</a></li></ul>\\n' +\n    '</div>\\n' +\n    '\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Notes\">Notes</span></h2>\\n' +\n    '<div class=\"reflist reflist-columns references-column-width reflist-lower-alpha\">\\n' +\n    '<ol class=\"references\">\\n' +\n    '<li id=\"cite_note-BTCcode-102\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BTCcode_102-0\">^</a></b></span> <span class=\"reference-text\">As of 2014<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, BTC is a commonly used code. It does not conform to <a href=\"https://en.wikipedia.org/wiki/ISO_4217\">ISO 4217</a> as BT is the country code of Bhutan, and ISO 4217 requires the first letter used in global commodities to be &apos;X&apos;.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-XBTcode-106\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-XBTcode_106-0\">^</a></b></span> <span class=\"reference-text\">As of 2014<sup class=\"plainlinks noexcerpt noprint asof-tag update\"><a class=\"external text\" href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;action=edit\">[update]</a></sup>, XBT, a code that conforms to ISO 4217 though is not officially part of it, is used by <a href=\"https://en.wikipedia.org/wiki/Bloomberg_L.P.\">Bloomberg L.P.</a>,<sup id=\"cite_ref-103\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-103\">[98]</a></sup> <a href=\"https://en.wikipedia.org/wiki/CNNMoney\" class=\"mw-redirect\">CNNMoney</a>,<sup id=\"cite_ref-104\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-104\">[99]</a></sup> and <a href=\"https://en.wikipedia.org/wiki/Xe.com\" class=\"mw-redirect\">xe.com</a>.<sup id=\"cite_ref-105\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-105\">[100]</a></sup></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-112\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-112\">^</a></b></span> <span class=\"reference-text\">The genesis block is the block number 0. The timestamp of the block is 2009-01-03 18:15:05. This block is unlike all other blocks in that it does not have a previous block to reference.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-115\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-115\">^</a></b></span> <span class=\"reference-text\">The exact number is 20,999,999.9769 bitcoins.<sup id=\"cite_ref-Antonopoulos2014_9-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Antonopoulos2014-9\">[6]</a></sup><sup class=\"reference nowrap\">:<span>ch. 8</span></sup></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-127\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-127\">^</a></b></span> <span class=\"reference-text\">Relative mining difficulty is defined as the ratio of the difficulty target on 9 January 2009 to the current difficulty target.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-129\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-129\">^</a></b></span> <span class=\"reference-text\">It is misleading to think that there is an analogy between gold mining and bitcoin mining. The fact is that gold miners are rewarded for producing gold, while bitcoin miners are not rewarded for producing bitcoins; they are rewarded for their record-keeping services.<sup id=\"cite_ref-Andolfatto2014-03_128-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_note-Andolfatto2014-03-128\">[119]</a></sup></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-144\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-144\">^</a></b></span> <span class=\"reference-text\">The private key can be printed as a <a href=\"https://en.wikipedia.org/wiki/Human-readable_medium\">series of letters and numbers</a>, a <a href=\"https://en.wikipedia.org/wiki/Passphrase\">seed phrase</a>, or a <a href=\"https://en.wikipedia.org/wiki/2D_barcode\" class=\"mw-redirect\">2D barcode</a>. Usually, the public key or bitcoin address is also printed, so that a holder of a paper wallet can check or add funds without exposing the private key to a device.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-LinUSD-175\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-LinUSD_175-0\">^</a></b></span> <span class=\"reference-text\">Liquidity is estimated by a 365-day running sum of transaction outputs in USD.</span>\\n' +\n    '</li>\\n' +\n    '</ol></div>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"References\">References</span></h2>\\n' +\n    '<div class=\"reflist reflist-columns references-column-width\">\\n' +\n    '<ol class=\"references\">\\n' +\n    '<li id=\"cite_note-unicode-10-1\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-unicode-10_1-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-unicode-10_1-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.unicode.org/versions/Unicode10.0.0/\">&quot;Unicode 10.0.0&quot;</a>. Unicode Consortium. 20 June 2017. <a class=\"external text\" href=\"https://web.archive.org/web/20170620130342/http://www.unicode.org/versions/Unicode10.0.0/\">Archived</a> from the original on 20 June 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 June</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-satoshi_unit-4\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-satoshi_unit_4-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-satoshi_unit_4-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFMick2011\" class=\"citation web cs1\">Mick, Jason (12 June 2011). <a class=\"external text\" href=\"https://archive.today/20130120051306/http://www.dailytech.com/Cracking+the+Bitcoin+Digging+Into+a+131M+USD+Virtual+Currency/article21878.htm\">&quot;Cracking the Bitcoin: Digging Into a $131M USD Virtual Currency&quot;</a>. Daily Tech. Archived from <a class=\"external text\" href=\"http://www.dailytech.com/Cracking+the+Bitcoin+Digging+Into+a+131M+USD+Virtual+Currency/article21878.htm\">the original</a> on 20 January 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">30 September</span> 2012</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-5\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-5\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://github.com/bitcoin/bitcoin/releases\">&quot;Releases - bitcoin/bitcoin&quot;</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 May</span> 2021</span> &#x2013; via <a href=\"https://en.wikipedia.org/wiki/GitHub\">GitHub</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-paper-6\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-paper_6-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-paper_6-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-paper_6-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-paper_6-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-paper_6-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-paper_6-5\"><sup><i><b>f</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFNakamoto2008\" class=\"citation web cs1\">Nakamoto, Satoshi (31 October 2008). <a class=\"external text\" href=\"https://bitcoin.org/bitcoin.pdf\">&quot;Bitcoin: A Peer-to-Peer Electronic Cash System&quot;</a> <span class=\"cs1-format\">(PDF)</span>. bitcoin.org. <a class=\"external text\" href=\"https://web.archive.org/web/20140320135003/https://bitcoin.org/bitcoin.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 20 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-8\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-8\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFNakamoto2016\" class=\"citation web cs1\">Nakamoto;  et&#xA0;al. (1 April 2016). <a class=\"external text\" href=\"https://github.com/bitcoin/bitcoin/blob/08a7316c144f9f2516db8fa62400893f4358c5ae/src/amount.h\">&quot;Bitcoin source code - amount constraints&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180701112835/https://github.com/bitcoin/bitcoin/blob/08a7316c144f9f2516db8fa62400893f4358c5ae/src/amount.h\">Archived</a> from the original on 1 July 2018.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Antonopoulos2014-9\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-5\"><sup><i><b>f</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-6\"><sup><i><b>g</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-7\"><sup><i><b>h</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-8\"><sup><i><b>i</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-9\"><sup><i><b>j</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-10\"><sup><i><b>k</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-11\"><sup><i><b>l</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-12\"><sup><i><b>m</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-13\"><sup><i><b>n</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-14\"><sup><i><b>o</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-15\"><sup><i><b>p</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-16\"><sup><i><b>q</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-17\"><sup><i><b>r</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-18\"><sup><i><b>s</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-19\"><sup><i><b>t</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-20\"><sup><i><b>u</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-21\"><sup><i><b>v</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos2014_9-22\"><sup><i><b>w</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFAntonopoulos,_Andreas_M.2014\" class=\"citation book cs1\"><a href=\"https://en.wikipedia.org/wiki/Andreas_Antonopoulos\">Antonopoulos, Andreas M.</a> (April 2014). <i>Mastering Bitcoin: Unlocking Digital Crypto-Currencies</i>. O&apos;Reilly Media. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1-4493-7404-4\"><bdi>978-1-4493-7404-4</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-JSC-11\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JSC_11-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JSC_11-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JSC_11-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JSC_11-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JSC_11-4\"><sup><i><b>e</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.fincen.gov/sites/default/files/2016-08/20131118.pdf\">&quot;Statement of Jennifer Shasky Calvery, Director Financial Crimes Enforcement Network United States Department of the Treasury Before the United States Senate Committee on Banking, Housing, and Urban Affairs Subcommittee on National Security and International Trade and Finance Subcommittee on Economic Policy&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>fincen.gov</i>. Financial Crimes Enforcement Network. 19 November 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20161009183700/https://www.fincen.gov/sites/default/files/2016-08/20131118.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 9 October 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 June</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-whoissn-12\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-whoissn_12-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-whoissn_12-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFS.2015\" class=\"citation news cs1\">S., L. (2 November 2015). <a class=\"external text\" href=\"https://www.economist.com/blogs/economist-explains/2015/11/economist-explains-1\">&quot;Who is Satoshi Nakamoto?&quot;</a>. <i>The Economist</i>. The Economist Newspaper Limited. <a class=\"external text\" href=\"https://web.archive.org/web/20160821154511/http://www.economist.com/blogs/economist-explains/2015/11/economist-explains-1\">Archived</a> from the original on 21 August 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 September</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-NY2011-13\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NY2011_13-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NY2011_13-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NY2011_13-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NY2011_13-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NY2011_13-4\"><sup><i><b>e</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFDavis2011\" class=\"citation web cs1\">Davis, Joshua (10 October 2011). <a class=\"external text\" href=\"https://www.newyorker.com/magazine/2011/10/10/the-crypto-currency\">&quot;The Crypto-Currency: Bitcoin and its mysterious inventor&quot;</a>. <i>The New Yorker</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20141101014157/http://www.newyorker.com/magazine/2011/10/10/the-crypto-currency\">Archived</a> from the original on 1 November 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 October</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-14\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-14\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://money.cnn.com/infographic/technology/what-is-bitcoin/\">&quot;What is Bitcoin?&quot;</a>. <i>CNN Money</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20151031113913/https://money.cnn.com/infographic/technology/what-is-bitcoin/\">Archived</a> from the original on 31 October 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 November</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-:1-15\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-:1_15-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-:1_15-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFGmbH\" class=\"citation web cs1\">GmbH, finanzen net. <a class=\"external text\" href=\"https://www.businessinsider.com/bitcoin-limited-real-use-volatility-speculative-bubble-ubs-wealth-management-2021-3\">&quot;Bitcoin&apos;s limited real-world use and extreme volatility show its recent surge is still a speculative bubble, UBS Global Wealth Management says&quot;</a>. <i>markets.businessinsider.com</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 March</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-CU2017-16\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-CU2017_16-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-CU2017_16-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFHilemanRauchs\" class=\"citation web cs1\">Hileman, Garrick; Rauchs, Michel. <a class=\"external text\" href=\"https://www.jbs.cam.ac.uk/fileadmin/user_upload/research/centres/alternative-finance/downloads/2017-global-cryptocurrency-benchmarking-study.pdf\">&quot;Global Cryptocurrency Benchmarking Study&quot;</a> <span class=\"cs1-format\">(PDF)</span>. Cambridge University. <a class=\"external text\" href=\"https://web.archive.org/web/20170410130007/https://www.jbs.cam.ac.uk/fileadmin/user_upload/research/centres/alternative-finance/downloads/2017-global-cryptocurrency-benchmarking-study.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 10 April 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 April</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-CFTC_bitcoin-17\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-CFTC_bitcoin_17-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-CFTC_bitcoin_17-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://cftc.gov/Bitcoin/index.htm\">&quot;Bitcoin&quot;</a>. <i>U.S. Commodity Futures Trading Commission</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180701150718/https://www.cftc.gov/Bitcoin/index.htm\">Archived</a> from the original on 1 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-18\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-18\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.sec.gov/oiea/investor-alerts-bulletins/investoralertsia_bitcoin.html\">&quot;SEC.gov | INVESTOR ALERT: BITCOIN AND OTHER VIRTUAL CURRENCY-RELATED INVESTMENTS&quot;</a>. <i>www.sec.gov</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190603183220/https://www.sec.gov/oiea/investor-alerts-bulletins/investoralertsia_bitcoin.html\">Archived</a> from the original on 3 June 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 June</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ageofcr-19\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ageofcr_19-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFVignaCasey2015\" class=\"citation book cs1\">Vigna, Paul; Casey, Michael J. (January 2015). <i>The Age of Cryptocurrency: How Bitcoin and Digital Money Are Challenging the Global Economic Order</i> (1&#xA0;ed.). New York: St. Martin&apos;s Press. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1-250-06563-6\"><bdi>978-1-250-06563-6</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-btox-20\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-btox_20-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-btox_20-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.oxforddictionaries.com/definition/english/bitcoin\">&quot;bitcoin&quot;</a>. <a href=\"https://en.wikipedia.org/wiki/OxfordDictionaries.com\" class=\"mw-redirect\">OxfordDictionaries.com</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20150102041748/http://www.oxforddictionaries.com/definition/english/bitcoin\">Archived</a> from the original on 2 January 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 December</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-capitalization-21\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-capitalization_21-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBustillos,_Maria2013\" class=\"citation web cs1\">Bustillos, Maria (2 April 2013). <a class=\"external text\" href=\"https://www.newyorker.com/tech/elements/the-bitcoin-boom\">&quot;The Bitcoin Boom&quot;</a>. <i>The New Yorker</i>. Cond&#xE9; Nast. <a class=\"external text\" href=\"https://web.archive.org/web/20140727185121/http://www.newyorker.com/tech/elements/the-bitcoin-boom\">Archived</a> from the original on 27 July 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 December</span> 2013</span>. <q>Standards vary, but there seems to be a consensus forming around Bitcoin, capitalized, for the system, the software, and the network it runs on, and bitcoin, lowercase, for the currency itself.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-22\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-22\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFVigna2014\" class=\"citation news cs1\">Vigna, Paul (3 March 2014). <a class=\"external text\" href=\"https://blogs.wsj.com/moneybeat/2014/03/14/bitbeat-is-it-bitcoin-or-bitcoin-the-orthography-of-the-cryptography\">&quot;BitBeat: Is It Bitcoin, or bitcoin? The Orthography of the Cryptography&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/Wall_Street_Journal\" class=\"mw-redirect\">WSJ</a></i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140419024119/http://blogs.wsj.com/moneybeat/2014/03/14/bitbeat-is-it-bitcoin-or-bitcoin-the-orthography-of-the-cryptography/\">Archived</a> from the original on 19 April 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-23\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-23\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMetcalf2014\" class=\"citation web cs1\">Metcalf, Allan (14 April 2014). <a class=\"external text\" href=\"http://chronicle.com/blogs/linguafranca/2014/04/11/the-latest-style/\">&quot;The latest style&quot;</a>. Lingua Franca blog. The Chronicle of Higher Education (chronicle.com). <a class=\"external text\" href=\"https://web.archive.org/web/20140416083920/http://chronicle.com/blogs/linguafranca/2014/04/11/the-latest-style/\">Archived</a> from the original on 16 April 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-24\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-24\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBernard2017\" class=\"citation news cs1\">Bernard, Zo&#xEB; (2 December 2017). <a class=\"external text\" href=\"http://www.businessinsider.com/bitcoin-history-cryptocurrency-satoshi-nakamoto-2017-12\">&quot;Everything you need to know about Bitcoin, its mysterious origins, and the many alleged identities of its creator&quot;</a>. <i>Business Insider</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180615010015/http://www.businessinsider.com/bitcoin-history-cryptocurrency-satoshi-nakamoto-2017-12\">Archived</a> from the original on 15 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-25\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-25\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFinley2018\" class=\"citation news cs1\">Finley, Klint (31 October 2018). <a class=\"external text\" href=\"https://www.wired.com/story/after-10-years-bitcoin-changed-everything-nothing/\">&quot;After 10 Years, Bitcoin Has Changed Everything&#x2014;And Nothing&quot;</a>. <i>Wired</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20181105070656/https://www.wired.com/story/after-10-years-bitcoin-changed-everything-nothing/\">Archived</a> from the original on 5 November 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 November</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-26\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-26\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFNakamoto,_Satoshi2009\" class=\"citation web cs1\">Nakamoto, Satoshi (3 January 2009). <a class=\"external text\" href=\"https://sourceforge.net/p/bitcoin/code/HEAD/tree/\">&quot;Bitcoin&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20170721190347/https://sourceforge.net/p/bitcoin/code/HEAD/tree/\">Archived</a> from the original on 21 July 2017.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-27\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-27\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFNakamoto,_Satoshi2009\" class=\"citation web cs1\">Nakamoto, Satoshi (9 January 2009). <a class=\"external text\" href=\"http://www.mail-archive.com/cryptography@metzdowd.com/msg10142.html\">&quot;Bitcoin v0.1 released&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20140326174921/http://www.mail-archive.com/cryptography%40metzdowd.com/msg10142.html\">Archived</a> from the original on 26 March 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Wired:RFB-28\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Wired:RFB_28-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Wired:RFB_28-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFWallace,_Benjamin2011\" class=\"citation magazine cs1\">Wallace, Benjamin (23 November 2011). <a class=\"external text\" href=\"https://www.wired.com/2011/11/mf-bitcoin/\">&quot;The Rise and Fall of Bitcoin&quot;</a>. <i>Wired</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20131031043919/http://www.wired.com/magazine/2011/11/mf_bitcoin\">Archived</a> from the original on 31 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 October</span> 2012</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-29\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-29\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://blockexplorer.com/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f\">&quot;Block 0&#xA0;&#x2013; Bitcoin Block Explorer&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20131015154613/http://blockexplorer.com/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f\">Archived</a> from the original on 15 October 2013.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-30\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-30\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPagliery2014\" class=\"citation book cs1\">Pagliery, Jose (2014). <a class=\"external text\" href=\"https://books.google.com/books?id=_-wuBAAAQBAJ\"><i>Bitcoin: And the Future of Money</i></a>. Triumph Books. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/9781629370361\"><bdi>9781629370361</bdi></a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180121071329/https://books.google.com.au/books?id=_-wuBAAAQBAJ\">Archived</a> from the original on 21 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-31\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-31\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.businessinsider.com/did-shinichi-mochizuki-invent-bitcoin-2013-5\">&quot;Here&apos;s The Problem with the New Theory That A Japanese Math Professor Is The Inventor of Bitcoin&quot;</a>. <i>San Francisco Chronicle</i>. 19 May 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20150104063653/http://www.sfgate.com/technology/businessinsider/article/Here-s-The-Problem-With-The-New-Theory-That-A-4529573.php\">Archived</a> from the original on 4 January 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 February</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-32\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-32\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPeterson2014\" class=\"citation news cs1\">Peterson, Andrea (3 January 2014). <a class=\"external text\" href=\"https://www.washingtonpost.com/blogs/the-switch/wp/2014/01/03/hal-finney-received-the-first-bitcoin-transaction-heres-how-he-describes-it/\">&quot;Hal Finney received the first Bitcoin transaction. Here&apos;s how he describes it&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20150227213647/http://www.washingtonpost.com/blogs/the-switch/wp/2014/01/03/hal-finney-received-the-first-bitcoin-transaction-heres-how-he-describes-it/\">Archived</a> from the original on 27 February 2015.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-33\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-33\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPopper2014\" class=\"citation news cs1\">Popper, Nathaniel (30 August 2014). <a class=\"external text\" href=\"https://www.nytimes.com/2014/08/31/business/hal-finney-cryptographer-and-bitcoin-pioneer-dies-at-58.html\">&quot;Hal Finney, Cryptographer and Bitcoin Pioneer, Dies at 58&quot;</a>. <i>NYTimes</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140903162835/http://www.nytimes.com/2014/08/31/business/hal-finney-cryptographer-and-bitcoin-pioneer-dies-at-58.html\">Archived</a> from the original on 3 September 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 September</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-34\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-34\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKharpal2018\" class=\"citation news cs1\">Kharpal, Arjun (18 June 2018). <a class=\"external text\" href=\"https://www.cnbc.com/2018/06/18/blockchain-what-is-it-and-how-does-it-work.html\">&quot;Everything you need to know about the blockchain&quot;</a>. <i>CNBC</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180913112144/https://www.cnbc.com/2018/06/18/blockchain-what-is-it-and-how-does-it-work.html\">Archived</a> from the original on 13 September 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 September</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-35\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-35\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMcMillan\" class=\"citation news cs1\">McMillan, Robert. <a class=\"external text\" href=\"https://www.wired.com/2013/12/fbi-wallet/\">&quot;Who Owns the World&apos;s Biggest Bitcoin Wallet? The FBI&quot;</a>. <i>Wired</i>. Cond&#xE9; Nast. <a class=\"external text\" href=\"https://web.archive.org/web/20161021221609/https://www.wired.com/2013/12/fbi-wallet/\">Archived</a> from the original on 21 October 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 October</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-36\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-36\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSimonite\" class=\"citation web cs1\">Simonite, Tom. <a class=\"external text\" href=\"https://www.technologyreview.com/s/527051/the-man-who-really-built-bitcoin/\">&quot;Meet Gavin Andresen, the most powerful person in the world of Bitcoin&quot;</a>. <i>MIT Technology Review</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">6 December</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-governance-37\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-governance_37-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-governance_37-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFOdell2015\" class=\"citation news cs1\">Odell, Matt (21 September 2015). <a class=\"external text\" href=\"https://techcrunch.com/2015/09/21/a-solution-to-bitcoins-governance-problem/\">&quot;A Solution To Bitcoin&apos;s Governance Problem&quot;</a>. <i>TechCrunch</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20160126051521/http://techcrunch.com/2015/09/21/a-solution-to-bitcoins-governance-problem/\">Archived</a> from the original on 26 January 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 January</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-breakingup-38\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-breakingup_38-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-breakingup_38-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFVigna2016\" class=\"citation news cs1\">Vigna, Paul (17 January 2016). <a class=\"external text\" href=\"https://www.wsj.com/articles/is-bitcoin-breaking-up-1453044493\">&quot;Is Bitcoin Breaking Up?&quot;</a>. <i>The Wall Street Journal</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20160820144312/http://www.wsj.com/articles/is-bitcoin-breaking-up-1453044493\">Archived</a> from the original on 20 August 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">8 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-JEP-39\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-5\"><sup><i><b>f</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-6\"><sup><i><b>g</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JEP_39-7\"><sup><i><b>h</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFRainer_B&#xF6;hmeNicolas_ChristinBenjamin_EdelmanTyler_Moore2015\" class=\"citation journal cs1\">Rainer B&#xF6;hme; Nicolas Christin; Benjamin Edelman; Tyler Moore (2015). <a class=\"external text\" href=\"https://doi.org/10.1257%2Fjep.29.2.213\">&quot;Bitcoin: Economics, Technology, and Governance&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/Journal_of_Economic_Perspectives\">Journal of Economic Perspectives</a></i>. <b>29</b> (2): 213&#x2013;238. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://doi.org/10.1257%2Fjep.29.2.213\">10.1257/jep.29.2.213</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Odata-40\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Odata_40-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Odata_40-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Odata_40-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Odata_40-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Odata_40-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Odata_40-5\"><sup><i><b>f</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.officialdata.org/bitcoin-price\">&quot;Bitcoin Historical Prices&quot;</a>. <i>OfficialData.org</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180704010212/https://www.officialdata.org/bitcoin-price\">Archived</a> from the original on 4 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-MktWatch09022018-41\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-MktWatch09022018_41-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-MktWatch09022018_41-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-MktWatch09022018_41-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-MktWatch09022018_41-3\"><sup><i><b>d</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFFrench2017\" class=\"citation news cs1\">French, Sally (9 February 2017). <a class=\"external text\" href=\"https://www.marketwatch.com/story/heres-proof-that-this-bitcoin-crash-is-far-from-the-worst-the-cryptocurrency-has-seen-2018-02-09\">&quot;Here&apos;s proof that this bitcoin crash is far from the worst the cryptocurrency has seen&quot;</a>. Market Watch. <a class=\"external text\" href=\"https://web.archive.org/web/20180703220246/https://www.marketwatch.com/story/heres-proof-that-this-bitcoin-crash-is-far-from-the-worst-the-cryptocurrency-has-seen-2018-02-09\">Archived</a> from the original on 3 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-42\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-42\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBustillos2013\" class=\"citation news cs1\">Bustillos, Maria (1 April 2013). <a class=\"external text\" href=\"https://www.newyorker.com/tech/elements/the-bitcoin-boom\">&quot;The Bitcoin Boom&quot;</a>. <i>The New Yorker</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180702064450/https://www.newyorker.com/tech/elements/the-bitcoin-boom\">Archived</a> from the original on 2 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">30 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bqt-43\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bqt_43-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoin.org/en/release/v0.5.0\">&quot;Bitcoin-Qt version 0.5.0 released&quot;</a>. Bitcoin Project. 1 November 2011<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bug_events-44\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bug_events_44-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bug_events_44-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFLee2013\" class=\"citation web cs1\">Lee, Timothy (11 March 2013). <a class=\"external text\" href=\"https://arstechnica.com/business/2013/03/major-glitch-in-bitcoin-network-sparks-sell-off-price-temporarily-falls-23/\">&quot;Major glitch in Bitcoin network sparks sell-off; price temporarily falls 23%&quot;</a>. arstechnica.com. <a class=\"external text\" href=\"https://www.webcitation.org/6G4e02Xd1?url=http://arstechnica.com/business/2013/03/major-glitch-in-bitcoin-network-sparks-sell-off-price-temporarily-falls-23/\">Archived</a> from the original on 22 April 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 February</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-VergeFork-45\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-VergeFork_45-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBlagdon2013\" class=\"citation web cs1\">Blagdon, Jeff (12 March 2013). <a class=\"external text\" href=\"https://www.theverge.com/2013/3/12/4092898/technical-problems-cause-bitcoin-to-plummet-from-record-high\">&quot;Technical problems cause Bitcoin to plummet from record high, Mt. Gox suspends deposits&quot;</a>. <i>The Verge</i>. <a class=\"external text\" href=\"https://www.webcitation.org/6G4e0aImv?url=http://www.theverge.com/2013/3/12/4092898/technical-problems-cause-bitcoin-to-plummet-from-record-high\">Archived</a> from the original on 22 April 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 March</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-46\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-46\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://bitcoincharts.com/charts/mtgoxUSD#rg60zczsg2013-03-12zeg2013-03-15ztgSzm1g10zm2g25zv\">&quot;Bitcoin Charts&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20140509133404/http://bitcoincharts.com/charts/mtgoxUSD\">Archived</a> from the original on 9 May 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ArsFinCEN-47\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ArsFinCEN_47-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLee2013\" class=\"citation web cs1\">Lee, Timothy (20 March 2013). <a class=\"external text\" href=\"https://arstechnica.com/tech-policy/2013/03/us-regulator-bitcoin-exchanges-must-comply-with-money-laundering-laws/\">&quot;US regulator Bitcoin Exchanges Must Comply With Money Laundering Laws&quot;</a>. Arstechnica. <a class=\"external text\" href=\"https://web.archive.org/web/20131021203745/http://arstechnica.com/tech-policy/2013/03/us-regulator-bitcoin-exchanges-must-comply-with-money-laundering-laws/\">Archived</a> from the original on 21 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 July</span> 2017</span>. <q>Bitcoin miners must also register if they trade in their earnings for dollars.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Finextra1-48\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Finextra1_48-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.finextra.com/News/FullStory.aspx?newsitemid=24645\">&quot;US govt clarifies virtual currency regulatory position&quot;</a>. Finextra. 19 March 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20140326183202/http://www.finextra.com/News/FullStory.aspx?newsitemid=24645\">Archived</a> from the original on 26 March 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-FinCEN1-49\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-FinCEN1_49-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://web.archive.org/web/20130328190308/http://fincen.gov/statutes_regs/guidance/pdf/FIN-2013-G001.pdf\">&quot;Application of FinCEN&apos;s Regulations to Persons Administering, Exchanging, or Using Virtual Currencies&quot;</a> <span class=\"cs1-format\">(PDF)</span>. Department of the Treasury Financial Crimes Enforcement Network. Archived from <a class=\"external text\" href=\"http://www.fincen.gov/statutes_regs/guidance/pdf/FIN-2013-G001.pdf\">the original</a> <span class=\"cs1-format\">(PDF)</span> on 28 March 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 March</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-50\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-50\">^</a></b></span> <span class=\"reference-text\">Roose, Kevin (8 April 2013) <cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://nymag.com/daily/intelligencer/2013/04/inside-the-bitcoin-bubble-bitinstants-ceo.html\">&quot;Inside the Bitcoin Bubble: BitInstant&apos;s CEO&#xA0;&#x2013; Daily Intelligencer&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20140409031731/http://nymag.com/daily/intelligencer/2013/04/inside-the-bitcoin-bubble-bitinstants-ceo.html\">Archived</a> from the original on 9 April 2014.</cite><span class=\"Z3988\"></span>. Nymag.com. Retrieved on 20 April 2013.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-51\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-51\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://bitcoincharts.com/charts/mtgoxUSD\">&quot;Bitcoin Exchange Rate&quot;</a>. Bitcoinscharts.com. <a class=\"external text\" href=\"https://www.webcitation.org/68eGWrjWE?url=http://bitcoincharts.com/charts/mtgoxUSD\">Archived</a> from the original on 24 June 2012<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 August</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-52\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-52\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDillet\" class=\"citation web cs1\">Dillet, Romain. <a class=\"external text\" href=\"https://techcrunch.com/2013/05/16/mt-gox-dwolla-account-money-seizure/\">&quot;Feds Seize Assets From Mt. Gox&apos;s Dwolla Account, Accuse It Of Violating Money Transfer Regulations&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20131009161856/http://techcrunch.com/2013/05/16/mt-gox-dwolla-account-money-seizure/\">Archived</a> from the original on 9 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 May</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ABA_FINCEN-53\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ABA_FINCEN_53-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBerson2013\" class=\"citation web cs1\">Berson, Susan A. (2013). <a class=\"external text\" href=\"http://www.abajournal.com/magazine/article/some_basic_rules_for_using_bitcoin_as_virtual_money/\">&quot;Some basic rules for using &apos;bitcoin&apos; as virtual money&quot;</a>. American Bar Association. <a class=\"external text\" href=\"https://web.archive.org/web/20131029185546/http://www.abajournal.com/magazine/article/some_basic_rules_for_using_bitcoin_as_virtual_money/\">Archived</a> from the original on 29 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 June</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-54\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-54\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSampson2013\" class=\"citation news cs1\">Sampson, Tim (2013). <a class=\"external text\" href=\"http://www.dailydot.com/business/11-bitcoins-seized-government-dea/\">&quot;U.S. government makes its first-ever Bitcoin seizure&quot;</a>. <i>The Daily Dot</i>. <a class=\"external text\" href=\"https://www.webcitation.org/6Hl0yLbIR?url=http://www.dailydot.com/business/11-bitcoins-seized-government-dea\">Archived</a> from the original on 30 June 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 October</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-draper-55\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-draper_55-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-draper_55-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFEmber,_Sydney2014\" class=\"citation web cs1\">Ember, Sydney (2 July 2014). <a class=\"external text\" href=\"https://dealbook.nytimes.com/2014/07/02/venture-capitalist-tim-draper-wins-bitcoin-auction/\">&quot;Winner of Bitcoin Auction, Tim Draper, Plans to Expand Currency&apos;s Use&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/The_New_York_Times\">The New York Times</a> DealBook</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190828223151/https://dealbook.nytimes.com/2014/07/02/venture-capitalist-tim-draper-wins-bitcoin-auction/\">Archived</a> from the original on 28 August 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 June</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-56\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-56\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.zdnet.com/after-silk-road-seizure-fbi-bitcoin-wallet-identified-and-pranked-7000021603/\">&quot;After Silk Road seizure, FBI Bitcoin wallet identified and pranked&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20140405173339/http://www.zdnet.com/after-silk-road-seizure-fbi-bitcoin-wallet-identified-and-pranked-7000021603/\">Archived</a> from the original on 5 April 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-57\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-57\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://blockchain.info/address/1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX\">&quot;Silkroad Seized Coins&quot;</a>. <a class=\"external text\" href=\"https://www.webcitation.org/6MUFj8Kcn?url=http://blockchain.info/address/1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX\">Archived</a> from the original on 9 January 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 November</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-58\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-58\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHill\" class=\"citation news cs1\">Hill, Kashmir. <a class=\"external text\" href=\"https://www.forbes.com/sites/kashmirhill/2013/10/04/fbi-silk-road-bitcoin-seizure/\">&quot;The FBI&apos;s Plan For The Millions Worth Of Bitcoins Seized From Silk Road&quot;</a>. <i>Forbes</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140502154935/http://www.forbes.com/sites/kashmirhill/2013/10/04/fbi-silk-road-bitcoin-seizure/\">Archived</a> from the original on 2 May 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ccontrols-59\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ccontrols_59-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKelion,_Leo2013\" class=\"citation news cs1\">Kelion, Leo (18 December 2013). <a class=\"external text\" href=\"https://www.bbc.co.uk/news/technology-25428866\">&quot;Bitcoin sinks after China restricts yuan exchanges&quot;</a>. <i>bbc.com</i>. BBC. <a class=\"external text\" href=\"https://web.archive.org/web/20131219214615/http://www.bbc.co.uk/news/technology-25428866\">Archived</a> from the original on 19 December 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 December</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-60\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-60\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.smh.com.au/business/markets/currencies/china-bans-banks-from-bitcoin-transactions-20131206-2yugy.html\">&quot;China bans banks from bitcoin transactions&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/The_Sydney_Morning_Herald\">The Sydney Morning Herald</a></i>. Reuters. 6 December 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20140323102824/http://www.smh.com.au/business/markets/currencies/china-bans-banks-from-bitcoin-transactions-20131206-2yugy.html\">Archived</a> from the original on 23 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 October</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bloomberg-61\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bloomberg_61-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.bloomberg.com/news/2013-12-07/baidu-stops-accepting-bitcoins-after-china-ban.html\">&quot;Baidu Stops Accepting Bitcoins After China Ban&quot;</a>. <i>Bloomberg</i>. New York. 7 December 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20131210214547/http://www.bloomberg.com/news/2013-12-07/baidu-stops-accepting-bitcoins-after-china-ban.html\">Archived</a> from the original on 10 December 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 December</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-62\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-62\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://english.mofcom.gov.cn/aarticle/newsrelease/commonnews/200906/20090606364208.html\">&quot;China bars use of virtual money for trading in real goods&quot;</a>. English.mofcom.gov.cn. 29 June 2009. <a class=\"external text\" href=\"https://web.archive.org/web/20131129184312/http://english.mofcom.gov.cn/aarticle/newsrelease/commonnews/200906/20090606364208.html\">Archived</a> from the original on 29 November 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-63\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-63\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRayman2014\" class=\"citation web cs1\">Rayman, Noah (30 July 2014). <a class=\"external text\" href=\"https://web.archive.org/web/20140730182422/http://time.com/3059325/wikimedia-wikipedia-bitcoin-donations/\">&quot;You Can Now Donate to Wikipedia in Bitcoin&quot;</a>. <i>TIME</i>. Archived from <a class=\"external text\" href=\"http://time.com/3059325/wikimedia-wikipedia-bitcoin-donations/\">the original</a> on 30 July 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">27 April</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-v0.11.2-64\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-v0.11.2_64-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoin.org/en/release/v0.11.2\">&quot;Bitcoin Core version 0.11.2 released&quot;</a>. Bitcoin Project. 13 November 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-0.12.1rel-65\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-0.12.1rel_65-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKyle_Torpey2016\" class=\"citation news cs1\">Kyle Torpey (15 April 2016). <a class=\"external text\" href=\"http://www.nasdaq.com/article/bitcoin-core-0121-released-major-step-forward-for-scalability-cm607209\">&quot;Bitcoin Core 0.12.1 Released, Major Step Forward for Scalability&quot;</a>. <i>Bitcoin Magazine</i>. NASDAQ.com<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-66\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-66\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAntonopoulos2017\" class=\"citation book cs1\">Antonopoulos, Andreas (2017). <i>Mastering Bitcoin: Programming the Open Blockchain</i> (2nd&#xA0;ed.). O&apos;Reilly Media. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1491954386\"><bdi>978-1491954386</bdi></a>. <q>BIP-68 and BIP-112 were activated in May 2016 as a soft fork upgrade to the consensus rules.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-rel13.1-67\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-rel13.1_67-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoincore.org/en/releases/0.13.1/\">&quot;Bitcoin Core 0.13.1&quot;</a>. Bitcoin Core<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">25 October</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-swb-68\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-swb_68-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoincore.org/en/2016/01/26/segwit-benefits/\">&quot;Segregated Witness Benefits&quot;</a>. <i>Bitcoin Core</i>. 26 January 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-wsjsegwit-69\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-wsjsegwit_69-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-wsjsegwit_69-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-wsjsegwit_69-2\"><sup><i><b>c</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFVigna2017\" class=\"citation news cs1\">Vigna, Paul (21 July 2017). <a class=\"external text\" href=\"https://blogs.wsj.com/moneybeat/2017/07/21/bitcoin-rallies-sharply-after-vote-resolves-bitter-scaling-debate/\">&quot;Bitcoin Rallies Sharply After Vote Resolves Bitter Scaling Debate&quot;</a>. <i>The Wall Street Journal</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20200126104343/https://blogs.wsj.com/moneybeat/2017/07/21/bitcoin-rallies-sharply-after-vote-resolves-bitter-scaling-debate/\">Archived</a> from the original on 26 January 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 January</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bsit-70\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bsit_70-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSelena_Larson2017\" class=\"citation news cs1\">Selena Larson (1 August 2017). <a class=\"external text\" href=\"https://money.cnn.com/2017/08/01/technology/business/bitcoin-cash-new-currency/index.html\">&quot;Bitcoin split in two, here&apos;s what that means&quot;</a>. <i>CNN Tech</i>. Cable News Network. <a class=\"external text\" href=\"https://web.archive.org/web/20180227214042/https://money.cnn.com/2017/08/01/technology/business/bitcoin-cash-new-currency/index.html\">Archived</a> from the original on 27 February 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 April</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-71\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-71\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://fortune.com/2017/12/17/bitcoin-record-high-short-of-20000/\">&quot;Bitcoin Hits a New Record High, But Stops Short of $20,000&quot;</a>. <i>Fortune</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20181114132600/http://fortune.com/2017/12/17/bitcoin-record-high-short-of-20000/\">Archived</a> from the original on 14 November 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 April</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-rmbXinhua-72\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-rmbXinhua_72-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"http://www.xinhuanet.com/english/2018-07/07/c_137308879.htm\">&quot;RMB Bitcoin trading falls below 1 pct of world total&quot;</a>. Xinhuanet. <a href=\"https://en.wikipedia.org/wiki/Xinhua\" class=\"mw-redirect\">Xinhua</a>. 7 July 2018. <a class=\"external text\" href=\"https://web.archive.org/web/20180710225218/http://www.xinhuanet.com/english/2018-07/07/c_137308879.htm\">Archived</a> from the original on 10 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-YahooFin-73\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-YahooFin_73-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-YahooFin_73-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://finance.yahoo.com/quote/BTC-USD/history/\">&quot;Bitcoin USD&quot;</a>. Yahoo Finance!. <a class=\"external text\" href=\"https://web.archive.org/web/20190128082721/https://finance.yahoo.com/quote/BTC-USD/history/\">Archived</a> from the original on 28 January 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">27 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Xpress10072018-74\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Xpress10072018_74-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDawkins2018\" class=\"citation news cs1\">Dawkins, David (10 July 2018). <a class=\"external text\" href=\"https://www.express.co.uk/finance/city/986552/Bitcoin-price-ripple-cryptocurrency-ethereum-BTC-to-USD-XRP-news-china\">&quot;Has CHINA burst the bitcoin BUBBLE? Trading in RMB drops from 90% to 1%&quot;</a>. Express. <a class=\"external text\" href=\"https://web.archive.org/web/20180710225323/https://www.express.co.uk/finance/city/986552/Bitcoin-price-ripple-cryptocurrency-ethereum-BTC-to-USD-XRP-news-china\">Archived</a> from the original on 10 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-75\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-75\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.cnbc.com/2019/01/04/bitcoin-turns-10-the-obscure-technology-that-became-a-household-name.html\">&quot;Bitcoin turns 10: The obscure technology that became a household name&quot;</a>. <i>CNBC</i>. 4 January 2019. <a class=\"external text\" href=\"https://web.archive.org/web/20190119121616/https://www.cnbc.com/2019/01/04/bitcoin-turns-10-the-obscure-technology-that-became-a-household-name.html\">Archived</a> from the original on 19 January 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">18 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-76\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-76\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://bitcoincore.org/en/2018/09/20/notice/\">&quot;CVE-2018-17144 Full Disclosure&quot;</a>. <i>Bitcoin Core</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 September</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Roy3072018-77\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Roy3072018_77-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFChavez-Dreyfuss2018\" class=\"citation news cs1\">Chavez-Dreyfuss, Gertrude (3 July 2018). <a class=\"external text\" href=\"https://www.reuters.com/article/us-crypto-currencies-ciphertrace/cryptocurrency-exchange-theft-surges-in-first-half-of-2018-report-idUSKBN1JT1Q5\">&quot;Cryptocurrency exchange theft surges in first half of 2018: report&quot;</a>. <i>Reuters</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180704120854/https://www.reuters.com/article/us-crypto-currencies-ciphertrace/cryptocurrency-exchange-theft-surges-in-first-half-of-2018-report-idUSKBN1JT1Q5\">Archived</a> from the original on 4 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-BloomFort-78\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BloomFort_78-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation magazine cs1\"><a class=\"external text\" href=\"http://fortune.com/2018/06/20/south-korea-cryptocurrency-hack/\">&quot;Cryptocurrencies Tumble After $32 Million South Korea Exchange Hack&quot;</a>. <i>Fortune</i>. Bloomberg. 20 July 2018. <a class=\"external text\" href=\"https://web.archive.org/web/20180711032352/http://fortune.com/2018/06/20/south-korea-cryptocurrency-hack/\">Archived</a> from the original on 11 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-CNNhack-79\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-CNNhack_79-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFShane2018\" class=\"citation news cs1\">Shane, Daniel (11 June 2018). <a class=\"external text\" href=\"https://money.cnn.com/2018/06/11/investing/coinrail-hack-bitcoin-exchange/index.html\">&quot;Billions in cryptocurrency wealth wiped out after hack&quot;</a>. CNN. <a class=\"external text\" href=\"https://web.archive.org/web/20180711032051/https://money.cnn.com/2018/06/11/investing/coinrail-hack-bitcoin-exchange/index.html\">Archived</a> from the original on 11 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-TCBancor-80\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-TCBancor_80-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRussell2018\" class=\"citation news cs1\">Russell, Jon (10 July 2018). <a class=\"external text\" href=\"https://techcrunch.com/2018/07/10/bancor-loses-23-5m/\">&quot;The crypto world&apos;s latest hack sees Israel&apos;s Bancor lose $23.5M&quot;</a>. <i>TechCrunch</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180710084932/https://techcrunch.com/2018/07/10/bancor-loses-23-5m/\">Archived</a> from the original on 10 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-WSJBakkt-81\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-WSJBakkt_81-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFOsipovich2019\" class=\"citation news cs1\">Osipovich, Alexander (22 September 2019). <a class=\"external text\" href=\"https://www.wsj.com/articles/nyse-owner-to-launch-long-awaited-bitcoin-futures-11569153649\">&quot;NYSE Owner Launches Long-Awaited Bitcoin Futures&quot;</a>. <i>The Wall Street Journal</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190924021537/https://www.wsj.com/articles/nyse-owner-to-launch-long-awaited-bitcoin-futures-11569153649\">Archived</a> from the original on 24 September 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 September</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bakkt20191024-82\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bakkt20191024_82-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFOlga_Kharif2019\" class=\"citation news cs1\">Olga Kharif (24 October 2019). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2019-10-24/bakkt-plans-first-regulated-options-contracts-on-bitcoin-futures\">&quot;Bakkt Plans First Regulated Options Contracts on Bitcoin Futures&quot;</a>. <i>bloomberg.com</i>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20191024192915/https://www.bloomberg.com/news/articles/2019-10-24/bakkt-plans-first-regulated-options-contracts-on-bitcoin-futures\">Archived</a> from the original on 24 October 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 November</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-YoutubeBBC-Block-83\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-YoutubeBBC-Block_83-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.bbc.com/news/technology-50924494\">&quot;YouTube admits error over Bitcoin video purge&quot;</a>. <i>bbc.com</i>. BBC. 28 December 2019. <a class=\"external text\" href=\"https://web.archive.org/web/20191228003142/https://www.bbc.com/news/technology-50924494\">Archived</a> from the original on 28 December 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 December</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Quadriga-Bloomberg-84\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Quadriga-Bloomberg_84-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAlexander2019\" class=\"citation news cs1\">Alexander, Doug (4 February 2019). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2019-02-04/crypto-exchange-founder-dies-leaves-behind-200-million-problem\">&quot;Crypto CEO Dies Holding Only Passwords That Can Unlock Millions in Customer Coins&quot;</a>. <i>bloomberg.com</i>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20191216163149/https://www.bloomberg.com/news/articles/2019-02-04/crypto-exchange-founder-dies-leaves-behind-200-million-problem\">Archived</a> from the original on 16 December 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">27 January</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ForbesCorona-85\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ForbesCorona_85-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ForbesCorona_85-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ForbesCorona_85-2\"><sup><i><b>c</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFdel_Castillo2020\" class=\"citation news cs1\">del Castillo, Michael (19 March 2020). <a class=\"external text\" href=\"https://www.forbes.com/sites/michaeldelcastillo/2020/03/19/bitcoins-magic-is-fading-and-thats-a-good-thing/\">&quot;Bitcoin&apos;s Magic Is Fading, And That&apos;s A Good Thing&quot;</a>. <i>Forbes.com</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20200320174739/https://www.forbes.com/sites/michaeldelcastillo/2020/03/19/bitcoins-magic-is-fading-and-thats-a-good-thing/amp/\">Archived</a> from the original on 20 March 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 March</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-86\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-86\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.cnbc.com/2020/03/13/bitcoin-loses-half-of-its-value-in-two-day-plunge.html\">&quot;Bitcoin loses half of its value in two-day plunge&quot;</a>. <i>CNBC</i>. 13 March 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 December</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-87\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-87\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.bizjournals.com/washington/news/2020/08/11/microstratregy-buys-250m-in-bitcoin.html\">&quot;MicroStrategy buys $250M in Bitcoin as CEO says it&apos;s superior to cash&quot;</a>. <i>Washington Business Journal</i>. 11 August 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 August</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-88\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-88\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBusiness\" class=\"citation web cs1\">Business, Oliver Effron, CNN. <a class=\"external text\" href=\"https://www.cnn.com/2020/10/08/business/square-bitcoin-crypto-investment/index.html\">&quot;Square just bought $50 million in bitcoin&quot;</a>. <i>CNN</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 October</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-89\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-89\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://techcrunch.com/2020/11/12/paypal-says-all-users-in-u-s-can-now-buy-hold-and-sell-cryptocurrencies/\">&quot;PayPal says all users in US can now buy, hold and sell cryptocurrencies&quot;</a>. <i>Techcrunch</i>. 13 November 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 November</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-90\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-90\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://edition.cnn.com/2020/11/30/investing/bitcoin-prices-record-high/index.html\">&quot;Bitcoin hits an all-time high of just under $20,000&quot;</a>. <i>CNN</i>. 30 November 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 December</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-zdnetfrance-91\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-zdnetfrance_91-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFCatalin_Cimpanu2020\" class=\"citation news cs1\">Catalin Cimpanu (7 December 2020). <a class=\"external text\" href=\"https://www.zdnet.com/article/btc-e-founder-sentenced-to-five-years-in-prison-for-laundering-ransomware-funds/\">&quot;BTC-e founder sentenced to five years in prison for laundering ransomware funds&quot;</a>. <i>ZDNet</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 December</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-MM2020-92\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-MM2020_92-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFOlga_Kharif2020\" class=\"citation news cs1\">Olga Kharif (11 December 2020). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2020-12-10/169-year-old-insurer-massmutual-invests-100-million-in-bitcoin\">&quot;169-Year-Old MassMutual Invests $100 Million in Bitcoin&quot;</a>. <i>Bloomberg</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 December</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-CNBCMusk-93\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-CNBCMusk_93-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRyan_Browne2021\" class=\"citation news cs1\">Ryan Browne (29 January 2021). <a class=\"external text\" href=\"https://www.cnbc.com/2021/01/29/bitcoin-spikes-20percent-after-elon-musk-adds-bitcoin-to-his-twitter-bio.html\">&quot;Bitcoin spikes 20% after Elon Musk adds #bitcoin to his Twitter bio&quot;</a>. <i>CNBC</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 February</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-BIMS-94\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BIMS_94-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWill_Daniel2021\" class=\"citation news cs1\">Will Daniel (26 January 2021). <a class=\"external text\" href=\"https://www.businessinsider.com/buy-bitcoin-dip-marathon-patent-group-pours-millions-btc-2021-1\">&quot;Crypto miner Marathon Patent Group pours $150 million into bitcoin as the token pulls back from record highs&quot;</a>. <i>Business Insider</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 February</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-TeslaCNBCbitcoinATH-95\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-TeslaCNBCbitcoinATH_95-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFYun_Li2021\" class=\"citation news cs1\">Yun Li (8 February 2021). <a class=\"external text\" href=\"https://www.cnbc.com/2021/02/08/bitcoin-surges-above-43000-to-a-record-after-elon-musks-tesla-buys-1point5-billion.html\">&quot;Bitcoin surges above $44,000 to record after Elon Musk&apos;s Tesla buys $1.5 billion worth&quot;</a>. <i>CNBC</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 February</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-96\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-96\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://economictimes.indiatimes.com/markets/stocks/news/elon-musk-says-bitcoin-is-slightly-better-than-holding-cash/articleshow/81104000.cms\">&quot;Elon Musk says bitcoin is slightly better than holding cash&quot;</a>. <i>The Economic Times</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 February</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-97\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-97\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.zg.ch/behoerden/finanzdirektion/direktionssekretariat/aktuell/kanton-zug-akzeptiert-ab-2021-kryptowaehrungen-fuer-steuerzahlungen/medienmitteilungen/press-release-of-september-3rd-2020-english-version/download\">&quot;Canton Zug to accept cryptocurrencies for tax payment beginning in 2021&quot;</a>. Canton of Zug. 3 September 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 January</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-98\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-98\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.srf.ch/news/regional/zentralschweiz/steuern-zahlen-mit-bitcoin-kanton-zug-akzeptiert-kryptowaehrungen-bei-steuern\">&quot;Kanton Zug akzeptiert Kryptow&#xE4;hrungen bei Steuern&quot;</a> (in German). Schweizerischen Radio- und Fernsehgesellschaft. 3 September 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 January</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bwiki-99\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bwiki_99-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://en.bitcoin.it/wiki/Secp256k1\">&quot;Secp256k1&quot;</a>. Bitcoin Wiki. 24 April 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">4 February</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-hnhk-100\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-hnhk_100-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKnutson2018\" class=\"citation news cs1\">Knutson, Hans (6 April 2018). <a class=\"external text\" href=\"https://hackernoon.com/what-is-the-math-behind-elliptic-curve-cryptography-f61b25253da3\">&quot;What is the math behind elliptic curve cryptography?&quot;</a>. Hacker Noon.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-BP_A_Look-101\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BP_A_Look_101-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFVan_Hijfte2020\" class=\"citation book cs1\">Van Hijfte, Stijn (2020). <i>Blockchain Platforms: A Look at the Underbelly of Distributed Platforms</i>. Morgan &amp; Claypool Publishers. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/9781681738925\"><bdi>9781681738925</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-103\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-103\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRomain_Dillet2013\" class=\"citation news cs1\">Romain Dillet (9 August 2013). <a class=\"external text\" href=\"https://techcrunch.com/2013/08/09/bitcoin-ticker-available-on-bloomberg-terminal/\">&quot;Bitcoin Ticker Available On Bloomberg Terminal For Employees&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/TechCrunch\">TechCrunch</a></i>. <a class=\"external text\" href=\"https://web.archive.org/web/20141101232825/http://techcrunch.com/2013/08/09/bitcoin-ticker-available-on-bloomberg-terminal/\">Archived</a> from the original on 1 November 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 November</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-104\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-104\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://money.cnn.com/quote/quote.html?symb=XBT\">&quot;Bitcoin Composite Quote (XBT)&quot;</a>. <i>CNN Money</i>. CNN. <a class=\"external text\" href=\"https://web.archive.org/web/20141027100208/https://money.cnn.com/quote/quote.html?symb=xbt\">Archived</a> from the original on 27 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 November</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-105\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-105\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.xe.com/currency/xbt-bitcoin\">&quot;XBT &#x2013; Bitcoin&quot;</a>. xe.com. <a class=\"external text\" href=\"https://web.archive.org/web/20141102111801/http://www.xe.com/currency/xbt-bitcoin\">Archived</a> from the original on 2 November 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 November</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-btcregs-107\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-btcregs_107-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.loc.gov/law/help/bitcoin-survey/regulation-of-bitcoin.pdf\">&quot;Regulation of Bitcoin in Selected Jurisdictions&quot;</a> <span class=\"cs1-format\">(PDF)</span>. The Law Library of Congress, Global Legal Research Center. January 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20141014012832/http://www.loc.gov/law/help/bitcoin-survey/regulation-of-bitcoin.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 14 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 August</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-108\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-108\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKatie_PisaNatasha_Maguder2014\" class=\"citation news cs1\">Katie Pisa &amp; Natasha Maguder (9 July 2014). <a class=\"external text\" href=\"http://edition.cnn.com/2014/06/18/business/bitcoin-your-way-to-a-double-espresso/\">&quot;Bitcoin your way to a double espresso&quot;</a>. <i>cnn.com</i>. CNN. <a class=\"external text\" href=\"https://web.archive.org/web/20150618072429/http://edition.cnn.com/2014/06/18/business/bitcoin-your-way-to-a-double-espresso/\">Archived</a> from the original on 18 June 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 April</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Blockchair.com-109\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchair.com_109-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchair.com_109-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://blockchair.com/\">&quot;Blockchair&quot;</a>. <i>Blockchair.com</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20191013042308/https://blockchair.com/\">Archived</a> from the original on 13 October 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 October</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Blockchain.info-110\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchain.info_110-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchain.info_110-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchain.info_110-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchain.info_110-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Blockchain.info_110-4\"><sup><i><b>e</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://blockchain.info/charts\">&quot;Charts&quot;</a>. <a href=\"https://en.wikipedia.org/wiki/Blockchain.info\" class=\"mw-redirect\">Blockchain.info</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20141103020741/http://blockchain.info/charts\">Archived</a> from the original on 3 November 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 November</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-econbc-111\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econbc_111-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econbc_111-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econbc_111-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econbc_111-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econbc_111-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econbc_111-5\"><sup><i><b>f</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.economist.com/news/briefing/21677228-technology-behind-bitcoin-lets-people-who-do-not-know-or-trust-each-other-build-dependable\">&quot;The great chain of being sure about things&quot;</a>. <i>The Economist</i>. The Economist Newspaper Limited. 31 October 2015. <a class=\"external text\" href=\"https://web.archive.org/web/20160703000844/http://www.economist.com/news/briefing/21677228-technology-behind-bitcoin-lets-people-who-do-not-know-or-trust-each-other-build-dependable\">Archived</a> from the original on 3 July 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 July</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-f_c2-113\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-f_c2_113-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSparkes,_Matthew2014\" class=\"citation news cs1\">Sparkes, Matthew (9 June 2014). <a class=\"external text\" href=\"https://www.telegraph.co.uk/technology/news/10881213/The-coming-digital-anarchy.html\">&quot;The coming digital anarchy&quot;</a>. <i>The Daily Telegraph</i>. London. <a class=\"external text\" href=\"https://web.archive.org/web/20150123190900/http://www.telegraph.co.uk/technology/news/10881213/The-coming-digital-anarchy.html\">Archived</a> from the original on 23 January 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 January</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bloombergvance111413-114\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bloombergvance111413_114-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bloombergvance111413_114-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFAshlee_Vance2013\" class=\"citation magazine cs1\">Ashlee Vance (14 November 2013). <a class=\"external text\" href=\"http://www.businessweek.com/articles/2013-11-14/2014-outlook-bitcoin-mining-chips-a-high-tech-arms-race\">&quot;2014 Outlook: Bitcoin Mining Chips, a High-Tech Arms Race&quot;</a>. <i>Businessweek</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20131121225123/http://www.businessweek.com/articles/2013-11-14/2014-outlook-bitcoin-mining-chips-a-high-tech-arms-race\">Archived</a> from the original on 21 November 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 November</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-KWY-116\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-KWY_116-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRitchie_S._KingSam_WilliamsDavid_Yanofsky2013\" class=\"citation web cs1\">Ritchie S. King; Sam Williams; David Yanofsky (17 December 2013). <a class=\"external text\" href=\"http://qz.com/154877/by-reading-this-page-you-are-mining-bitcoins/\">&quot;By reading this article, you&apos;re mining bitcoins&quot;</a>. <i>qz.com</i>. Atlantic Media Co. <a class=\"external text\" href=\"https://web.archive.org/web/20131217221429/http://qz.com/154877/by-reading-this-page-you-are-mining-bitcoins/\">Archived</a> from the original on 17 December 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 December</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-117\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-117\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFShin2016\" class=\"citation news cs1\">Shin, Laura (24 May 2016). <a class=\"external text\" href=\"https://www.forbes.com/sites/laurashin/2016/05/24/bitcoin-production-will-drop-by-half-in-july-how-will-that-affect-the-price/\">&quot;Bitcoin Production Will Drop By Half In July, How Will That Affect The Price?&quot;</a>. <i>Forbes</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20160524141916/http://www.forbes.com/sites/laurashin/2016/05/24/bitcoin-production-will-drop-by-half-in-july-how-will-that-affect-the-price/\">Archived</a> from the original on 24 May 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 July</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-EconOfBTC-118\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-EconOfBTC_118-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-EconOfBTC_118-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-EconOfBTC_118-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-EconOfBTC_118-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-EconOfBTC_118-4\"><sup><i><b>e</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFJoshua_A._KrollIan_C._DaveyEdward_W._Felten2013\" class=\"citation web cs1\">Joshua A. Kroll; Ian C. Davey; Edward W. Felten (11&#x2013;12 June 2013). <a class=\"external text\" href=\"http://www.econinfosec.org/archive/weis2013/papers/KrollDaveyFeltenWEIS2013.pdf\">&quot;The Economics of Bitcoin Mining, or Bitcoin in the Presence of Adversaries&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>The Twelfth Workshop on the Economics of Information Security (WEIS 2013)</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20160509053819/http://www.econinfosec.org/archive/weis2013/papers/KrollDaveyFeltenWEIS2013.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 9 May 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 April</span> 2016</span>. <q>A transaction fee is like a tip or gratuity left for the miner.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-119\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-119\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFOrcutt2015\" class=\"citation news cs1\">Orcutt, Mike (19 May 2015). <a class=\"external text\" href=\"https://www.technologyreview.com/s/537486/leaderless-bitcoin-struggles-to-make-its-most-crucial-decision/\">&quot;Leaderless Bitcoin Struggles to Make Its Most Crucial Decision&quot;</a>. <i>MIT Technology Review</i>. <a class=\"external text\" href=\"https://wayback.archive-it.org/all/20171018075515/https://www.technologyreview.com/s/537486/leaderless-bitcoin-struggles-to-make-its-most-crucial-decision/\">Archived</a> from the original on 18 October 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 June</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-120\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-120\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"http://washington.cbslocal.com/2013/11/29/man-throws-away-7500-bitcoins-now-worth-7-5-million/\">&quot;Man Throws Away 7,500 Bitcoins, Now Worth $7.5 Million&quot;</a>. <i>CBS DC</i>. 29 November 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20140115062630/http://washington.cbslocal.com/2013/11/29/man-throws-away-7500-bitcoins-now-worth-7-5-million/\">Archived</a> from the original on 15 January 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-wsjlost-121\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-wsjlost_121-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKrause2018\" class=\"citation news cs1\">Krause, Elliott (5 July 2018). <a class=\"external text\" href=\"https://www.wsj.com/articles/a-fifth-of-all-bitcoin-is-missing-these-crypto-hunters-can-help-1530798731\">&quot;A Fifth of All Bitcoin Is Missing. These Crypto Hunters Can Help&quot;</a>. <i>The Wall Street Journal</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180709010939/https://www.wsj.com/articles/a-fifth-of-all-bitcoin-is-missing-these-crypto-hunters-can-help-1530798731\">Archived</a> from the original on 9 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">8 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-122\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-122\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFJeffries2013\" class=\"citation news cs1\">Jeffries, Adrianne (19 December 2013). <a class=\"external text\" href=\"https://www.theverge.com/2013/12/19/5183356/how-to-steal-bitcoin-in-three-easy-steps\">&quot;How to steal Bitcoin in three easy steps&quot;</a>. <i>The Verge</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190727141228/https://www.theverge.com/2013/12/19/5183356/how-to-steal-bitcoin-in-three-easy-steps\">Archived</a> from the original on 27 July 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-harney-123\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-harney_123-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-harney_123-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFHarneyStecklow2017\" class=\"citation news cs1\">Harney, Alexandra; Stecklow, Steve (16 November 2017). <a class=\"external text\" href=\"https://www.reuters.com/investigates/special-report/bitcoin-gox/\">&quot;Twice burned - How Mt. Gox&apos;s bitcoin customers could lose again&quot;</a>. <i>Reuters</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190829052101/https://www.reuters.com/investigates/special-report/bitcoin-gox/\">Archived</a> from the original on 29 August 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">6 September</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-124\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-124\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMartindale2018\" class=\"citation news cs1\">Martindale, Jon (16 March 2018). <a class=\"external text\" href=\"https://www.digitaltrends.com/computing/who-owns-all-the-bitcoin/\">&quot;Who owns all the Bitcoin? A few billionaire whales in a small pond&quot;</a>. <i>Digital Trends</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190630234800/https://www.digitaltrends.com/computing/who-owns-all-the-bitcoin/\">Archived</a> from the original on 30 June 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 July</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-125\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-125\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.theverge.com/2018/1/30/16949550/bitcoin-graphics-cards-pc-prices-surge\">&quot;Bitcoin mania is hurting PC gamers by pushing up GPU prices&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180202070911/https://www.theverge.com/2018/1/30/16949550/bitcoin-graphics-cards-pc-prices-surge\">Archived</a> from the original on 2 February 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 February</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-126\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-126\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.worldoil.com/news/2018/1/26/cryptocurrency-mining-operation-launched-by-iron-bridge-resources\">&quot;Cryptocurrency mining operation launched by Iron Bridge Resources&quot;</a>. <i>World Oil</i>. 26 January 2018. <a class=\"external text\" href=\"https://web.archive.org/web/20180130091353/http://www.worldoil.com/news/2018/1/26/cryptocurrency-mining-operation-launched-by-iron-bridge-resources\">Archived</a> from the original on 30 January 2018.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Andolfatto2014-03-128\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Andolfatto2014-03_128-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Andolfatto2014-03_128-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFAndolfatto,_David2014\" class=\"citation web cs1\">Andolfatto, David (31 March 2014). <a class=\"external text\" href=\"http://www.stlouisfed.org/dialogue-with-the-fed/assets/Bitcoin-3-31-14.pdf\">&quot;Bitcoin and Beyond: The Possibilities and Pitfalls of Virtual Currencies&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>Dialogue with the Fed</i>. Federal Reserve Bank of St. Louis. <a class=\"external text\" href=\"https://web.archive.org/web/20140409044505/http://www.stlouisfed.org/dialogue-with-the-fed/assets/Bitcoin-3-31-14.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 9 April 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-130\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-130\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFShermanJavaniGolaszewski2019\" class=\"citation journal cs1\">Sherman, Alan; Javani, Farid; Golaszewski, Enis (25 March 2019). &quot;On the Origins and Variations of Blockchain Technologies&quot;. <i>IEEE Security and Policy</i>. <b>17</b> (1): 72&#x2013;77. <a href=\"https://en.wikipedia.org/wiki/ArXiv_(identifier)\" class=\"mw-redirect\">arXiv</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://arxiv.org/abs/1810.06130\">1810.06130</a></span>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1109%2FMSEC.2019.2893730\">10.1109/MSEC.2019.2893730</a>. <a href=\"https://en.wikipedia.org/wiki/S2CID_(identifier)\" class=\"mw-redirect\">S2CID</a>&#xA0;<a class=\"external text\" href=\"https://api.semanticscholar.org/CorpusID:53114747\">53114747</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-diffhistory-131\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-diffhistory_131-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://blockchain.info/charts/difficulty?timespan=all&amp;showDataPoints=false&amp;daysAverageString=1&amp;show_header=true&amp;scale=0&amp;address=\">&quot;Difficulty History&quot;</a> (The ratio of all hashes over valid hashes is D x 4,295,032,833, where D is the published &quot;Difficulty&quot; figure.). Blockchain.info. <a class=\"external text\" href=\"https://web.archive.org/web/20150408212548/https://blockchain.info/charts/difficulty?timespan=all&amp;showDataPoints=false&amp;daysAverageString=1&amp;show_header=true&amp;scale=0&amp;address=\">Archived</a> from the original on 8 April 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 March</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-132\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-132\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHampton2016\" class=\"citation news cs1\">Hampton, Nikolai (5 September 2016). <a class=\"external text\" href=\"http://www.computerworld.com.au/article/606253/understanding-blockchain-hype-why-much-it-nothing-more-than-snake-oil-spin/\">&quot;Understanding the blockchain hype: Why much of it is nothing more than snake oil and spin&quot;</a>. <i>Computerworld</i>. IDG. <a class=\"external text\" href=\"https://web.archive.org/web/20160906171838/http://www.computerworld.com.au/article/606253/understanding-blockchain-hype-why-much-it-nothing-more-than-snake-oil-spin/\">Archived</a> from the original on 6 September 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 September</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Techcrunch12-133\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Techcrunch12_133-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBiggs2013\" class=\"citation web cs1\">Biggs, John (8 April 2013). <a class=\"external text\" href=\"https://techcrunch.com/2013/04/08/how-to-mine-bitcoins/\">&quot;How To Mine Bitcoins&quot;</a>. Techcrunch. <a class=\"external text\" href=\"https://web.archive.org/web/20170706132517/https://techcrunch.com/2013/04/08/how-to-mine-bitcoins/\">Archived</a> from the original on 6 July 2017.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Bitcoin_Clients-134\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Bitcoin_Clients_134-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSkudnov2012\" class=\"citation thesis cs1\">Skudnov, Rostislav (2012). <a class=\"external text\" href=\"http://publications.theseus.fi/bitstream/handle/10024/47166/Skudnov_Rostislav.pdf?sequence=1\"><i>Bitcoin Clients</i></a> <span class=\"cs1-format\">(PDF)</span> (Bachelor&apos;s Thesis). <a href=\"https://en.wikipedia.org/wiki/Turku_University_of_Applied_Sciences\">Turku University of Applied Sciences</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20140118104507/http://publications.theseus.fi/bitstream/handle/10024/47166/Skudnov_Rostislav.pdf?sequence=1\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 18 January 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-135\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-135\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoin.org/en/release/v0.9.0\">&quot;Bitcoin Core version 0.9.0 released&quot;</a>. <i>bitcoin.org</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20150227213613/https://bitcoin.org/en/release/v0.9.0\">Archived</a> from the original on 27 February 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">8 January</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-136\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-136\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMetz2015\" class=\"citation news cs1\">Metz, Cade (19 August 2015). <a class=\"external text\" href=\"https://www.wired.com/2015/08/bitcoin-schism-shows-genius-open-source/\">&quot;The Bitcoin Schism Shows the Genius of Open Source&quot;</a>. <i>Wired</i>. Cond&#xE9; Nast. <a class=\"external text\" href=\"https://web.archive.org/web/20160630230101/http://www.wired.com/2015/08/bitcoin-schism-shows-genius-open-source\">Archived</a> from the original on 30 June 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 July</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-137\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-137\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAllison2017\" class=\"citation news cs1\">Allison, Ian (28 April 2017). <a class=\"external text\" href=\"http://www.ibtimes.co.uk/ethereum-co-founder-dr-gavin-wood-company-release-parity-bitcoin-1619025\">&quot;Ethereum co-founder Dr Gavin Wood and company release Parity Bitcoin&quot;</a>. <i>International Business Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20170428032027/http://www.ibtimes.co.uk/ethereum-co-founder-dr-gavin-wood-company-release-parity-bitcoin-1619025\">Archived</a> from the original on 28 April 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 April</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-138\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-138\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAdam_SerwerDana_Liebelson2013\" class=\"citation web cs1\">Adam Serwer &amp; Dana Liebelson (10 April 2013). <a class=\"external text\" href=\"https://www.motherjones.com/politics/2013/04/what-is-bitcoin-explained\">&quot;Bitcoin, Explained&quot;</a>. <i>motherjones.com</i>. Mother Jones. <a class=\"external text\" href=\"https://web.archive.org/web/20140427022315/https://www.motherjones.com/politics/2013/04/what-is-bitcoin-explained\">Archived</a> from the original on 27 April 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Economist113013Pressure-139\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Economist113013Pressure_139-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.economist.com/news/technology-quarterly/21590766-virtual-currency-it-mathematically-elegant-increasingly-popular-and-highly\">&quot;Bitcoin: Bitcoin under pressure&quot;</a>. <i>The Economist</i>. 30 November 2013. <a class=\"external text\" href=\"https://web.archive.org/web/20131130032403/http://www.economist.com/news/technology-quarterly/21590766-virtual-currency-it-mathematically-elegant-increasingly-popular-and-highly\">Archived</a> from the original on 30 November 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">30 November</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-140\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-140\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://blockchain.info/charts/blocks-size\">&quot;Blockchain Size&quot;</a>. <i>Blockchain.info</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20170527050820/https://blockchain.info/charts/blocks-size\">Archived</a> from the original on 27 May 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-LBC-141\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-LBC_141-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGervaisO._KarameGruberCapkun\" class=\"citation web cs1\">Gervais, Arthur; O. Karame, Ghassan; Gruber, Damian; Capkun, Srdjan. <a class=\"external text\" href=\"https://eprint.iacr.org/2014/763.pdf\">&quot;On the Privacy Provisions of Bloom Filters in Lightweight Bitcoin Clients&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <a class=\"external text\" href=\"https://web.archive.org/web/20161005045518/https://eprint.iacr.org/2014/763.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 5 October 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 September</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-142\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-142\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBill_Barhydt2014\" class=\"citation news cs1\">Bill Barhydt (4 June 2014). <a class=\"external text\" href=\"https://www.cnbc.com/id/101711220\">&quot;3 reasons Wall Street can&apos;t stay away from bitcoin&quot;</a>. NBCUniversal. <a class=\"external text\" href=\"https://web.archive.org/web/20150403052101/https://www.cnbc.com/id/101711220\">Archived</a> from the original on 3 April 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 April</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-mtgoxdetails-143\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-mtgoxdetails_143-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.bbc.com/news/technology-26420932\">&quot;MtGox gives bankruptcy details&quot;</a>. <i>bbc.com</i>. BBC. 4 March 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20140312001338/http://www.bbc.com/news/technology-26420932\">Archived</a> from the original on 12 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-befuddled-145\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-befuddled_145-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-befuddled_145-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFBarskiWilmer2015\" class=\"citation book cs1\">Barski, Conrad; Wilmer, Chris (2015). <i>Bitcoin for the Befuddled</i>. <a href=\"https://en.wikipedia.org/wiki/No_Starch_Press\">No Starch Press</a>. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1-59327-573-0\"><bdi>978-1-59327-573-0</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-146\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-146\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPopper2017\" class=\"citation web cs1\">Popper, Nathaniel (19 December 2017). <a class=\"external text\" href=\"https://www.nytimes.com/2017/12/19/technology/bitcoin-winklevoss-twins.html\">&quot;How the Winklevoss Twins Found Vindication in a Bitcoin Fortune&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190620045721/https://www.nytimes.com/2017/12/19/technology/bitcoin-winklevoss-twins.html\">Archived</a> from the original on 20 June 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 June</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-alexander-147\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-alexander_147-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAlexander2019\" class=\"citation web cs1\">Alexander, Doug (15 February 2019). <a class=\"external text\" href=\"https://business.financialpost.com/technology/blockchain/quadrigas-late-founder-used-to-store-clients-bitcoin-passwords-on-paper-so-they-wouldnt-get-lost\">&quot;Quadriga&apos;s late founder used to store clients&apos; Bitcoin passwords on paper so they wouldn&apos;t get lost&quot;</a>. <i>Bloomberg News</i>. Financial Post. <a class=\"external text\" href=\"https://web.archive.org/web/20190620035814/https://business.financialpost.com/technology/blockchain/quadrigas-late-founder-used-to-store-clients-bitcoin-passwords-on-paper-so-they-wouldnt-get-lost\">Archived</a> from the original on 20 June 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 June</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-theverge-148\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-theverge_148-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-theverge_148-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFStaff2013\" class=\"citation web cs1\">Staff, Verge (13 December 2013). <a class=\"external text\" href=\"https://www.theverge.com/2013/12/13/5207256/casascius-maker-of-shiny-physical-bitcoins-shut-down-by-treasury\">&quot;Casascius, maker of shiny physical bitcoins, shut down by Treasury Department&quot;</a>. <i>The Verge</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140110010445/http://www.theverge.com/2013/12/13/5207256/casascius-maker-of-shiny-physical-bitcoins-shut-down-by-treasury\">Archived</a> from the original on 10 January 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Ahonen2016-149\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ahonen2016_149-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ahonen2016_149-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ahonen2016_149-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ahonen2016_149-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ahonen2016_149-4\"><sup><i><b>e</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFAhonenRipponKesselman2016\" class=\"citation book cs1\">Ahonen, Elias; Rippon, Matthew J.; Kesselman, Howard (15 April 2016). <i>Encyclopedia of Physical Bitcoins and Crypto-Currencies</i>. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-0-9950-8990-7\"><bdi>978-0-9950-8990-7</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-150\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-150\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMack2011\" class=\"citation web cs1\">Mack, Eric (25 October 2011). <a class=\"external text\" href=\"https://www.cnet.com/news/are-physical-bitcoins-legal/\">&quot;Are physical Bitcoins legal?&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/CNET\">CNET</a></i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190626215256/https://www.cnet.com/news/are-physical-bitcoins-legal/\">Archived</a> from the original on 26 June 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 May</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-151\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-151\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBritish_Museum2012\" class=\"citation web cs1\"><a href=\"https://en.wikipedia.org/wiki/British_Museum\">British Museum</a> (2012). <a class=\"external text\" href=\"https://www.britishmuseum.org/research/collection_online/collection_object_details.aspx?objectId=3451294&amp;partId=1&amp;people=185966&amp;peoA=185966-3-9&amp;page=1\">&quot;Bitcoin token with digital code for bitcoin currency&quot;</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 May</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-152\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-152\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRoberts2017\" class=\"citation news cs1\">Roberts, Daniel (15 December 2017). <a class=\"external text\" href=\"https://finance.yahoo.com/news/send-bitcoin-hardware-wallet-140141385.html\">&quot;How to send bitcoin to a hardware wallet&quot;</a>. <i>Yahoo Finance</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180217142235/https://finance.yahoo.com/news/send-bitcoin-hardware-wallet-140141385.html\">Archived</a> from the original on 17 February 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 February</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-DLT-153\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-DLT_153-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMeola2017\" class=\"citation news cs1\">Meola, Andrew (5 October 2017). <a class=\"external text\" href=\"https://www.businessinsider.com/blockchain-distributed-ledgers-2017-10\">&quot;How distributed ledger technology will change the way the world works&quot;</a>. <i>Business Insider</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180427142806/http://www.businessinsider.com/blockchain-distributed-ledgers-2017-10\">Archived</a> from the original on 27 April 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-primer-154\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-primer_154-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFJerry_BritoAndrea_Castillo2013\" class=\"citation web cs1\">Jerry Brito &amp; Andrea Castillo (2013). <a class=\"external text\" href=\"http://mercatus.org/sites/default/files/Brito_BitcoinPrimer.pdf\">&quot;Bitcoin: A Primer for Policymakers&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>Mercatus Center</i>. <a href=\"https://en.wikipedia.org/wiki/George_Mason_University\">George Mason University</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20130921060724/http://mercatus.org/sites/default/files/Brito_BitcoinPrimer.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 21 September 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 October</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ieeesurvey-155\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ieeesurvey_155-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFTschorschScheuermann2016\" class=\"citation journal cs1\">Tschorsch, Florian; Scheuermann, Bj&#xF6;rn (2016). &quot;Bitcoin and Beyond: A Technical Survey on Decentralized Digital Currencies&quot;. <i>IEEE Communications Surveys &amp; Tutorials</i>. <b>18</b> (3): 2084&#x2013;2123. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1109%2Fcomst.2016.2535718\">10.1109/comst.2016.2535718</a>. <a href=\"https://en.wikipedia.org/wiki/S2CID_(identifier)\" class=\"mw-redirect\">S2CID</a>&#xA0;<a class=\"external text\" href=\"https://api.semanticscholar.org/CorpusID:5115101\">5115101</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-156\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-156\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBeikverdiSong2015\" class=\"citation book cs1\">Beikverdi, A.; Song, J. (June 2015). <i>Trend of centralization in Bitcoin&apos;s distributed network</i>. <i>2015 IEEE/ACIS 16th International Conference on Software Engineering, Artificial Intelligence, Networking and Parallel/Distributed Computing (SNPD)</i>. pp.&#xA0;1&#x2013;6. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1109%2FSNPD.2015.7176229\">10.1109/SNPD.2015.7176229</a>. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1-4799-8676-7\"><bdi>978-1-4799-8676-7</bdi></a>. <a href=\"https://en.wikipedia.org/wiki/S2CID_(identifier)\" class=\"mw-redirect\">S2CID</a>&#xA0;<a class=\"external text\" href=\"https://api.semanticscholar.org/CorpusID:15516195\">15516195</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-:0-157\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-:0_157-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-:0_157-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-:0_157-2\"><sup><i><b>c</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFGervaisKarameCapkunCapkun\" class=\"citation web cs1\">Gervais, Arthur; Karame, Ghassan O.; Capkun, Vedran; Capkun, Srdjan. <a class=\"external text\" href=\"https://www.infoq.com/articles/is-bitcoin-a-decentralized-currency/\">&quot;Is Bitcoin a Decentralized Currency?&quot;</a>. <i>InfoQ</i>. InfoQ &amp; <a href=\"https://en.wikipedia.org/wiki/IEEE_Computer_Society\">IEEE Computer Society</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20161010042659/https://www.infoq.com/articles/is-bitcoin-a-decentralized-currency/\">Archived</a> from the original on 10 October 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 October</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-158\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-158\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWilhelm\" class=\"citation news cs1\">Wilhelm, Alex. <a class=\"external text\" href=\"https://techcrunch.com/2014/07/16/popular-bitcoin-mining-pool-promises-to-restrict-its-compute-power-to-prevent-feared-51-fiasco/\">&quot;Popular Bitcoin Mining Pool Promises To Restrict Its Compute Power To Prevent Feared &apos;51%&apos; Fiasco&quot;</a>. <i>TechCrunch</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20171205042008/https://techcrunch.com/2014/07/16/popular-bitcoin-mining-pool-promises-to-restrict-its-compute-power-to-prevent-feared-51-fiasco/\">Archived</a> from the original on 5 December 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">25 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-159\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-159\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFChan\" class=\"citation web cs1\">Chan, Edwin. <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2019-04-09/china-plans-to-ban-cryptocurrency-mining-in-renewed-clampdown\">&quot;China Plans to Ban Cryptocurrency Mining in Renewed Clampdown&quot;</a>. <i>www.bloomberg.com</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20191218152525/https://www.bloomberg.com/news/articles/2019-04-09/china-plans-to-ban-cryptocurrency-mining-in-renewed-clampdown\">Archived</a> from the original on 18 December 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 April</span> 2019</span>. <q>While China was once home to about 70 percent of Bitcoin mining and 90 percent of trades, authorities have waged a nearly two-year campaign to shrink the crypto industry amid concerns over speculative bubbles, fraud and wasteful energy consumption.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-160\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-160\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSimonite,_Tom2013\" class=\"citation web cs1\">Simonite, Tom (5 September 2013). <a class=\"external text\" href=\"https://www.technologyreview.com/2013/09/05/176558/mapping-the-bitcoin-economy-could-reveal-users-identities/\">&quot;Mapping the Bitcoin Economy Could Reveal Users&apos; Identities&quot;</a>. <i>MIT Technology Review</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-5facts-161\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-5facts_161-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLee,_Timothy2013\" class=\"citation news cs1\">Lee, Timothy (21 August 2013). <a class=\"external text\" href=\"https://www.washingtonpost.com/blogs/the-switch/wp/2013/08/21/five-surprising-facts-about-bitcoin-2/\">&quot;Five surprising facts about Bitcoin&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20131012035053/http://www.washingtonpost.com/blogs/the-switch/wp/2013/08/21/five-surprising-facts-about-bitcoin-2/\">Archived</a> from the original on 12 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-162\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-162\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMcMillan,_Robert2013\" class=\"citation web cs1\">McMillan, Robert (6 June 2013). <a class=\"external text\" href=\"https://www.wired.com/2013/06/bitcoin-retai/\">&quot;How Bitcoin lets you spy on careless companies&quot;</a>. <i>wired.co.uk</i>. Conde Nast. <a class=\"external text\" href=\"https://web.archive.org/web/20140209202222/http://www.wired.co.uk/news/archive/2013-06/06/bitcoin-retail\">Archived</a> from the original on 9 February 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 April</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-163\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-163\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBen-SassonChiesaGarmanGreen2014\" class=\"citation web cs1\">Ben-Sasson, Eli; Chiesa, Alessandro; Garman, Christina; Green, Matthew; Miers, Ian; Tromer, Eran; Virza, Madars (2014). <a class=\"external text\" href=\"http://zerocash-project.org/media/pdf/zerocash-oakland2014.pdf\">&quot;Zerocash: Decentralized Anonymous Payments from Bitcoin&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>2014 IEEE Symposium on Security and Privacy</i>. IEEE computer society. <a class=\"external text\" href=\"https://web.archive.org/web/20141014012438/http://zerocash-project.org/media/pdf/zerocash-oakland2014.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 14 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 October</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-164\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-164\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFM&#xF6;serB&#xF6;hmeBreuker2013\" class=\"citation conference cs1\">M&#xF6;ser, Malte; B&#xF6;hme, Rainer; Breuker, Dominic (2013). <a class=\"external text\" href=\"https://maltemoeser.de/paper/money-laundering.pdf\"><i>An Inquiry into Money Laundering Tools in the Bitcoin Ecosystem</i></a> <span class=\"cs1-format\">(PDF)</span>. 2013 APWG eCrime Researchers Summit. <a href=\"https://en.wikipedia.org/wiki/Institute_of_Electrical_and_Electronics_Engineers\">IEEE</a>. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1-4799-1158-5\"><bdi>978-1-4799-1158-5</bdi></a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180626110754/https://maltemoeser.de/paper/money-laundering.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 26 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 June</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-BitIdeo-165\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BitIdeo_165-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BitIdeo_165-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFFeuer2013\" class=\"citation news cs1\">Feuer, Alan (14 December 2013). <a class=\"external text\" href=\"https://www.nytimes.com/2013/12/15/sunday-review/the-bitcoin-ideology.html\">&quot;The Bitcoin Ideology&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180701222302/https://www.nytimes.com/2013/12/15/sunday-review/the-bitcoin-ideology.html\">Archived</a> from the original on 1 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-166\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-166\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFriedrich_von_Hayek1976\" class=\"citation book cs1\"><a href=\"https://en.wikipedia.org/wiki/Friedrich_von_Hayek\" class=\"mw-redirect\">Friedrich von Hayek</a> (October 1976). <a class=\"external text\" href=\"https://archive.org/details/denationalisatio0000haye\"><i>Denationalisation of Money: The Argument Refined</i></a>. 2 Lord North Street, Westminster, London SWIP 3LB: The institute of economic affairs. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-0-255-36239-9\"><bdi>978-0-255-36239-9</bdi></a>. <a class=\"external text\" href=\"https://web.archive.org/web/20200111013930/https://archive.org/details/denationalisatio0000haye\">Archived</a> from the original on 11 January 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 September</span> 2015</span>.</cite><span class=\"Z3988\"></span><span class=\"cs1-maint citation-comment\">CS1 maint: location (<a href=\"https://en.wikipedia.org/wiki/Category:CS1_maint:_location\">link</a>)</span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ECB-167\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ECB_167-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFEuropean_Central_Bank2012\" class=\"citation book cs1\">European Central Bank (October 2012). <a class=\"external text\" href=\"http://www.ecb.europa.eu/pub/pdf/other/virtualcurrencyschemes201210en.pdf\"><i>Virtual Currency Schemes</i></a> <span class=\"cs1-format\">(PDF)</span>. Frankfurt am Main: European Central Bank. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-92-899-0862-7\"><bdi>978-92-899-0862-7</bdi></a>. <a class=\"external text\" href=\"https://web.archive.org/web/20121106053452/http://www.ecb.europa.eu/pub/pdf/other/virtualcurrencyschemes201210en.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 6 November 2012.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-30082018Economist-168\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-30082018Economist_168-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-30082018Economist_168-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.economist.com/leaders/2018/08/30/bitcoin-and-other-cryptocurrencies-are-useless\">&quot;Bitcoin and other cryptocurrencies are useless&quot;</a>. <i>The Economist</i>. 30 August 2018. <a class=\"external text\" href=\"https://web.archive.org/web/20180904040905/https://www.economist.com/leaders/2018/08/30/bitcoin-and-other-cryptocurrencies-are-useless\">Archived</a> from the original on 4 September 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">4 September</span> 2018</span>. <q>Lack of adoption and loads of volatility mean that cryptocurrencies satisfy none of those criteria.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Krugman-169\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Krugman_169-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Krugman_169-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFKrugman2018\" class=\"citation news cs1\">Krugman, Paul (29 January 2018). <a class=\"external text\" href=\"https://www.nytimes.com/2018/01/29/opinion/bitcoin-bubble-fraud.html\">&quot;Bubble, Bubble, Fraud and Trouble&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180604124251/https://www.nytimes.com/2018/01/29/opinion/bitcoin-bubble-fraud.html\">Archived</a> from the original on 4 June 2018.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-DecInd-170\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-DecInd_170-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-DecInd_170-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFTourianski\" class=\"citation web cs1\">Tourianski, Julia. <a class=\"external text\" href=\"https://archive.org/details/DECLARATION_201508\">&quot;The Declaration Of Bitcoin&apos;s Independence&quot;</a>. <i>Archive.org</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190323085106/https://archive.org/details/DECLARATION_201508\">Archived</a> from the original on 23 March 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-DoddLSE-171\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-DoddLSE_171-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-DoddLSE_171-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFDodd2017\" class=\"citation web cs1\">Dodd, Nigel (2017). <a class=\"external text\" href=\"http://eprints.lse.ac.uk/69229/1/Dodd_The%20social%20life%20of%20Bitcoin_author_2017%20LSERO.pdf\">&quot;The social life of Bitcoin&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>LSE Research Online</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180701222330/http://eprints.lse.ac.uk/69229/1/Dodd_The%20social%20life%20of%20Bitcoin_author_2017%20LSERO.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 1 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Golumbia1-172\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Golumbia1_172-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGolumbia2015\" class=\"citation book cs1\">Golumbia, David (2015).  Lovink, Geert (ed.). <i>Bitcoin as Politics: Distributed Right-Wing Extremism</i>. Institute of Network Cultures, Amsterdam. pp.&#xA0;117&#x2013;131. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-90-822345-5-8\"><bdi>978-90-822345-5-8</bdi></a>. <a href=\"https://en.wikipedia.org/wiki/SSRN_(identifier)\" class=\"mw-redirect\">SSRN</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://ssrn.com/abstract=2589890\">2589890</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-NYTBannon-173\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NYTBannon_173-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPetersPopper2018\" class=\"citation news cs1\">Peters, Jeremy W.; Popper, Nathaniel (14 June 2018). <a class=\"external text\" href=\"https://www.nytimes.com/2018/06/14/technology/steve-bannon-bitcoin.html\">&quot;Stephen Bannon Buys Into Bitcoin&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180701015803/https://www.nytimes.com/2018/06/14/technology/steve-bannon-bitcoin.html\">Archived</a> from the original on 1 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-uok-174\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-uok_174-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-uok_174-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFMatthew_Graham_WilsonAaron_Yelowitz2014\" class=\"citation journal cs1\">Matthew Graham Wilson &amp; Aaron Yelowitz (November 2014). &quot;Characteristics of Bitcoin Users: An Analysis of Google Search Data&quot;. <i>Social Science Research Network</i>. Working Papers Series. <a href=\"https://en.wikipedia.org/wiki/SSRN_(identifier)\" class=\"mw-redirect\">SSRN</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://ssrn.com/abstract=2518603\">2518603</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Monetarists-176\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Monetarists_176-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Monetarists_176-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"http://www.economist.com/node/21563752\">&quot;Monetarists Anonymous&quot;</a>. <i>The Economist</i>. The Economist Newspaper Limited. 29 September 2012. <a class=\"external text\" href=\"https://web.archive.org/web/20131020192331/http://www.economist.com/node/21563752\">Archived</a> from the original on 20 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 October</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ec1305-177\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ec1305_177-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ec1305_177-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.economist.com/news/business/21638124-minting-digital-currency-has-become-big-ruthlessly-competitive-business-magic\">&quot;The magic of mining&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/The_Economist\">The Economist</a></i>. 13 January 2015. <a class=\"external text\" href=\"https://web.archive.org/web/20150112165531/http://www.economist.com/news/business/21638124-minting-digital-currency-has-become-big-ruthlessly-competitive-business-magic\">Archived</a> from the original on 12 January 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 January</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-econ315-178\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econ315_178-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-econ315_178-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.economist.com/news/finance-and-economics/21599053-chronic-deflation-may-keep-bitcoin-displacing-its-fiat-rivals-money\">&quot;Free Exchange. Money from nothing. Chronic deflation may keep Bitcoin from displacing its rivals&quot;</a>. <i>The Economist</i>. 15 March 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20140325085119/http://www.economist.com/news/finance-and-economics/21599053-chronic-deflation-may-keep-bitcoin-displacing-its-fiat-rivals-money\">Archived</a> from the original on 25 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">25 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Shiller-179\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Shiller_179-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Shiller_179-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFShiller2014\" class=\"citation news cs1\">Shiller, Robert (1 March 2014). <a class=\"external text\" href=\"https://www.nytimes.com/2014/03/02/business/in-search-of-a-stable-electronic-currency.html\">&quot;In Search of a Stable Electronic Currency&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20141024120222/http://www.nytimes.com/2014/03/02/business/in-search-of-a-stable-electronic-currency.html\">Archived</a> from the original on 24 October 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-FT08062018-180\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-FT08062018_180-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-FT08062018_180-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFMurphy2018\" class=\"citation news cs1\">Murphy, Hannah (8 June 2018). <a class=\"external text\" href=\"https://www.ft.com/content/29259448-69b3-11e8-b6eb-4acfcfb08c11\">&quot;Who really owns bitcoin now?&quot;</a>. <i>Financial Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180610051316/https://www.ft.com/content/29259448-69b3-11e8-b6eb-4acfcfb08c11\">Archived</a> from the original on 10 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-181\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-181\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKarkaria2014\" class=\"citation web cs1\">Karkaria, Urvaksh (23 September 2014). <a class=\"external text\" href=\"http://www.bizjournals.com/atlanta/blog/atlantech/2014/09/atlanta-based-bitpay-hooks-up-with-paypal-to.html\">&quot;Atlanta-based BitPay hooks up with PayPal to expand bitcoin adoption&quot;</a>. <i>Atlanta Business Chronicle</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20141026224207/http://www.bizjournals.com/atlanta/blog/atlantech/2014/09/atlanta-based-bitpay-hooks-up-with-paypal-to.html\">Archived</a> from the original on 26 October 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-182\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-182\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKatz2017\" class=\"citation web cs1\">Katz, Lily (12 July 2017). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2017-07-12/bitcoin-acceptance-among-retailers-is-low-and-getting-lower\">&quot;Bitcoin Acceptance Among Retailers Is Low and Getting Lower&quot;</a>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20180125204553/https://www.bloomberg.com/news/articles/2017-07-12/bitcoin-acceptance-among-retailers-is-low-and-getting-lower\">Archived</a> from the original on 25 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">25 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-impractical-183\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-impractical_183-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKharif2018\" class=\"citation news cs1\">Kharif, Olga (1 August 2018). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2018-08-01/bitcoin-s-use-in-commerce-keeps-falling-even-as-volatility-eases\">&quot;Bitcoin&apos;s Use in Commerce Keeps Falling Even as Volatility Eases&quot;</a>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20180802073219/https://www.bloomberg.com/news/articles/2018-08-01/bitcoin-s-use-in-commerce-keeps-falling-even-as-volatility-eases\">Archived</a> from the original on 2 August 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 August</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-184\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-184\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFChan2015\" class=\"citation news cs1\">Chan, Bernice (16 January 2015). <a class=\"external text\" href=\"https://www.scmp.com/lifestyle/technology/article/1679904/bitcoin-transactions-cut-cost-international-money-transfers\">&quot;Bitcoin transactions cut the cost of international money transfers&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/South_China_Morning_Post\">South China Morning Post</a></i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190531060301/https://www.scmp.com/lifestyle/technology/article/1679904/bitcoin-transactions-cut-cost-international-money-transfers\">Archived</a> from the original on 31 May 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 May</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-185\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-185\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.theguardian.com/world/2014/apr/10/bitcoin-dumped-by-national-australia-bank-as-too-risky\">&quot;Bitcoin firms dumped by National Australia Bank as &apos;too risky<span class=\"cs1-kern-right\">&apos;</span>&quot;</a>. <i>The Guardian</i>. Australian Associated Press. 10 April 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20150223011000/http://www.theguardian.com/world/2014/apr/10/bitcoin-dumped-by-national-australia-bank-as-too-risky\">Archived</a> from the original on 23 February 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 February</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-186\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-186\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWeir,_Mike2014\" class=\"citation web cs1\">Weir, Mike (1 December 2014). <a class=\"external text\" href=\"https://www.bbc.com/news/world-europe-jersey-30261976\">&quot;HSBC severs links with firm behind Bitcoin fund&quot;</a>. <i>bbc.com</i>. BBC. <a class=\"external text\" href=\"https://web.archive.org/web/20150203210318/http://www.bbc.com/news/world-europe-jersey-30261976\">Archived</a> from the original on 3 February 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 January</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-afr.com-187\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-afr.com_187-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.afr.com/technology/accc-investigating-why-banks-are-closing-bitcoin-companies-accounts-20151018-gkc5iv\">&quot;ACCC investigating why banks are closing bitcoin companies&apos; accounts&quot;</a>. <i>Financial Review</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20160211070834/http://www.afr.com/technology/accc-investigating-why-banks-are-closing-bitcoin-companies-accounts-20151018-gkc5iv\">Archived</a> from the original on 11 February 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 January</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-188\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-188\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.cbsnews.com/news/bitcoin-futures-price-surge-in-first-day-of-trading/\">&quot;Bitcoin futures surge in first day of trading&quot;</a>. <i>CBS News</i>. 11 December 2017. <a class=\"external text\" href=\"https://web.archive.org/web/20190531054558/https://www.cbsnews.com/news/bitcoin-futures-price-surge-in-first-day-of-trading/\">Archived</a> from the original on 31 May 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 May</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-189\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-189\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.cbsnews.com/news/chicago-mercantile-exchange-jumps-into-bitcoin-futures/\">&quot;Chicago Mercantile Exchange jumps into bitcoin futures&quot;</a>. <i>CBS News</i>. 18 December 2017. <a class=\"external text\" href=\"https://web.archive.org/web/20190531054602/https://www.cbsnews.com/news/chicago-mercantile-exchange-jumps-into-bitcoin-futures/\">Archived</a> from the original on 31 May 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 May</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-190\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-190\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2019-09-26/venezuela-has-bitcoin-stash-and-doesn-t-know-what-to-do-with-it\">&quot;Venezuela Has Bitcoin Stash and Doesn&apos;t Know What to Do With It&quot;</a>. <i>Bloomberg</i>. 26 September 2019. <a class=\"external text\" href=\"https://web.archive.org/web/20190926180923/https://www.bloomberg.com/news/articles/2019-09-26/venezuela-has-bitcoin-stash-and-doesn-t-know-what-to-do-with-it\">Archived</a> from the original on 26 September 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 September</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-191\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-191\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLee\" class=\"citation news cs1\">Lee, Timothy B. <a class=\"external text\" href=\"https://www.washingtonpost.com/news/the-switch/wp/2013/11/09/the-11-million-in-bitcoins-the-winklevoss-brothers-bought-is-now-worth-32-million/\">&quot;The $11 million in bitcoins the Winklevoss brothers bought is now worth $32 million&quot;</a>. <i>The Switch</i>. The Washington Post. <a class=\"external text\" href=\"https://web.archive.org/web/20170706111658/https://www.washingtonpost.com/news/the-switch/wp/2013/11/09/the-11-million-in-bitcoins-the-winklevoss-brothers-bought-is-now-worth-32-million/\">Archived</a> from the original on 6 July 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 August</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-BitcoinJersey-192\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-BitcoinJersey_192-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.bbc.com/news/world-europe-jersey-28247796\">&quot;Jersey approve Bitcoin fund launch on island&quot;</a>. <i>BBC news</i>. 10 July 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20140710211917/http://www.bbc.com/news/world-europe-jersey-28247796\">Archived</a> from the original on 10 July 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 July</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-193\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-193\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHill\" class=\"citation news cs1\">Hill, Kashmir. <a class=\"external text\" href=\"https://www.forbes.com/sites/kashmirhill/2013/12/26/how-you-should-have-spent-100-in-2013-hint-bitcoin/\">&quot;How You Should Have Spent $100 In 2013 (Hint: Bitcoin)&quot;</a>. <i>Forbes</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20150219043444/http://www.forbes.com/sites/kashmirhill/2013/12/26/how-you-should-have-spent-100-in-2013-hint-bitcoin/\">Archived</a> from the original on 19 February 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 February</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-worst-194\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-worst_194-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSteverman,_Ben2014\" class=\"citation news cs1\">Steverman, Ben (23 December 2014). <a class=\"external text\" href=\"https://www.bloomberg.com/news/2014-12-22/the-best-and-worst-investments-of-2014.html\">&quot;The Best and Worst Investments of 2014&quot;</a>. <i>bloomberg.com</i>. Bloomberg LP. <a class=\"external text\" href=\"https://web.archive.org/web/20150109122649/http://www.bloomberg.com/news/2014-12-22/the-best-and-worst-investments-of-2014.html\">Archived</a> from the original on 9 January 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 January</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-195\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-195\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGilbert2015\" class=\"citation news cs1\">Gilbert, Mark (29 December 2015). <a class=\"external text\" href=\"http://www.bloombergview.com/articles/2015-12-29/bitcoin-won-in-2015-but-apple-lost-big\">&quot;Bitcoin Won 2015. Apple ... Did Not&quot;</a>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20151229200002/http://www.bloombergview.com/articles/2015-12-29/bitcoin-won-in-2015-but-apple-lost-big\">Archived</a> from the original on 29 December 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">29 December</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-196\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-196\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitinfocharts.com/top-100-richest-bitcoin-addresses.html\">&quot;Top 100 Richest Bitcoin Addresses and Bitcoin distribution&quot;</a>. <i>bitinfocharts.com</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20171015082601/https://bitinfocharts.com/top-100-richest-bitcoin-addresses.html\">Archived</a> from the original on 15 October 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 October</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-197\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-197\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.benzinga.com/markets/cryptocurrency/20/12/18663624/microstrategy-buys-50-million-worth-of-bitcoin-topping-up-holdings-to-766m\">&quot;MicroStrategy Buys $50 Million Worth Of Bitcoin, Topping Up Holdings To $766M&quot;</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-198\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-198\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.bizjournals.com/washington/news/2020/08/11/microstratregy-buys-250m-in-bitcoin.html\">&quot;MicroStrategy buys $250M in Bitcoin as CEO says it&apos;s superior to cash&quot;</a>. <i>Washington Business Journal</i>. 11 August 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 August</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-199\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-199\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWilson2021\" class=\"citation web cs1\">Wilson, Tom (18 May 2021). <a class=\"external text\" href=\"https://www.reuters.com/article/us-crypto-currency-altcoins/buyers-beware-as-altcoin-frenzy-bruises-bitcoin-idUSKCN2CZ1N6\">&quot;Buyers beware as &quot;altcoin&quot; frenzy bruises bitcoin&quot;</a>. <i>Reuters</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 May</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-mtr20130612-200\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-mtr20130612_200-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSimonite,_Tom2013\" class=\"citation news cs1\">Simonite, Tom (12 June 2013). <a class=\"external text\" href=\"https://www.technologyreview.com/2013/06/12/15919/bitcoin-millionaires-become-investing-angels/\">&quot;Bitcoin Millionaires Become Investing Angels&quot;</a>. <i>Computing News</i>. <a href=\"https://en.wikipedia.org/wiki/MIT_Technology_Review\">MIT Technology Review</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 June</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-wsj1214-201\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-wsj1214_201-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-wsj1214_201-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFRobin_Sidel2014\" class=\"citation news cs1\">Robin Sidel (1 December 2014). <a class=\"external text\" href=\"https://www.wsj.com/news/articles/SB21659981523255993497704580305120918936264\">&quot;Ten-hut! Bitcoin Recruits Snap To&quot;</a>. <i>The Wall Street Journal</i>. Dow Jones &amp; Company<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 December</span> 2014</span>.</cite><span class=\"Z3988\"></span><sup class=\"noprint Inline-Template\"><span>[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Link_rot\"><span>dead link</span></a></i>]</span></sup></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-guard714-202\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-guard714_202-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAlex_Hern2014\" class=\"citation news cs1\">Alex Hern (1 July 2014). <a class=\"external text\" href=\"https://www.theguardian.com/technology/2014/jul/01/silk-road-bitcoin-auction\">&quot;Silk Road&apos;s legacy 30,000 bitcoin sold at auction to mystery buyers&quot;</a>. <i>The Guardian</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20141023190952/http://www.theguardian.com/technology/2014/jul/01/silk-road-bitcoin-auction\">Archived</a> from the original on 23 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 October</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-203\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-203\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"http://www.redherring.com/finance/coinseed-raises-7-5m-invests-5m-in-bitcoin-mining-hardware-investment-round-up/\">&quot;CoinSeed raises $7.5m, invests $5m in Bitcoin mining hardware &#x2013; Investment Round Up&quot;</a>. <i>Red Herring</i>. 24 January 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20140309042510/http://www.redherring.com/finance/coinseed-raises-7-5m-invests-5m-in-bitcoin-mining-hardware-investment-round-up/\">Archived</a> from the original on 9 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Tasca-204\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Tasca_204-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Tasca_204-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFTasca2015\" class=\"citation cs2\">Tasca, Paolo (7 September 2015), <i>Digital Currencies: Principles, Trends, Opportunities, and Risks</i>, Social Science Research Network, <a href=\"https://en.wikipedia.org/wiki/SSRN_(identifier)\" class=\"mw-redirect\">SSRN</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://ssrn.com/abstract=2657598\">2657598</a></span></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-205\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-205\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMoore,_Heidi2013\" class=\"citation web cs1\">Moore, Heidi (3 April 2013). <a class=\"external text\" href=\"https://www.theguardian.com/commentisfree/2013/apr/03/bitcoin-currency-bubble-crash-not-rocking-financial-markets\">&quot;Confused about Bitcoin? It&apos;s &apos;the Harlem Shake of currency<span class=\"cs1-kern-right\">&apos;</span>&quot;</a>. <i>The Guardian</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140301083816/http://www.theguardian.com/commentisfree/2013/apr/03/bitcoin-currency-bubble-crash-not-rocking-financial-markets\">Archived</a> from the original on 1 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 May</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Leebubble-206\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Leebubble_206-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLee,_Timothy2013\" class=\"citation news cs1\">Lee, Timothy (5 November 2013). <a class=\"external text\" href=\"https://www.washingtonpost.com/blogs/the-switch/wp/2013/11/05/when-will-the-people-who-called-bitcoin-a-bubble-admit-they-were-wrong\">&quot;When will the people who called Bitcoin a bubble admit they were wrong&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140111011839/http://www.washingtonpost.com/blogs/the-switch/wp/2013/11/05/when-will-the-people-who-called-bitcoin-a-bubble-admit-they-were-wrong/\">Archived</a> from the original on 11 January 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-207\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-207\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLiu2013\" class=\"citation web cs1\">Liu, Alec (19 March 2013). <a class=\"external text\" href=\"https://www.vice.com/en/article/ypp9v5/cyprus-spain-when-governments-take-your-money-bitcoin-looks-really-good\">&quot;When Governments Take Your Money, Bitcoin Looks Really Good&quot;</a>. Motherboard. <a class=\"external text\" href=\"https://web.archive.org/web/20140207194506/http://motherboard.vice.com/blog/cyprus-spain-when-governments-take-your-money-bitcoin-looks-really-good\">Archived</a> from the original on 7 February 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-208\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-208\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBen_Rooney2013\" class=\"citation news cs1\">Ben Rooney (29 November 2013). <a class=\"external text\" href=\"https://money.cnn.com/2013/11/29/investing/bitcoin-gold/index.html\">&quot;Bitcoin worth almost as much as gold&quot;</a>. CNN. <a class=\"external text\" href=\"https://web.archive.org/web/20141026213248/https://money.cnn.com/2013/11/29/investing/bitcoin-gold/index.html\">Archived</a> from the original on 26 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 October</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-209\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-209\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.nasdaq.com/article/bitcoin-prices-remain-below-600-amid-bearish-chart-signals-cm376685\">&quot;Bitcoin prices remain below $600 amid bearish chart signals&quot;</a>. nasdaq.com. August 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20141014012642/http://www.nasdaq.com/article/bitcoin-prices-remain-below-600-amid-bearish-chart-signals-cm376685\">Archived</a> from the original on 14 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 October</span> 2014</span>.</cite><span class=\"Z3988\"></span>.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-210\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-210\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWilliams,_Mark_T.2014\" class=\"citation web cs1\">Williams, Mark T. (21 October 2014). <a class=\"external text\" href=\"http://management.bu.edu/files/2014/10/Wlliams-World-Bank-10-21-2014.pdf\">&quot;Virtual Currencies &#x2013; Bitcoin Risk&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>World Bank Conference Washington DC</i>. <a href=\"https://en.wikipedia.org/wiki/Boston_University\">Boston University</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20141111095526/http://management.bu.edu/files/2014/10/Wlliams-World-Bank-10-21-2014.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 11 November 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 November</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-211\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-211\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFIrrera2021\" class=\"citation web cs1\">Irrera, Tom Wilson, Anna (11 January 2021). <a class=\"external text\" href=\"https://www.reuters.com/article/us-crypto-currencies-analysis-idUSKBN29G0DV\">&quot;Analysis: Cancel your weekends! Bitcoin doesn&apos;t rest, and neither can you&quot;</a>. <i>Reuters</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20210206170123/https://www.reuters.com/article/us-crypto-currencies-analysis-idUSKBN29G0DV\">Archived</a> from the original on 6 February 2021. <q>Trading volumes across six major cryptocurrency exchanges have been 10% higher at weekends than weekdays in that period</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-212\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-212\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFZaki2021\" class=\"citation web cs1\">Zaki, Myret (14 January 2021). <a class=\"external text\" href=\"https://themarket.ch/meinung/bitcoin-the-derivative-bomb-ld.3398\">&quot;Bitcoin: The Derivative Bomb&quot;</a>. <i>The Market</i> (in German). <a class=\"external text\" href=\"https://web.archive.org/web/20210115081742/https://themarket.ch/meinung/bitcoin-the-derivative-bomb-ld.3398\">Archived</a> from the original on 15 January 2021. <q>the lion&#x2019;s share of institutional trading in bitcoin is being done without owning any single bitcoin. The bitcoin derivative boom was encouraged by the fact that you can get 2 to 3 times leverage on the CME, and more than 100 x leverage on native crypto derivative exchanges. In 2020, the ratio between bitcoin futures and spot volumes has increased from 2,3 to 4,6 in 2019</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-213\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-213\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBambrough2021\" class=\"citation web cs1\">Bambrough, Billy (30 January 2021). <a class=\"external text\" href=\"https://web.archive.org/web/20210209100159/https://www.forbes.com/sites/billybambrough/2021/01/30/bitcoin-price-data-reveals-bitcoin-could-be-about-to-become-the-new-gamestop/\">&quot;Data Reveals Bitcoin Could Be About To Become The New GameStop After Huge Price Spike&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/Forbes\">Forbes</a></i>. Archived from <a class=\"external text\" href=\"https://www.forbes.com/sites/billybambrough/2021/01/30/bitcoin-price-data-reveals-bitcoin-could-be-about-to-become-the-new-gamestop/\">the original</a> on 9 February 2021<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 February</span> 2021</span>. <q>The net short position in bitcoin futures is now the biggest it has ever been, according to the CFTC&apos;s latest Traders in Financial Futures report. .. hedge funds increasingly bet against the bitcoin price</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-214\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-214\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://cftc.gov/dea/futures/financial_lf.htm\">&quot;CFTC Commitments of Traders Short Report - Financial Traders in Markets (Futures Only)&quot;</a>. <i>cftc.gov</i>. <a href=\"https://en.wikipedia.org/wiki/Commodity_Futures_Trading_Commission\">Commodity Futures Trading Commission</a> (CFTC). 2&#x2013;5 February 2021. <a class=\"external text\" href=\"https://web.archive.org/web/20210208113707/https://cftc.gov/dea/futures/financial_lf.htm\">Archived</a> from the original on 8 February 2021. <q>BITCOIN - CHICAGO MERCANTILE EXCHANGE, CFTC Code #133741</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-215\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-215\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.wsj.com/market-data/quotes/fx/BTCUSD/historical-prices\">&quot;WSJ Markets Bitcoin USD&quot;</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">8 February</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-216\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-216\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.pastemagazine.com/articles/2017/09/china-may-be-gearing-up-to-ban-bitcoin.html\">&quot;China May Be Gearing Up to Ban Bitcoin&quot;</a>. <i>pastemagazine.com</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20171003224721/https://www.pastemagazine.com/articles/2017/09/china-may-be-gearing-up-to-ban-bitcoin.html\">Archived</a> from the original on 3 October 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">6 October</span> 2017</span>. <q>The decentralized nature of bitcoin is such that it is impossible to &quot;ban&quot; the cryptocurrency, but if you shut down exchanges and the peer-to-peer economy running on bitcoin, it&apos;s a de facto ban.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-RCAWJune2018LOC-217\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-RCAWJune2018LOC_217-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.loc.gov/law/help/cryptocurrency/cryptocurrency-world-survey.pdf\">&quot;Regulation of Cryptocurrency Around the World&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>Library of Congress</i>. The Law Library of Congress, Global Legal Research Center. June 2018. pp.&#xA0;4&#x2013;5. <a class=\"external text\" href=\"https://web.archive.org/web/20180814071440/https://www.loc.gov/law/help/cryptocurrency/cryptocurrency-world-survey.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 14 August 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 August</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-aawsat202011-218\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-aawsat202011_218-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-aawsat202011_218-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://english.aawsat.com/home/article/2596686/iran-new-crypto-law-requires-selling-bitcoin-directly-central-bank-fund-imports\">&quot;Iran: New Crypto Law Requires Selling Bitcoin Directly to Central Bank to Fund Imports&quot;</a>. <i>aawsat.com</i>. 31 October 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 November</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ViceIran-219\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ViceIran_219-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.vice.com/en/article/qjppx3/iran-bitcoin-us-sanctions\">&quot;Iran Is Pivoting to Bitcoin&quot;</a>. <i>vice.com</i>. 3 November 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 November</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-FPIran-220\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-FPIran_220-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://foreignpolicy.com/2020/01/24/iran-bitcoin-strategy-cryptocurrency-blockchain-sanctions/\">&quot;Iran Has a Bitcoin Strategy to Beat Trump&quot;</a>. <i>foreignpolicy.com</i>. 24 January 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 November</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-JulyCFTC-221\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JulyCFTC_221-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.cftc.gov/sites/default/files/2018-07/customeradvisory_tokens0718.pdf\">&quot;Customer Advisory: Use Caution When Buying Digital Coins or Tokens&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>U.S.Commodity Futures Trading Commission</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180717071031/https://www.cftc.gov/sites/default/files/2018-07/customeradvisory_tokens0718.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 17 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-SECMay2014-222\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-SECMay2014_222-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.investor.gov/additional-resources/news-alerts/alerts-bulletins/investor-alert-bitcoin-other-virtual-currency\">&quot;Investor Alert: Bitcoin and Other Virtual Currency-related Investments&quot;</a>. <i>Investor.gov</i>. <a href=\"https://en.wikipedia.org/wiki/U.S._Securities_and_Exchange_Commission\">U.S. Securities and Exchange Commission</a>. 7 May 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20180630224256/https://www.investor.gov/additional-resources/news-alerts/alerts-bulletins/investor-alert-bitcoin-other-virtual-currency\">Archived</a> from the original on 30 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-SEC2-223\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-SEC2_223-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.sec.gov/investor/alerts/ia_virtualcurrencies.pdf\">&quot;Ponzi schemes Using virtual Currencies&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>sec.gov</i>. <a href=\"https://en.wikipedia.org/wiki/U.S._Securities_and_Exchange_Commission\">U.S. Securities and Exchange Commission</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180616111648/https://www.sec.gov/investor/alerts/ia_virtualcurrencies.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 16 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-ebawarn-224\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-ebawarn_224-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.webcitation.org/6MCBOsSXG?url=http://www.eba.europa.eu/documents/10180/16136/EBA+Warning+on+Virtual+Currencies.pdf\">&quot;Warning to consumers on virtual currencies&quot;</a> <span class=\"cs1-format\">(PDF)</span>. European Banking Authority. 12 December 2013. Archived from <a class=\"external text\" href=\"http://www.eba.europa.eu/documents/10180/16136/EBA+Warning+on+Virtual+Currencies.pdf\">the original</a> <span class=\"cs1-format\">(PDF)</span> on 28 December 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 December</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-225\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-225\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.finra.org/investors/alerts/dont-fall-cryptocurrency-related-stock-scams\">&quot;Investor Alerts Don&apos;t Fall for Cryptocurrency-Related Stock Scams&quot;</a>. <i>FINRA.org</i>. Financial Industry Regulatory Authority. 21 December 2017. <a class=\"external text\" href=\"https://web.archive.org/web/20180701195236/http://www.finra.org/investors/alerts/dont-fall-cryptocurrency-related-stock-scams\">Archived</a> from the original on 1 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-226\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-226\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.nasaa.org/44848/informed-investor-advisory-cryptocurrencies/\">&quot;Informed Investor Advisory: Cryptocurrencies&quot;</a>. North American Securities Administrators Association. April 2018. <a class=\"external text\" href=\"https://web.archive.org/web/20180723182210/http://www.nasaa.org/44848/informed-investor-advisory-cryptocurrencies/\">Archived</a> from the original on 23 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Times05252018-227\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Times05252018_227-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDean2018\" class=\"citation news cs1\">Dean, James (25 May 2018). <a class=\"external text\" href=\"https://www.thetimes.co.uk/article/bitcoin-investigation-to-focus-on-british-traders-c58brwn60\">&quot;Bitcoin investigation to focus on British traders, US officials examine manipulation of cryptocurrency prices&quot;</a>. <i>The Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180525101341/https://www.thetimes.co.uk/article/bitcoin-investigation-to-focus-on-british-traders-c58brwn60\">Archived</a> from the original on 25 May 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">25 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-chloeFT-228\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-chloeFT_228-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFCornish2018\" class=\"citation news cs1\">Cornish, Chloe (24 May 2018). <a class=\"external text\" href=\"https://www.ft.com/content/5d8f06f2-5f3a-11e8-9334-2218e7146b04\">&quot;Bitcoin slips again on reports of US DoJ investigation&quot;</a>. <i>Financial Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180524222527/https://www.ft.com/content/5d8f06f2-5f3a-11e8-9334-2218e7146b04\">Archived</a> from the original on 24 May 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Bloom052418-229\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Bloom052418_229-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRobinsonSchoenberg2018\" class=\"citation news cs1\">Robinson, Matt; Schoenberg, Tom (24 May 2018). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2018-05-24/bitcoin-manipulation-is-said-to-be-focus-of-u-s-criminal-probe\">&quot;U.S. Launches Criminal Probe into Bitcoin Price Manipulation&quot;</a>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20180524082123/https://www.bloomberg.com/news/articles/2018-05-24/bitcoin-manipulation-is-said-to-be-focus-of-u-s-criminal-probe\">Archived</a> from the original on 24 May 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-USAT05242018-230\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-USAT05242018_230-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMcCoy2018\" class=\"citation news cs1\">McCoy, Kevin (24 May 2018). <a class=\"external text\" href=\"https://www.usatoday.com/story/money/2018/05/24/bitcoin-value-gyrates-after-report-department-justice-probe/640289002/\">&quot;Bitcoin value gyrates amid report of Department of Justice manipulation investigation&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/USA_Today\">USA Today</a></i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180524205443/https://www.usatoday.com/story/money/2018/05/24/bitcoin-value-gyrates-after-report-department-justice-probe/640289002/\">Archived</a> from the original on 24 May 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">25 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-MWmanipulation-231\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-MWmanipulation_231-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRubinMichaelsOsipovich2018\" class=\"citation web cs1\">Rubin, Gabriel T.; Michaels, Dave; Osipovich, Alexander (8 June 2018). <a class=\"external text\" href=\"https://www.marketwatch.com/story/us-regulators-demand-trading-data-from-bitcoin-exchanges-in-manipulation-probe-2018-06-08\">&quot;U.S. regulators demand trading data from bitcoin exchanges in manipulation probe&quot;</a>. <i>MarketWatch</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180608214458/https://www.marketwatch.com/story/us-regulators-demand-trading-data-from-bitcoin-exchanges-in-manipulation-probe-2018-06-08\">Archived</a> from the original on 8 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 June</span> 2018</span>.</cite><span class=\"Z3988\"></span> Note:this is a short open access version of a Wall Street Journal article</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-WSJmanipulation-232\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-WSJmanipulation_232-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRubinMichaelsOsipovich2018\" class=\"citation news cs1\">Rubin, Gabriel T.; Michaels, Dave; Osipovich, Alexander (8 June 2018). <a class=\"external text\" href=\"https://www.wsj.com/articles/u-s-regulators-demand-trading-data-from-bitcoin-exchanges-in-manipulation-probe-1528492835\">&quot;U.S. regulators demand trading data from bitcoin exchanges in manipulation probe&quot;</a>. <i>The Wall Street Journal</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180608233342/https://www.wsj.com/articles/u-s-regulators-demand-trading-data-from-bitcoin-exchanges-in-manipulation-probe-1528492835\">Archived</a> from the original on 8 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 June</span> 2018</span>.</cite><span class=\"Z3988\"></span> (paywalled)</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-WaPo52118-233\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-WaPo52118_233-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFung2018\" class=\"citation news cs1\">Fung, Brian (21 May 2018). <a class=\"external text\" href=\"https://www.washingtonpost.com/news/the-switch/wp/2018/05/21/state-regulators-unveil-nationwide-crackdown-on-suspicious-cryptocurrency-investment-schemes/\">&quot;State regulators unveil nationwide crackdown on suspicious cryptocurrency investment schemes&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180527081727/https://www.washingtonpost.com/news/the-switch/wp/2018/05/21/state-regulators-unveil-nationwide-crackdown-on-suspicious-cryptocurrency-investment-schemes/\">Archived</a> from the original on 27 May 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">27 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-JME-234\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-JME_234-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGandalHamrickMooreOberman2018\" class=\"citation journal cs1\">Gandal, Neil; Hamrick, J.T.; Moore, Tyler; Oberman, Tali (May 2018). &quot;Price manipulation in the Bitcoin ecosystem&quot;. <i><a href=\"https://en.wikipedia.org/wiki/Journal_of_Monetary_Economics\">Journal of Monetary Economics</a></i>. <b>95</b>: 86&#x2013;96. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1016%2Fj.jmoneco.2017.12.004\">10.1016/j.jmoneco.2017.12.004</a>. <a href=\"https://en.wikipedia.org/wiki/S2CID_(identifier)\" class=\"mw-redirect\">S2CID</a>&#xA0;<a class=\"external text\" href=\"https://api.semanticscholar.org/CorpusID:26358036\">26358036</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-235\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-235\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLee2017\" class=\"citation web cs1\">Lee, Tim (12 December 2017). <a class=\"external text\" href=\"https://arstechnica.com/tech-policy/2017/12/a-brief-history-of-bitcoin-hacks-and-frauds/\">&quot;A brief history of Bitcoin hacks and frauds&quot;</a>. <i>Ars Technica</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180528051930/https://arstechnica.com/tech-policy/2017/12/a-brief-history-of-bitcoin-hacks-and-frauds/\">Archived</a> from the original on 28 May 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">27 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-untethered-236\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-untethered_236-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGriffinShams2018\" class=\"citation journal cs1\">Griffin, John M.; Shams, Amin (13 June 2018). &quot;Is Bitcoin Really Un-Tethered?&quot;. <i>Social Science Research Network</i>. <a href=\"https://en.wikipedia.org/wiki/SSRN_(identifier)\" class=\"mw-redirect\">SSRN</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://ssrn.com/abstract=3195066\">3195066</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Artynyt-237\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Artynyt_237-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPopper2018\" class=\"citation news cs1\">Popper, Nathaniel (13 June 2018). <a class=\"external text\" href=\"https://www.nytimes.com/2018/06/13/technology/bitcoin-price-manipulation.html\">&quot;Bitcoin&apos;s Price Was Artificially Inflated Last Year, Researchers Say&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180613100732/https://www.nytimes.com/2018/06/13/technology/bitcoin-price-manipulation.html\">Archived</a> from the original on 13 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-WaPoVdV-238\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-WaPoVdV_238-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFShaban2018\" class=\"citation news cs1\">Shaban, Hamza (14 June 2018). <a class=\"external text\" href=\"https://www.washingtonpost.com/news/the-switch/wp/2018/06/14/bitcoins-astronomical-rise-last-year-was-buoyed-by-market-manipulation-researchers-say/\">&quot;Bitcoin&apos;s astronomical rise last year was buoyed by market manipulation, researchers say&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180615111336/https://www.washingtonpost.com/news/the-switch/wp/2018/06/14/bitcoins-astronomical-rise-last-year-was-buoyed-by-market-manipulation-researchers-say/\">Archived</a> from the original on 15 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bis_report-239\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bis_report_239-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bis_report_239-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFJanda2018\" class=\"citation news cs1\">Janda, Michael (18 June 2018). <a class=\"external text\" href=\"http://www.abc.net.au/news/2018-06-18/cryptocurrencies-cannot-replace-money-bis/9879448\">&quot;Cryptocurrencies like bitcoin cannot replace money, says Bank for International Settlements&quot;</a>. ABC (Australia). <a class=\"external text\" href=\"https://web.archive.org/web/20180618072225/http://www.abc.net.au/news/2018-06-18/cryptocurrencies-cannot-replace-money-bis/9879448\">Archived</a> from the original on 18 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">18 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-chapterV-240\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-chapterV_240-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHyun_Song_Shin2018\" class=\"citation web cs1\">Hyun Song Shin (June 2018). <a class=\"external text\" href=\"https://www.bis.org/publ/arpdf/ar2018e5.pdf\">&quot;Chapter V. Cryptocurrencies: looking beyond the hype&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>BIS 2018 Annual Economic Report</i>. Bank for International Settlements. <a class=\"external text\" href=\"https://web.archive.org/web/20180618080358/https://www.bis.org/publ/arpdf/ar2018e5.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 18 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 June</span> 2018</span>. <q>Put in the simplest terms, the quest for decentralised trust has quickly become an environmental disaster.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-LATHiltzik-241\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-LATHiltzik_241-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHiltzik2018\" class=\"citation news cs1\">Hiltzik, Michael (18 June 2018). <a class=\"external text\" href=\"https://www.latimes.com/business/hiltzik/la-fi-hiltzik-bitcoin-bank-20180618-story.html\">&quot;Is this scathing report the death knell for bitcoin?&quot;</a>. <i>Los Angeles Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180618233532/http://www.latimes.com/business/hiltzik/la-fi-hiltzik-bitcoin-bank-20180618-story.html\">Archived</a> from the original on 18 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-242\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-242\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFVelde2013\" class=\"citation web cs1\">Velde, Fran&#xE7;ois (December 2013). <a class=\"external text\" href=\"https://www.chicagofed.org/digital_assets/publications/chicago_fed_letter/2013/cfldecember2013_317.pdf\">&quot;Bitcoin: A primer&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>Chicago Fed letter</i>. <a href=\"https://en.wikipedia.org/wiki/Federal_Reserve_Bank_of_Chicago\">Federal Reserve Bank of Chicago</a>. p.&#xA0;4. <a class=\"external text\" href=\"https://web.archive.org/web/20141026065254/http://www.chicagofed.org/digital_assets/publications/chicago_fed_letter/2013/cfldecember2013_317.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 26 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 September</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-243\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-243\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWile,_Rob2014\" class=\"citation web cs1\">Wile, Rob (6 April 2014). <a class=\"external text\" href=\"http://www.businessinsider.com/interview-with-david-andolfatto-2014-4\">&quot;St. Louis Fed Economist: Bitcoin Could Be A Good Threat To Central Banks&quot;</a>. <i>businessinsider.com</i>. Business Insider. <a class=\"external text\" href=\"https://web.archive.org/web/20150924095030/http://www.businessinsider.com/interview-with-david-andolfatto-2014-4\">Archived</a> from the original on 24 September 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-244\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-244\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAndolfatto,_David2013\" class=\"citation web cs1\">Andolfatto, David (24 December 2013). <a class=\"external text\" href=\"http://andolfatto.blogspot.com/2013/12/in-gold-we-trust.html\">&quot;In gold we trust?&quot;</a>. <i>MacroMania</i>. David Andolfatto. <a class=\"external text\" href=\"https://web.archive.org/web/20170412053554/http://andolfatto.blogspot.com/2013/12/in-gold-we-trust.html\">Archived</a> from the original on 12 April 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">17 April</span> 2014</span>. <q>Also, note that I am not against gold or bitcoin (or whatever) as a currency. In fact, I think that the threat that they pose as alternate currency can serve as a useful check on a central bank.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Stiglitz-245\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Stiglitz_245-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFCostelloe2017\" class=\"citation news cs1\">Costelloe, Kevin (29 November 2017). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2017-11-29/bitcoin-ought-to-be-outlawed-nobel-prize-winner-stiglitz-says-jal10hxd\">&quot;Bitcoin &apos;Ought to Be Outlawed,&apos; Nobel Prize Winner Stiglitz Says&quot;</a>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20180612224313/https://www.bloomberg.com/news/articles/2017-11-29/bitcoin-ought-to-be-outlawed-nobel-prize-winner-stiglitz-says-jal10hxd\">Archived</a> from the original on 12 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 June</span> 2018</span>. <q>It doesn&apos;t serve any socially useful function.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Thaler-246\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Thaler_246-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://econews.pt/2018/01/22/economics-nobel-prize-winner-richard-thaler-the-market-that-looks-most-like-a-bubble-to-me-is-bitcoin-and-its-brethren/\">&quot;Economics Nobel prize winner, Richard Thaler: &quot;The market that looks most like a bubble to me is Bitcoin and its brethren<span class=\"cs1-kern-right\">&quot;</span>&quot;</a>. ECO Portuguese Economy. 22 January 2018. <a class=\"external text\" href=\"https://web.archive.org/web/20180612140603/https://econews.pt/2018/01/22/economics-nobel-prize-winner-richard-thaler-the-market-that-looks-most-like-a-bubble-to-me-is-bitcoin-and-its-brethren/\">Archived</a> from the original on 12 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-4Nobels-247\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-4Nobels_247-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-4Nobels_247-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFWolff-Mann2018\" class=\"citation news cs1\">Wolff-Mann, Ethan (27 April 2018). <a class=\"external text\" href=\"https://finance.yahoo.com/news/good-drug-dealers-nobel-prize-winners-snub-bitcoin-184903784.html\">&quot;<span class=\"cs1-kern-left\">&apos;</span>Only good for drug dealers&apos;: More Nobel prize winners snub bitcoin&quot;</a>. <i>Yahoo Finance</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180612141128/https://finance.yahoo.com/news/good-drug-dealers-nobel-prize-winners-snub-bitcoin-184903784.html\">Archived</a> from the original on 12 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-248\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-248\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.theguardian.com/technology/2018/feb/02/bitcoin-biggest-bubble-in-history-says-economist-who-predicted-2008-crash\">&quot;Bitcoin biggest bubble in history, says economist who predicted 2008 crash&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180612141424/https://www.theguardian.com/technology/2018/feb/02/bitcoin-biggest-bubble-in-history-says-economist-who-predicted-2008-crash\">Archived</a> from the original on 12 June 2018.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-249\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-249\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBraue2014\" class=\"citation news cs1\">Braue, David (11 March 2014). <a class=\"external text\" href=\"https://www.zdnet.com/article/bitcoin-confidence-game-is-a-ponzi-scheme-for-the-21st-century/\">&quot;Bitcoin confidence game is a Ponzi scheme for the 21st century&quot;</a>. <i>ZDNet</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20161006050933/http://www.zdnet.com/article/bitcoin-confidence-game-is-a-ponzi-scheme-for-the-21st-century/\">Archived</a> from the original on 6 October 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 October</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-250\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-250\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFClinch,_Matt2014\" class=\"citation web cs1\">Clinch, Matt (10 March 2014). <a class=\"external text\" href=\"https://www.cnbc.com/id/101479123\">&quot;Roubini launches stinging attack on bitcoin&quot;</a>. <a href=\"https://en.wikipedia.org/wiki/CNBC\">CNBC</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20141006074352/https://www.cnbc.com/id/101479123\">Archived</a> from the original on 6 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 July</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-251\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-251\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://fortune.com/2017/07/27/howard-marks-bitcoin-pyramid-scheme/\">&quot;This Billionaire Just Called Bitcoin a &apos;Pyramid Scheme<span class=\"cs1-kern-right\">&apos;</span>&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20170924045918/http://fortune.com/2017/07/27/howard-marks-bitcoin-pyramid-scheme/\">Archived</a> from the original on 24 September 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 September</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Ott_Ummelas_and_Milda_Seputyte-252\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ott_Ummelas_and_Milda_Seputyte_252-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFOtt_UmmelasMilda_Seputyte2014\" class=\"citation news cs1\">Ott Ummelas &amp; Milda Seputyte (31 January 2014). <a class=\"external text\" href=\"https://www.bloomberg.com/news/2014-01-30/bitcoin-ponzi-scheme-worry-sparks-estonia-central-bank-caution.html\">&quot;Bitcoin &apos;Ponzi&apos; Concern Sparks Warning From Estonia Bank&quot;</a>. <i>bloomberg.com</i>. Bloomberg. <a class=\"external text\" href=\"https://web.archive.org/web/20140329214501/http://www.bloomberg.com/news/2014-01-30/bitcoin-ponzi-scheme-worry-sparks-estonia-central-bank-caution.html\">Archived</a> from the original on 29 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Posner,_Eric-253\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Posner,_Eric_253-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPosner,_Eric2013\" class=\"citation web cs1\"><a href=\"https://en.wikipedia.org/wiki/Eric_Posner\">Posner, Eric</a> (11 April 2013). <a class=\"external text\" href=\"https://www.slate.com/articles/news_and_politics/view_from_chicago/2013/04/bitcoin_is_a_ponzi_scheme_the_internet_currency_will_collapse.html\">&quot;Fool&apos;s Gold: Bitcoin is a Ponzi scheme&#x2014;the Internet&apos;s favorite currency will collapse&quot;</a>. <i>Slate</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20140326185128/https://www.slate.com/articles/news_and_politics/view_from_chicago/2013/04/bitcoin_is_a_ponzi_scheme_the_internet_currency_will_collapse.html\">Archived</a> from the original on 26 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 April</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-254\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-254\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKaushik_Basu2014\" class=\"citation web cs1\">Kaushik Basu (July 2014). <a class=\"external text\" href=\"http://www-wds.worldbank.org/external/default/WDSContentServer/WDSP/IB/2014/07/16/000112742_20140716115536/Rendered/PDF/WPS6967.pdf\">&quot;Ponzis: The Science and Mystique of a Class of Financial Frauds&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <a href=\"https://en.wikipedia.org/wiki/World_Bank_Group\">World Bank Group</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20141031043236/http://www-wds.worldbank.org/external/default/WDSContentServer/WDSP/IB/2014/07/16/000112742_20140716115536/Rendered/PDF/WPS6967.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 31 October 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">30 October</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-FC20140625-255\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-FC20140625_255-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.news.admin.ch/NSBSubscriber/message/attachments/35355.pdf\">&quot;Federal Council report on virtual currencies in response to the Schwaab (13.3687) and Weibel (13.4070) postulates&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i><a href=\"https://en.wikipedia.org/wiki/Federal_Council_(Switzerland)\">Federal Council (Switzerland)</a></i>. <a href=\"https://en.wikipedia.org/wiki/Swiss_Confederation\" class=\"mw-redirect\">Swiss Confederation</a>. 25 June 2014. <a class=\"external text\" href=\"https://web.archive.org/web/20141205182453/http://www.news.admin.ch/NSBSubscriber/message/attachments/35355.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 5 December 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-256\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-256\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMooneyMufson2017\" class=\"citation news cs1\">Mooney, Chris; Mufson, Steven (19 December 2017). <a class=\"external text\" href=\"https://www.washingtonpost.com/news/energy-environment/wp/2017/12/19/why-the-bitcoin-craze-is-using-up-so-much-energy\">&quot;Why the bitcoin craze is using up so much energy&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180109212301/https://www.washingtonpost.com/news/energy-environment/wp/2017/12/19/why-the-bitcoin-craze-is-using-up-so-much-energy/\">Archived</a> from the original on 9 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 January</span> 2018</span>. <q>several experts told The Washington Post that bitcoin probably uses as much as 1 to 4 gigawatts, or billion watts, of electricity, roughly the output of one to three nuclear reactors.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-politico201804-257\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-politico201804_257-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-politico201804_257-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFRoberts2018\" class=\"citation news cs1\">Roberts, Paul (9 March 2018). <a class=\"external text\" href=\"https://www.politico.com/magazine/story/2018/03/09/bitcoin-mining-energy-prices-smalltown-feature-217230\">&quot;This Is What Happens When Bitcoin Miners Take Over Your Town - Eastern Washington had cheap power and tons of space. Then the suitcases of cash started arriving&quot;</a>. <i>Politico</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180309124201/https://www.politico.com/magazine/story/2018/03/09/bitcoin-mining-energy-prices-smalltown-feature-217230\">Archived</a> from the original on 9 March 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 March</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-258\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-258\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFde_Vries2018\" class=\"citation journal cs1\">de Vries, Alex (May 2018). <a class=\"external text\" href=\"https://doi.org/10.1016%2Fj.joule.2018.04.016\">&quot;Bitcoin&apos;s Growing Energy Problem&quot;</a>. <i>Joule</i>. <b>2</b> (5): 801&#x2013;805. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://doi.org/10.1016%2Fj.joule.2018.04.016\">10.1016/j.joule.2018.04.016</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Kohler-259\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Kohler_259-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Kohler_259-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFK&#xF6;hlerPizzol2019\" class=\"citation journal cs1\">K&#xF6;hler, Susanne; Pizzol, Massimo (20 November 2019). <a class=\"external text\" href=\"https://doi.org/10.1021%2Facs.est.9b05687\">&quot;Life Cycle Assessment of Bitcoin Mining&quot;</a>. <i>Environmental Science &amp; Technology</i>. <b>53</b> (23): 13598&#x2013;13606. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2019EnST...5313598K\">2019EnST...5313598K</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://doi.org/10.1021%2Facs.est.9b05687\">10.1021/acs.est.9b05687</a></span>. <a href=\"https://en.wikipedia.org/wiki/PMID_(identifier)\" class=\"mw-redirect\">PMID</a>&#xA0;<a class=\"external text\" href=\"https://pubmed.ncbi.nlm.nih.gov/31746188\">31746188</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-260\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-260\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBaraniuk2019\" class=\"citation web cs1\">Baraniuk, Chris (3 July 2019). <a class=\"external text\" href=\"https://www.bbc.com/news/technology-48853230\">&quot;Bitcoin&apos;s global energy use &apos;equals Switzerland<span class=\"cs1-kern-right\">&apos;</span>&quot;</a>. <i>BBC News</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20200116160730/https://www.bbc.com/news/technology-48853230\">Archived</a> from the original on 16 January 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 February</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Independent-261\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Independent_261-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.independent.co.uk/life-style/gadgets-and-tech/bitcoin-environment-mining-energy-cryptocurrency-b1800938.html\">&quot;How bad is Bitcoin for the environment really?&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/The_Independent\">Independent</a></i>. 12 February 2021<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 February</span> 2021</span>. <q>requires nearly as much energy as the entire country of Argentina</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-dh150613-262\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-dh150613_262-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFO&apos;Brien2015\" class=\"citation news cs1\">O&apos;Brien, Matt (13 June 2015). <a class=\"external text\" href=\"http://www.dailyherald.com/article/20150613/business/150619551/\">&quot;The scam called Bitcoin&quot;</a>. <i>Daily Herald</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20150616000405/http://www.dailyherald.com/article/20150613/business/150619551\">Archived</a> from the original on 16 June 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 September</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-verge20171221-263\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-verge20171221_263-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPotenza2017\" class=\"citation news cs1\">Potenza, Alessandra (21 December 2017). <a class=\"external text\" href=\"https://www.theverge.com/2017/12/21/16806772/bitcoin-cryptocurrency-energy-consumption-renewables-climate-change\">&quot;Can renewable power offset bitcoin&apos;s massive energy demands?&quot;</a>. <i>TheVerge News</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180112155940/https://www.theverge.com/2017/12/21/16806772/bitcoin-cryptocurrency-energy-consumption-renewables-climate-change\">Archived</a> from the original on 12 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-hydro2018-264\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-hydro2018_264-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLampert2018\" class=\"citation news cs1\">Lampert, Allison (12 January 2018). <a class=\"external text\" href=\"https://www.reuters.com/article/us-canada-bitcoin-china/chinese-bitcoin-miners-eye-sites-in-energy-rich-canada-idUSKBN1F10BU\">&quot;Chinese bitcoin miners eye sites in energy-rich Canada&quot;</a>. <i>Reuters</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180114001018/https://www.reuters.com/article/us-canada-bitcoin-china/chinese-bitcoin-miners-eye-sites-in-energy-rich-canada-idUSKBN1F10BU\">Archived</a> from the original on 14 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-265\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-265\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.independent.co.uk/life-style/gadgets-and-tech/news/bitcoin-environment-green-energy-power-global-warming-climate-change-a8094661.html\">&quot;Bitcoin is literally ruining the earth, claim experts&quot;</a>. <i>The Independent</i>. 6 December 2017. <a class=\"external text\" href=\"https://web.archive.org/web/20180119145633/http://www.independent.co.uk/life-style/gadgets-and-tech/news/bitcoin-environment-green-energy-power-global-warming-climate-change-a8094661.html\">Archived</a> from the original on 19 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-266\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-266\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"https://www.wired.com/story/bitcoin-global-warming/\">&quot;The Hard Math Behind Bitcoin&apos;s Global Warming Problem&quot;</a>. <i>WIRED</i>. 15 December 2017. <a class=\"external text\" href=\"https://web.archive.org/web/20180121095259/https://www.wired.com/story/bitcoin-global-warming/\">Archived</a> from the original on 21 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 January</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Ponciano-267\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ponciano_267-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Ponciano_267-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFPonciano2021\" class=\"citation news cs1\">Ponciano, Jonathan (18 April 2021). <a class=\"external text\" href=\"https://www.forbes.com/sites/jonathanponciano/2021/04/18/crypto-flash-crash-wiped-out-300-billion-in-less-than-24-hours-spurring-massive-bitcoin-liquidations/\">&quot;Crypto Flash Crash Wiped Out $300 Billion In Less Than 24 Hours, Spurring Massive Bitcoin Liquidations&quot;</a>. <i>Forbes</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 April</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-268\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-268\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMurtaugh2021\" class=\"citation news cs1\">Murtaugh, Dan (9 February 2021). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2021-02-09/tesla-s-bitcoin-binge-spells-overtime-for-xinjiang-coal-miners\">&quot;The Possible Xinjiang Coal Link in Tesla&apos;s Bitcoin Binge&quot;</a>. <i>Bloomberg.com</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">24 April</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-fortuneChina2021-269\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-fortuneChina2021_269-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-fortuneChina2021_269-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFTully2021\" class=\"citation web cs1\">Tully, Shawn (20 April 2021). <a class=\"external text\" href=\"https://fortune.com/2021/04/20/bitcoin-mining-coal-china-environment-pollution/\">&quot;Commentary: How much Bitcoin comes from dirty coal? A flooded mine in China just spotlighted the issue&quot;</a>. <i>Fortune</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 April</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-270\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-270\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFChant2021\" class=\"citation web cs1\">Chant, Tim De (10 May 2021). <a class=\"external text\" href=\"https://arstechnica.com/tech-policy/2021/05/private-equity-firm-revives-zombie-fossil-fuel-power-plant-to-mine-bitcoin/\">&quot;Private-equity firm revives zombie fossil-fuel power plant to mine bitcoin&quot;</a>. <i>Ars Technica</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 May</span> 2021</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-271\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-271\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHern2018\" class=\"citation news cs1\">Hern, Alex (17 January 2018). <a class=\"external text\" href=\"https://www.theguardian.com/technology/2018/jan/17/bitcoin-electricity-usage-huge-climate-cryptocurrency\">&quot;Bitcoin&apos;s energy usage is huge &#x2013; we can&apos;t afford to ignore it&quot;</a>. <i>The Guardian</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20180123061505/https://www.theguardian.com/technology/2018/jan/17/bitcoin-electricity-usage-huge-climate-cryptocurrency\">Archived</a> from the original on 23 January 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">18 September</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-272\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-272\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFEthan2019\" class=\"citation news cs1\">Ethan, Lou (17 January 2019). <a class=\"external text\" href=\"https://www.theguardian.com/commentisfree/2019/jan/17/bitcoin-big-oil-environment-energy\">&quot;Bitcoin as big oil: the next big environmental fight?&quot;</a>. <i>The Guardian</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20190829190224/https://www.theguardian.com/commentisfree/2019/jan/17/bitcoin-big-oil-environment-energy\">Archived</a> from the original on 29 August 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">18 September</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-273\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-273\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFoteinis2018\" class=\"citation journal cs1\">Foteinis, Spyros (2018). <a class=\"external text\" href=\"https://doi.org/10.1038%2Fd41586-018-01625-x\">&quot;Bitcoin&apos;s alarming carbon footprint&quot;</a>. <i>Nature</i>. <b>554</b> (7691): 169. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2018Natur.554..169F\">2018Natur.554..169F</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://doi.org/10.1038%2Fd41586-018-01625-x\">10.1038/d41586-018-01625-x</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-274\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-274\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKrauseTolaymat2018\" class=\"citation journal cs1\">Krause, Max J.; Tolaymat, Thabet (2018). &quot;Quantification of energy and carbon costs for mining cryptocurrencies&quot;. <i>Nature Sustainability</i>. <b>1</b> (11): 711&#x2013;718. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1038%2Fs41893-018-0152-7\">10.1038/s41893-018-0152-7</a>. <a href=\"https://en.wikipedia.org/wiki/S2CID_(identifier)\" class=\"mw-redirect\">S2CID</a>&#xA0;<a class=\"external text\" href=\"https://api.semanticscholar.org/CorpusID:169170289\">169170289</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Mora-275\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Mora_275-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Mora_275-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFMora2018\" class=\"citation journal cs1\">Mora, Camilo;  et&#xA0;al. (2018). &quot;Bitcoin emissions alone could push global warming above 2&#xB0;C&quot;. <i>Nature Climate Change</i>. <b>8</b> (11): 931&#x2013;933. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2018NatCC...8..931M\">2018NatCC...8..931M</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1038%2Fs41558-018-0321-8\">10.1038/s41558-018-0321-8</a>. <a href=\"https://en.wikipedia.org/wiki/S2CID_(identifier)\" class=\"mw-redirect\">S2CID</a>&#xA0;<a class=\"external text\" href=\"https://api.semanticscholar.org/CorpusID:91491182\">91491182</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Stoll-276\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Stoll_276-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Stoll_276-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFStollKlaa&#xDF;enGallersd&#xF6;rfer2019\" class=\"citation journal cs1\">Stoll, Christian; Klaa&#xDF;en, Lena; Gallersd&#xF6;rfer, Ulrich (2019). <a class=\"external text\" href=\"https://doi.org/10.1016%2Fj.joule.2019.05.012\">&quot;The Carbon Footprint of Bitcoin&quot;</a>. <i>Joule</i>. <b>3</b> (7): 1647&#x2013;1661. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://doi.org/10.1016%2Fj.joule.2019.05.012\">10.1016/j.joule.2019.05.012</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-277\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-277\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMasanet2019\" class=\"citation journal cs1\">Masanet, Eric;  et&#xA0;al. (2019). &quot;Implausible projections overestimate near-term Bitcoin <span class=\"nowrap\"><span class=\"chemf nowrap\">CO<span><br>2</span></span></span> emissions&quot;. <i>Nature Climate Change</i>. <b>9</b> (9): 653&#x2013;654. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2019NatCC...9..653M\">2019NatCC...9..653M</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1038%2Fs41558-019-0535-4\">10.1038/s41558-019-0535-4</a>. <a href=\"https://en.wikipedia.org/wiki/Hdl_(identifier)\" class=\"mw-redirect\">hdl</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://hdl.handle.net/2066%2F207817\">2066/207817</a></span>. <a href=\"https://en.wikipedia.org/wiki/OSTI_(identifier)\" class=\"mw-redirect\">OSTI</a>&#xA0;<a class=\"external text\" href=\"https://www.osti.gov/biblio/1561950\">1561950</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-278\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-278\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDittmarPraktiknjo2019\" class=\"citation journal cs1\">Dittmar, Lars; Praktiknjo, Aaron (2019). &quot;Could Bitcoin emissions push global warming above 2&#xB0;C?&quot;. <i>Nature Climate Change</i>. <b>9</b> (9): 656&#x2013;657. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2019NatCC...9..656D\">2019NatCC...9..656D</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1038%2Fs41558-019-0534-5\">10.1038/s41558-019-0534-5</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-279\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-279\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHouy2019\" class=\"citation journal cs1\">Houy, Nicolas (2019). <a class=\"external text\" href=\"https://doi.org/10.1038%2Fs41558-019-0533-6\">&quot;Rational mining limits Bitcoin emissions&quot;</a>. <i>Nature Climate Change</i>. <b>9</b> (9): 655. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2019NatCC...9..655H\">2019NatCC...9..655H</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://doi.org/10.1038%2Fs41558-019-0533-6\">10.1038/s41558-019-0533-6</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-280\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-280\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKamiya\" class=\"citation web cs1\">Kamiya, George. <a class=\"external text\" href=\"https://www.iea.org/commentaries/bitcoin-energy-use-mined-the-gap\">&quot;Commentary: Bitcoin energy use - mined the gap&quot;</a>. <i>iea.org</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20200303170408/https://www.iea.org/commentaries/bitcoin-energy-use-mined-the-gap\">Archived</a> from the original on 3 March 2020<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 December</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Lavin,_Tim-281\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Lavin,_Tim_281-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLavin,_Tim2013\" class=\"citation news cs1\">Lavin, Tim (8 August 2013). <a class=\"external text\" href=\"http://www.bloombergview.com/articles/2013-08-08/did-the-sec-just-validate-bitcoin-no-\">&quot;The SEC Shows Why Bitcoin Is Doomed&quot;</a>. <i>bloomberg.com</i>. Bloomberg LP. <a class=\"external text\" href=\"https://web.archive.org/web/20140325214514/http://www.bloombergview.com/articles/2013-08-08/did-the-sec-just-validate-bitcoin-no-\">Archived</a> from the original on 25 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 October</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-USoff-282\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-USoff_282-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLee2013\" class=\"citation news cs1\">Lee, Timothy B. (21 November 2013). <a class=\"external text\" href=\"https://www.washingtonpost.com/news/the-switch/wp/2013/11/21/heres-how-bitcoin-charmed-washington/\">&quot;Here&apos;s how Bitcoin charmed Washington&quot;</a>. <i>The Washington Post</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20170101144528/https://www.washingtonpost.com/news/the-switch/wp/2013/11/21/heres-how-bitcoin-charmed-washington/\">Archived</a> from the original on 1 January 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 October</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-nytspy2018-283\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-nytspy2018_283-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFPopper2018\" class=\"citation news cs1\">Popper, Nathaniel (13 July 2018). <a class=\"external text\" href=\"https://www.nytimes.com/2018/07/13/technology/bitcoin-russian-hacking.html\">&quot;How Russian Spies Hid Behind Bitcoin in Hacking Campaign&quot;</a>. NYT. <a class=\"external text\" href=\"https://web.archive.org/web/20180714110954/https://www.nytimes.com/2018/07/13/technology/bitcoin-russian-hacking.html\">Archived</a> from the original on 14 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-284\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-284\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFEhrlich\" class=\"citation web cs1\">Ehrlich, Steven. <a class=\"external text\" href=\"https://www.forbes.com/sites/stevenehrlich/2021/04/13/janet-yellen-bitcoin-and-crypto-fearmongers-get-pushback-from-former-cia-director/?sh=1741bd89bb7a\">&quot;Janet Yellen, Bitcoin And Crypto Fearmongers Get Pushback From Former CIA Director&quot;</a>. <i>Forbes</i>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-285\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-285\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBall,_James2013\" class=\"citation web cs1\">Ball, James (22 March 2013). <a class=\"external text\" href=\"https://www.theguardian.com/world/2013/mar/22/silk-road-online-drug-marketplace\">&quot;Silk Road: the online drug marketplace that officials seem powerless to stop&quot;</a>. <i>theguardian.com</i>. Guardian News and Media Limited. <a class=\"external text\" href=\"https://web.archive.org/web/20131012012106/http://www.theguardian.com/world/2013/mar/22/silk-road-online-drug-marketplace\">Archived</a> from the original on 12 October 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">20 October</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Hammer-286\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Hammer_286-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMontag2018\" class=\"citation news cs1\">Montag, Ali (9 July 2018). <a class=\"external text\" href=\"https://www.cnbc.com/2018/07/09/nobel-prize-winning-economist-joseph-stiglitz-criticizes-bitcoin.html\">&quot;Nobel-winning economist: Authorities will bring down &apos;hammer&apos; on bitcoin&quot;</a>. CNBC. <a class=\"external text\" href=\"https://web.archive.org/web/20180711200915/https://www.cnbc.com/2018/07/09/nobel-prize-winning-economist-joseph-stiglitz-criticizes-bitcoin.html\">Archived</a> from the original on 11 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-FN-287\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-FN_287-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFNewlands2018\" class=\"citation news cs1\">Newlands, Chris (9 July 2018). <a class=\"external text\" href=\"https://www.fnlondon.com/articles/stiglitz-roubini-and-rogoff-lead-joint-attack-on-bitcoin-20180709\">&quot;Stiglitz, Roubini and Rogoff lead joint attack on bitcoin&quot;</a>. <a href=\"https://en.wikipedia.org/wiki/Financial_News\">Financial News</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20180711200500/https://www.fnlondon.com/articles/stiglitz-roubini-and-rogoff-lead-joint-attack-on-bitcoin-20180709\">Archived</a> from the original on 11 July 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 July</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-SDB1-288\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-SDB1_288-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFoleyKarlsenPutni&#x146;&#x161;2018\" class=\"citation news cs1\">Foley, Sean; Karlsen, Jonathan R.; Putni&#x146;&#x161;, T&#x101;lis J. (19 February 2018). <a class=\"external text\" href=\"https://www.law.ox.ac.uk/business-law-blog/blog/2018/02/sex-drugs-and-bitcoin-how-much-illegal-activity-financed-through\">&quot;Sex, drugs, and bitcoin: How much illegal activity is financed through cryptocurrencies?&quot;</a>. University of Oxford Faculty of Law. Oxford Business Law Blog. <a class=\"external text\" href=\"https://web.archive.org/web/20180610034340/https://www.law.ox.ac.uk/business-law-blog/blog/2018/02/sex-drugs-and-bitcoin-how-much-illegal-activity-financed-through\">Archived</a> from the original on 10 June 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 June</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-SDB2-289\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-SDB2_289-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFoleyKarlsenPutni&#x146;&#x161;2018\" class=\"citation journal cs1\">Foley, Sean; Karlsen, Jonathan R.; Putni&#x146;&#x161;, T&#x101;lis J. (30 January 2018). &quot;Sex, Drugs, and Bitcoin: How Much Illegal Activity Is Financed Through Cryptocurrencies?&quot;. <i>Social Science Research Network</i>. <a href=\"https://en.wikipedia.org/wiki/SSRN_(identifier)\" class=\"mw-redirect\">SSRN</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://ssrn.com/abstract=3102645\">3102645</a></span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Antonopoulos-290\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-Antonopoulos_290-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAntonopoulos2017\" class=\"citation book cs1\">Antonopoulos, Andreas (2017). &quot;3&quot;. <i>Mastering Bitcoin: Programming the Open Blockchain</i> (2nd&#xA0;ed.). O&apos;Reilly Media. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1491954386\"><bdi>978-1491954386</bdi></a>. <q>Bitcoin Core is the reference implementation of the bitcoin system, meaning that it is the authoritative reference on how each part of the technology should be implemented. Bitcoin Core implements all aspects of bitcoin, including wallets, a transaction and block validation engine, and a full network node in the peer-to-peer bitcoin network.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-291\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-291\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoin.org/en/release/v0.9.0#rebranding-to-bitcoin-core\">&quot;Bitcoin Core version 0.9.0 released&quot;</a>. <i>Bitcoin Core</i>. 19 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-mastbit-292\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-mastbit_292-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-mastbit_292-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-mastbit_292-2\"><sup><i><b>c</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFAntonopoulos2014\" class=\"citation book cs1\">Antonopoulos, Andreas M. (2014). <a class=\"external text\" href=\"https://books.google.com/books?id=IXmrBQAAQBAJ\"><i>Mastering Bitcoin: Unlocking Digital Cryptocurrencies</i></a>. O&apos;Reilly Media, Inc. pp.&#xA0;31&#x2013;32. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-1491902646\"><bdi>978-1491902646</bdi></a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">6 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-blad-293\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-blad_293-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.inc.com/ilan-mochari/mit-media-lab-bitcoin-developer-fund.html\">&quot;MIT Announces $900,000 Bitcoin Developer Fund&quot;</a>. <i>Inc</i>. 29 March 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-about-294\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-about_294-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-about_294-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoincore.org/en/about/\">&quot;About&quot;</a>. <i>Bitcoin Core</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-bde-295\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-bde_295-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoin.org/en/developer-examples#testing-applications\">&quot;Bitcoin Developer Examples&quot;</a>. Bitcoin<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-check-296\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-check_296-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://github.com/bitcoin/bitcoin/blob/master/src/checkpoints.cpp\">&quot;checkpoints.cpp&quot;</a>. <i>Repository source code</i>. GitHub, Inc<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-297\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-297\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://github.com/bitcoin/bitcoin/blob/master/src/chainparams.cpp\">&quot;bitcoin/chainparams.cpp&quot;</a>. <i>GitHub</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-leadbit-298\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-leadbit_298-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMike_Orcutt2015\" class=\"citation news cs1\">Mike Orcutt (19 May 2015). <a class=\"external text\" href=\"https://www.technologyreview.com/s/537486/leaderless-bitcoin-struggles-to-make-its-most-crucial-decision/\">&quot;Leaderless Bitcoin Struggles to Make Its Most Crucial Decision&quot;</a>. <i>MIT Technology Review</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-asr-299\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-asr_299-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://bitcoin.org/en/alert/2016-11-01-alert-retirement\">&quot;Alert System Retirement&quot;</a>. Bitcoin Project. 1 November 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-mpapi-300\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-mpapi_300-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAntonopoulos2013\" class=\"citation web cs1\">Antonopoulos, Andreas (29 May 2013). <a class=\"external text\" href=\"http://radar.oreilly.com/2013/05/bitcoin-is-a-money-platform-with-many-apis.html#more-57340\">&quot;Bitcoin is a money platform with many APIs&quot;</a>. <i>Radar</i>. O&apos;Reilly<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-301\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-301\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://github.com/bitcoin/bitcoin/blob/ebd786b72a2a15143d7ef4ea2229fef121bd8f12/contrib/devtools/README.md#create-and-verify-timestamps-of-merge-commits\">&quot;Bitcoin Core devtools README - Create and verify timestamps of merge commits&quot;</a>. <i>GitHub</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 May</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-hunt-302\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-hunt_302-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-hunt_302-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFPreukschatJosep_Busquet2015\" class=\"citation book cs1\">Preukschat, Alex; Josep Busquet (2015). <a class=\"external text\" href=\"https://play.google.com/store/books/details?id=438FCwAAQBAJ\"><i>Bitcoin: The Hunt of Satoshi Nakamoto</i></a>. Europe Comics. p.&#xA0;87. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/9791032800201\"><bdi>9791032800201</bdi></a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">16 November</span> 2016</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-NewYorker-303\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-NewYorker_303-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMaria_Bustillos2015\" class=\"citation news cs1\">Maria Bustillos (25 August 2015). <a class=\"external text\" href=\"https://www.newyorker.com/business/currency/inside-the-fight-over-bitcoins-future\">&quot;Inside the Fight Over Bitcoin&apos;s Future&quot;</a>. <i>New Yorker</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">29 June</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-304\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-304\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFShin\" class=\"citation news cs1\">Shin, Laura. <a class=\"external text\" href=\"https://www.forbes.com/sites/laurashin/2017/12/19/bitcoin-and-taxes-if-not-hodling-consider-donating\">&quot;Bitcoin And Taxes: If Not HODLing, Consider Donating&quot;</a>. <i>Forbes</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20171222124446/https://www.forbes.com/sites/laurashin/2017/12/19/bitcoin-and-taxes-if-not-hodling-consider-donating/\">Archived</a> from the original on 22 December 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 December</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-305\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-305\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKaminska2017\" class=\"citation web cs1\">Kaminska, Izabella (22 December 2017). <a class=\"external text\" href=\"https://ftalphaville.ft.com/2017/12/22/2197074/the-hodl/\">&quot;The HODL&quot;</a>. <i>Financial Times</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 November</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-306\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-306\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMontag2018\" class=\"citation web cs1\">Montag, Ali (26 August 2018). <a class=\"external text\" href=\"https://www.cnbc.com/2018/01/23/what-hodl-whale-and-other-cryptocurrency-slang-terms-mean.html\">&quot;<span class=\"cs1-kern-left\">&apos;</span>HODL,&apos; &apos;whale&apos; and 5 other cryptocurrency slang terms explained&quot;</a>. <i>CNBC</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 November</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-307\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-307\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFWong\" class=\"citation news cs1\">Wong, Joon Ian. <a class=\"external text\" href=\"https://qz.com/878728/buy-and-hodl-just-dont-get-rekt-the-slang-that-gets-you-taken-seriously-as-a-bitcoin-trader/\">&quot;Buy and hodl, just don&apos;t get #rekt: The slang that gets you taken seriously as a bitcoin trader&quot;</a>. <i>Quartz</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20171222220057/https://qz.com/878728/buy-and-hodl-just-dont-get-rekt-the-slang-that-gets-you-taken-seriously-as-a-bitcoin-trader/\">Archived</a> from the original on 22 December 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 December</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-308\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-308\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAkhtar2017\" class=\"citation news cs1\">Akhtar, Tanzeel (22 December 2017). <a class=\"external text\" href=\"https://www.thestreet.com/story/14429339/1/bitcoin-fans-chant-hodl-as-price-plunges.html\">&quot;As Bitcoin plunges, cryptocurrency fans chant &apos;HODL&apos; for comfort&quot;</a>. <i>TheStreet</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20171223102117/https://www.thestreet.com/story/14429339/1/bitcoin-fans-chant-hodl-as-price-plunges.html\">Archived</a> from the original on 23 December 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 December</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-309\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-309\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHajric2020\" class=\"citation news cs1\">Hajric, Vildana (19 November 2020). <a class=\"external text\" href=\"https://www.bloomberg.com/news/articles/2020-11-19/what-the-heck-is-hodl-bitcoin-lingo-for-crypto-noobs-quicktake\">&quot;All the Bitcoin Lingo You Need to Know as Crypto Heats Up&quot;</a>. <i>Bloomberg</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 December</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-310\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-310\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFStross2013\" class=\"citation book cs1\">Stross, Charles (2013). <a class=\"external text\" href=\"https://archive.org/details/neptunesbrood0000stro\"><i>Neptune&apos;s Brood</i></a> (First&#xA0;ed.). New York: Penguin Group USA. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-0-425-25677-0\"><bdi>978-0-425-25677-0</bdi></a>. <q>It&apos;s theft-proof too &#x2013; for each bitcoin is cryptographically signed by the mind of its owner.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-311\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-311\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.antipope.org/charlie/blog-static/2014/09/crib-sheet-neptunes-brood.html\">&quot;Crib Sheet: Neptune&apos;s Brood &#x2013; Charlie&apos;s Diary&quot;</a>. <i>www.antipope.org</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20170614175136/http://www.antipope.org/charlie/blog-static/2014/09/crib-sheet-neptunes-brood.html\">Archived</a> from the original on 14 June 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 December</span> 2017</span>. <q>I wrote Neptune&apos;s Brood in 2011. Bitcoin was obscure back then, and I figured had just enough name recognition to be a useful term for an interstellar currency: it&apos;d clue people in that it was a networked digital currency.</q></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-312\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-312\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKenigsberg,_Ben2014\" class=\"citation news cs1\">Kenigsberg, Ben (2 October 2014). <a class=\"external text\" href=\"https://www.nytimes.com/2014/10/03/movies/the-rise-and-rise-of-bitcoin-from-nicholas-mross.html\">&quot;Financial Wild West&quot;</a>. <i>The New York Times</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20150518232516/http://www.nytimes.com/2014/10/03/movies/the-rise-and-rise-of-bitcoin-from-nicholas-mross.html\">Archived</a> from the original on 18 May 2015<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">8 May</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-313\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-313\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFMichel2017\" class=\"citation web cs1\">Michel, Lincoln (16 December 2017). <a class=\"external text\" href=\"https://www.gq.com/story/what-the-hell-is-bitcoin-let-this-documentary-on-netflix-explain\">&quot;What the Hell Is Bitcoin? Let This Documentary on Netflix Explain&quot;</a>. <i>GQ</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20181118220511/https://www.gq.com/story/what-the-hell-is-bitcoin-let-this-documentary-on-netflix-explain\">Archived</a> from the original on 18 November 2018<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 October</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-314\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-314\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://motherboard.vice.com/read/introducing-ledger-the-first-bitcoin-only-academic-journal\">&quot;Introducing Ledger, the First Bitcoin-Only Academic Journal&quot;</a>. <i>Motherboard</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20170110172807/http://motherboard.vice.com/read/introducing-ledger-the-first-bitcoin-only-academic-journal\">Archived</a> from the original on 10 January 2017.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-315\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-315\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.ledgerjournal.org/ojs/ledger/about\">&quot;Editorial Policies&quot;</a>. <i>ledgerjournal.org</i>. <a class=\"external text\" href=\"https://web.archive.org/web/20161223135741/http://www.ledgerjournal.org/ojs/index.php/ledger/about/editorialPolicies#custom-0\">Archived</a> from the original on 23 December 2016<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 January</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-316\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/Bitcoin#cite_ref-316\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation journal cs1\"><a class=\"external text\" href=\"http://ledger.pitt.edu/ojs/public/journals/1/AuthorGuide.pdf\">&quot;How to Write and Format an Article for Ledger&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i><a href=\"https://en.wikipedia.org/wiki/Ledger_(journal)\">Ledger</a></i>. 2015. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.5195%2FLEDGER.2015.1\">10.5195/LEDGER.2015.1</a> (inactive 19 January 2021). <a class=\"external text\" href=\"https://web.archive.org/web/20150922190603/http://ledger.pitt.edu/ojs/public/journals/1/AuthorGuide.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 22 September 2015.</cite><span class=\"Z3988\"></span><span class=\"cs1-maint citation-comment\">CS1 maint: DOI inactive as of January 2021 (<a href=\"https://en.wikipedia.org/wiki/Category:CS1_maint:_DOI_inactive_as_of_January_2021\">link</a>)</span></span>\\n' +\n    '</li>\\n' +\n    '</ol></div>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"External_links\">External links</span></h2>\\n' +\n    '<table class=\"mbox-small plainlinks sistersitebox\">\\n' +\n    '<tbody><tr>\\n' +\n    '<td class=\"mbox-image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png\" width=\"30\" height=\"40\" class=\"noviewer\" srcset=\"https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/45px-Commons-logo.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/59px-Commons-logo.svg.png 2x\"></td>\\n' +\n    '<td class=\"mbox-text plainlist\">Wikimedia Commons has media related to <span><a href=\"https://commons.wikimedia.org/wiki/Category:Bitcoin\" class=\"extiw\">Bitcoin</a></span>.</td></tr>\\n' +\n    '</tbody></table>\\n' +\n    '<ul><li><a class=\"external text\" href=\"https://www.bitcoin.org/\">Bitcoin.org website</a></li>\\n' +\n    '<li><a class=\"external text\" href=\"https://curlie.org/Science/Social_Sciences/Economics/Financial_Economics/Currency_and_Money/Alternative_Monetary_Systems/Cryptocurrencies/Bitcoin\">Bitcoin</a> at <a href=\"https://en.wikipedia.org/wiki/Curlie\" class=\"mw-redirect\">Curlie</a></li></ul>\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '</div>\\n' +\n    '<div class=\"printfooter\">Retrieved from &quot;<a href=\"https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;oldid=1025303171\">https://en.wikipedia.org/w/index.php?title=Bitcoin&amp;oldid=1025303171</a>&quot;</div></div></div><hr><h4>Page 2</h4><div><div id=\"mw-content-text\" class=\"mw-body-content mw-content-ltr\"><div class=\"mw-parser-output\"><div class=\"hatnote navigation-not-searchable\">For the taxonomic method, see <a href=\"https://en.wikipedia.org/wiki/DNA_barcoding\">DNA barcoding</a>.  For a code of conduct for barristers, see <a href=\"https://en.wikipedia.org/wiki/Legal_ethics\">legal ethics</a>.</div>\\n' +\n    '<div class=\"shortdescription nomobile noexcerpt noprint searchaux\">Optical machine-readable representation of data</div>\\n' +\n    '\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:UPC-A-036000291452.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/UPC-A-036000291452.svg/220px-UPC-A-036000291452.svg.png\" width=\"220\" height=\"189\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/UPC-A-036000291452.svg/330px-UPC-A-036000291452.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/UPC-A-036000291452.svg/440px-UPC-A-036000291452.svg.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:UPC-A-036000291452.svg\" class=\"internal\"></a></div>A <a href=\"https://en.wikipedia.org/wiki/Universal_Product_Code\">UPC-A</a> barcode</div></div></div>\\n' +\n    '<p>A <b>barcode</b> or <b>bar code</b> is a method of representing data in a visual, <a href=\"https://en.wikipedia.org/wiki/Machine-readable_data\">machine-readable form</a>. Initially, barcodes represented data by varying the widths and spacings of parallel lines. These barcodes, now commonly referred to as linear or one-dimensional (1D), can be scanned by special <a href=\"https://en.wikipedia.org/wiki/Optical_scanner\" class=\"mw-redirect\">optical scanners</a>, called <a href=\"https://en.wikipedia.org/wiki/Barcode_reader\">barcode readers</a>, of which there are several types. Later, two-dimensional (2D) variants were developed, using rectangles, dots, <a href=\"https://en.wikipedia.org/wiki/Hexagon\">hexagons</a> and other patterns, called <i>matrix codes</i> or <i>2D barcodes</i>, although they do not use bars as such. 2D barcodes can be read using purpose-built 2D optical scanners, which exist in a few different forms. 2D barcodes can also be read by a digital camera connected to a microcomputer running software that takes a photographic image of the barcode and analyzes the image to deconstruct and decode the 2D barcode. A <a href=\"https://en.wikipedia.org/wiki/Mobile_device\">mobile device</a> with an inbuilt camera, such as <a href=\"https://en.wikipedia.org/wiki/Smartphone\">smartphone</a>, can function as the latter type of 2D barcode reader using specialized <a href=\"https://en.wikipedia.org/wiki/Application_software\">application software</a>. (The same sort of mobile device could also read 1D barcodes, depending on the application software.)\\n' +\n    '</p><p>The barcode was invented by Norman Joseph Woodland and Bernard Silver and patented in the US in 1951.<sup id=\"cite_ref-patent_1-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-patent-1\">[1]</a></sup> The invention was based on <a href=\"https://en.wikipedia.org/wiki/Morse_code\">Morse code</a><sup id=\"cite_ref-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-2\">[2]</a></sup> that was extended to thin and thick bars. However, it took over twenty years before this invention became commercially successful. An early use of one type of barcode in an industrial context was sponsored by the <a href=\"https://en.wikipedia.org/wiki/Association_of_American_Railroads\">Association of American Railroads</a> in the late 1960s.  Developed by <a href=\"https://en.wikipedia.org/wiki/GTE\">General Telephone and Electronics</a> (GTE) and called <a href=\"https://en.wikipedia.org/wiki/KarTrak_ACI\" class=\"mw-redirect\">KarTrak ACI</a> (Automatic Car Identification), this scheme involved placing colored stripes in various combinations on steel plates which were affixed to the sides of railroad rolling stock.  Two plates were used per car, one on each side, with the arrangement of the colored stripes encoding information such as ownership, type of equipment, and identification number.<sup id=\"cite_ref-Cranstone_3-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Cranstone-3\">[3]</a></sup> The plates were read by a trackside scanner, located for instance, at the entrance to a classification yard, while the car was moving past.<sup id=\"cite_ref-Keyes_4-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Keyes-4\">[4]</a></sup> The project was abandoned after about ten years because the system proved unreliable after long-term use.<sup id=\"cite_ref-Cranstone_3-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Cranstone-3\">[3]</a></sup>\\n' +\n    '</p><p>Barcodes became commercially successful when they were used to automate supermarket <a href=\"https://en.wikipedia.org/wiki/Point_of_sale\">checkout</a> systems, a task for which they have become almost universal. The Uniform Grocery Product Code Council had chosen, in 1973, the barcode design developed by <a href=\"https://en.wikipedia.org/wiki/George_Laurer\">George Laurer</a>. Laurer&apos;s barcode, with vertical bars, printed better than the circular barcode developed by Woodland and Silver.<sup id=\"cite_ref-RobertsNYT_5-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-RobertsNYT-5\">[5]</a></sup> Their use has spread to many other tasks that are generically referred to as <a href=\"https://en.wikipedia.org/wiki/Automatic_identification_and_data_capture\">automatic identification and data capture</a> (AIDC). The first scanning of the now-ubiquitous <a href=\"https://en.wikipedia.org/wiki/Universal_Product_Code\">Universal Product Code</a> (UPC) barcode was on a pack of <a href=\"https://en.wikipedia.org/wiki/Wrigley_Company\">Wrigley Company</a> chewing gum in June 1974 at a <a href=\"https://en.wikipedia.org/wiki/Marsh_Supermarkets\">Marsh supermarket</a> in <a href=\"https://en.wikipedia.org/wiki/Troy,_Ohio\">Troy, Ohio</a>, using scanner produced by <a href=\"https://en.wikipedia.org/wiki/PSC_Inc.\">Photographic Sciences Corporation</a>.<sup id=\"cite_ref-6\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-6\">[6]</a></sup><sup id=\"cite_ref-RobertsNYT_5-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-RobertsNYT-5\">[5]</a></sup> <a href=\"https://en.wikipedia.org/wiki/QR_code\">QR codes</a>, a specific type of 2D barcode, have recently become very popular due to the growth in smartphone ownership.<sup id=\"cite_ref-7\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-7\">[7]</a></sup>\\n' +\n    '</p><p>Other systems have made inroads in the AIDC market, but the simplicity, universality and low cost of barcodes has limited the role of these other systems, particularly before technologies such as <a href=\"https://en.wikipedia.org/wiki/Radio-frequency_identification\">radio-frequency identification</a> (RFID) became available after 1995.\\n' +\n    '</p>\\n' +\n    '\\n' +\n    '\\n' +\n    '<h2><span class=\"mw-headline\" id=\"History\">History</span></h2>\\n' +\n    '<table class=\"box-Duplication plainlinks metadata ambox ambox-style\"><tbody><tr><td class=\"mbox-image\"><div><img alt src=\"https://upload.wikimedia.org/wikipedia/en/thumb/f/f2/Edit-clear.svg/40px-Edit-clear.svg.png\" width=\"40\" height=\"40\" srcset=\"https://upload.wikimedia.org/wikipedia/en/thumb/f/f2/Edit-clear.svg/60px-Edit-clear.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/en/thumb/f/f2/Edit-clear.svg/80px-Edit-clear.svg.png 2x\"></div></td><td class=\"mbox-text\"><div class=\"mbox-text-span\">This article <b><a href=\"https://en.wikipedia.org/wiki/Wikipedia:CFORK\" class=\"mw-redirect\">duplicates</a> the scope of other articles</b>, specifically, <a href=\"https://en.wikipedia.org/wiki/Universal_Product_Code#History\">Universal Product Code#History</a>.<span class=\"hide-when-compact\"> Please <a href=\"https://en.wikipedia.org/wiki/Talk:Barcode\">discuss</a> this issue on the talk page and edit it to conform with <a href=\"https://en.wikipedia.org/wiki/Wikipedia:Summary_style\">Wikipedia&apos;s Manual of Style</a>.</span>  <small class=\"date-container\"><i>(<span class=\"date\">December 2013</span>)</i></small></div></td></tr></tbody></table>\\n' +\n    '<p>In 1948 <a href=\"https://en.wikipedia.org/wiki/Bernard_Silver\">Bernard Silver</a>, a graduate student at <a href=\"https://en.wikipedia.org/wiki/Drexel_Institute_of_Technology\" class=\"mw-redirect\">Drexel Institute of Technology</a> in <a href=\"https://en.wikipedia.org/wiki/Philadelphia\">Philadelphia</a>, Pennsylvania, US overheard the president of the local food chain, <a href=\"https://en.wikipedia.org/wiki/Food_Fair\">Food Fair</a>, asking one of the deans to research a system to automatically read product information during checkout.<sup id=\"cite_ref-8\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-8\">[8]</a></sup> Silver told his friend <a href=\"https://en.wikipedia.org/wiki/Norman_Joseph_Woodland\">Norman Joseph Woodland</a> about the request, and they started working on a variety of systems. Their first working system used <a href=\"https://en.wikipedia.org/wiki/Ultraviolet\">ultraviolet</a> ink, but the ink faded too easily and was expensive.<sup id=\"cite_ref-story_9-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-story-9\">[9]</a></sup>\\n' +\n    '</p><p>Convinced that the system was workable with further development, Woodland left Drexel, moved into his father&apos;s apartment in Florida, and continued working on the system. His next inspiration came from <a href=\"https://en.wikipedia.org/wiki/Morse_code\">Morse code</a>, and he formed his first barcode from sand on the beach. &quot;I just extended the dots and dashes downwards and made narrow lines and wide lines out of them.&quot;<sup id=\"cite_ref-story_9-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-story-9\">[9]</a></sup> To read them, he adapted technology from optical soundtracks in movies, using a 500-watt incandescent light bulb shining through the paper onto an <a href=\"https://en.wikipedia.org/w/index.php?title=RCA935&amp;action=edit&amp;redlink=1\" class=\"new\">RCA935</a> <a href=\"https://en.wikipedia.org/wiki/Photomultiplier\">photomultiplier</a> tube (from a movie projector) on the far side. He later decided that the system would work better if it were printed as a circle instead of a line, allowing it to be scanned in any direction.\\n' +\n    '</p><p>On 20 October 1949, Woodland and Silver filed a patent application for &quot;Classifying Apparatus and Method&quot;, in which they described both the linear and <a href=\"https://en.wikipedia.org/wiki/Bullseye_(target)\">bull&apos;s eye</a> printing patterns, as well as the mechanical and electronic systems needed to read the code. The patent was issued on 7 October 1952 as US Patent 2,612,994.<sup id=\"cite_ref-patent_1-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-patent-1\">[1]</a></sup> In 1951, Woodland moved to <a href=\"https://en.wikipedia.org/wiki/IBM\">IBM</a> and continually tried to interest IBM in developing the system. The company eventually commissioned a report on the idea, which concluded that it was both feasible and interesting, but that processing the resulting information would require equipment that was some time off in the future.\\n' +\n    '</p><p>IBM offered to buy the patent, but the offer was not accepted. <a href=\"https://en.wikipedia.org/wiki/Philco\">Philco</a> purchased the patent in 1962 and then sold it to <a href=\"https://en.wikipedia.org/wiki/RCA\">RCA</a> sometime later.<sup id=\"cite_ref-story_9-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-story-9\">[9]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Collins_at_Sylvania\">Collins at Sylvania</span></h3>\\n' +\n    '<p>During his time as an undergraduate, David Jarrett Collins worked at the <a href=\"https://en.wikipedia.org/wiki/Pennsylvania_Railroad\">Pennsylvania Railroad</a> and became aware of the need to automatically identify railroad cars. Immediately after receiving his master&apos;s degree from <a href=\"https://en.wikipedia.org/wiki/Massachusetts_Institute_of_Technology\">MIT</a> in 1959, he started work at <a href=\"https://en.wikipedia.org/wiki/Sylvania_Electric_Products\">GTE Sylvania</a> and began addressing the problem. He developed a system called <i>KarTrak</i> using blue and red reflective stripes attached to the side of the cars, encoding a six-digit company identifier and a four-digit car number.<sup id=\"cite_ref-story_9-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-story-9\">[9]</a></sup> Light reflected off the colored stripes was read by <a href=\"https://en.wikipedia.org/wiki/Photomultiplier\">photomultiplier</a> vacuum tubes.<sup id=\"cite_ref-10\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-10\">[10]</a></sup>\\n' +\n    '</p><p>The <a href=\"https://en.wikipedia.org/wiki/Boston_and_Maine_Railroad\" class=\"mw-redirect\">Boston and Maine Railroad</a> tested the KarTrak system on their gravel cars in 1961. The tests continued until 1967, when the <a href=\"https://en.wikipedia.org/wiki/Association_of_American_Railroads\">Association of American Railroads</a> (AAR) selected it as a standard, <a href=\"https://en.wikipedia.org/wiki/Automatic_Car_Identification\" class=\"mw-redirect\">Automatic Car Identification</a>, across the entire North American fleet. The installations began on 10 October 1967. However, the <a href=\"https://en.wikipedia.org/wiki/1970s#Economy\">economic downturn</a> and rash of bankruptcies in the industry in the early 1970s greatly slowed the rollout, and it was not until 1974 that 95% of the fleet was labeled. To add to its woes, the system was found to be easily fooled by dirt in certain applications, which greatly affected accuracy. The AAR abandoned the system in the late 1970s, and it was not until the mid-1980s that they introduced a similar system, this time based on radio tags.<sup id=\"cite_ref-11\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-11\">[11]</a></sup>\\n' +\n    '</p><p>The railway project had failed, but a <a href=\"https://en.wikipedia.org/wiki/Toll_bridge\">toll bridge</a> in <a href=\"https://en.wikipedia.org/wiki/New_Jersey\">New Jersey</a> requested a similar system so that it could quickly scan for cars that had purchased a monthly pass. Then the <a href=\"https://en.wikipedia.org/wiki/United_States_Postal_Service\">U.S. Post Office</a> requested a system to track trucks entering and leaving their facilities. These applications required special <a href=\"https://en.wikipedia.org/wiki/Retroreflector\">retroreflector</a> labels. Finally, <a href=\"https://en.wikipedia.org/wiki/Whiskas\">Kal Kan</a> asked the Sylvania team for a simpler (and cheaper) version which they could put on cases of pet food for inventory control.\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Computer_Identics_Corporation\">Computer Identics Corporation</span></h3>\\n' +\n    '<p>In 1967, with the <a href=\"https://en.wikipedia.org/wiki/Railway\" class=\"mw-redirect\">railway</a> system maturing, Collins went to management looking for funding for a project to develop a black-and-white version of the code for other industries. They declined, saying that the railway project was large enough, and they saw no need to branch out so quickly.\\n' +\n    '</p><p>Collins then quit Sylvania and formed the Computer Identics Corporation.<sup id=\"cite_ref-story_9-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-story-9\">[9]</a></sup> As its first innovations, Computer Identics moved from using incandescent light bulbs in its systems, replacing them with <a href=\"https://en.wikipedia.org/wiki/Helium%E2%80%93neon_laser\">helium&#x2013;neon lasers</a>, and incorporated a mirror as well, making it capable of locating a barcode up to several feet in front of the scanner. This made the entire process much simpler and more reliable, and typically enabled these devices to deal with damaged labels, as well, by recognizing and reading the intact portions.\\n' +\n    '</p><p>Computer Identics Corporation installed one of its first two scanning systems in the spring of 1969 at a <a href=\"https://en.wikipedia.org/wiki/General_Motors\">General Motors</a> (Buick) factory in Flint, Michigan.<sup id=\"cite_ref-story_9-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-story-9\">[9]</a></sup> The system was used to identify a dozen types of transmissions moving on an overhead conveyor from production to shipping. The other scanning system was installed at General Trading Company&apos;s distribution center in Carlstadt, New Jersey to direct shipments to the proper loading bay.\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Universal_Product_Code\">Universal Product Code</span></h3>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Main article: <a href=\"https://en.wikipedia.org/wiki/Universal_Product_Code\">Universal Product Code</a></div>\\n' +\n    '<p>In 1966, the <a href=\"https://en.wikipedia.org/w/index.php?title=National_Association_of_Food_Chains&amp;action=edit&amp;redlink=1\" class=\"new\">National Association of Food Chains</a> (NAFC) held a meeting on the idea of automated checkout systems. <a href=\"https://en.wikipedia.org/wiki/RCA\">RCA</a>, who had purchased the rights to the original Woodland patent, attended the meeting and initiated an internal project to develop a system based on the bullseye code. The <a href=\"https://en.wikipedia.org/wiki/Kroger\">Kroger</a> grocery chain volunteered to test it.\\n' +\n    '</p><p>In the mid-1970s, the NAFC established the Ad-Hoc Committee for U.S. Supermarkets on a Uniform Grocery-Product Code to set guidelines for barcode development. In addition, it created a symbol-selection subcommittee to help standardize the approach. In cooperation with consulting firm, McKinsey &amp; Co., they developed a standardized 11-digit code for identifying products. The committee then sent out a contract tender to develop a <a href=\"https://en.wikipedia.org/wiki/Barcode_system\">barcode system</a> to print and read the code. The request went to <a href=\"https://en.wikipedia.org/wiki/Singer_Corporation\">Singer</a>, <a href=\"https://en.wikipedia.org/wiki/National_Cash_Register\" class=\"mw-redirect\">National Cash Register</a> (NCR), <a href=\"https://en.wikipedia.org/wiki/Litton_Industries\">Litton Industries</a>, RCA, <a href=\"https://en.wikipedia.org/wiki/Pitney-Bowes\" class=\"mw-redirect\">Pitney-Bowes</a>, IBM and many others.<sup id=\"cite_ref-12\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-12\">[12]</a></sup> A wide variety of barcode approaches was studied, including linear codes, RCA&apos;s bullseye concentric circle code, <a href=\"https://en.wiktionary.org/wiki/starburst\" class=\"extiw\">starburst</a> patterns and others.\\n' +\n    '</p><p>In the spring of 1971, RCA demonstrated their bullseye code at another industry meeting. IBM executives at the meeting noticed the crowds at the RCA booth and immediately developed their own system. IBM marketing specialist Alec Jablonover remembered that the company still employed Woodland, and he<sup class=\"noprint Inline-Template\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Words_to_watch#Unsupported_attributions\"><span>who?</span></a></i>]</sup> established a new facility in Raleigh-Durham <a href=\"https://en.wikipedia.org/wiki/Research_Triangle_Park\">Research Triangle Park</a> to lead development.\\n' +\n    '</p><p>In July 1972, RCA began an 18-month test in a Kroger store in Cincinnati. Barcodes were printed on small pieces of adhesive paper, and attached by hand by store employees when they were adding price tags. The code proved to have a serious problem; the printers would sometimes smear ink, rendering the code unreadable in most orientations. However, a linear code, like the one being developed by Woodland at IBM, was printed in the direction of the stripes, so extra ink would simply make the code &quot;taller&quot; while remaining readable. So on 3 April 1973, the IBM UPC was selected as the NAFC standard. IBM had designed five versions of UPC symbology for future industry requirements: UPC A, B, C, D, and E.<sup id=\"cite_ref-Nelson_13-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Nelson-13\">[13]</a></sup>\\n' +\n    '</p><p>NCR installed a testbed system at <a href=\"https://en.wikipedia.org/wiki/Marsh_Supermarkets\">Marsh&apos;s Supermarket</a> in <a href=\"https://en.wikipedia.org/wiki/Troy,_Ohio\">Troy, Ohio</a>, near the factory that was producing the equipment. On 26 June 1974, Clyde Dawson pulled a 10-pack of Wrigley&apos;s <a href=\"https://en.wikipedia.org/wiki/Juicy_Fruit\">Juicy Fruit</a> gum out of his basket and it was scanned by Sharon Buchanan at 8:01&#xA0;am. The pack of gum and the receipt are now on display in the <a href=\"https://en.wikipedia.org/wiki/Smithsonian_Institution\">Smithsonian Institution</a>. It was the first commercial appearance of the UPC.<sup id=\"cite_ref-Varchaver_14-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Varchaver-14\">[14]</a></sup>\\n' +\n    '</p><p>In 1971, an IBM team was assembled for an intensive planning session, threshing out, 12 to 18 hours a day, how the technology would be deployed and operate cohesively across the system, and scheduling a roll-out plan. By 1973, the team were meeting with grocery manufacturers to introduce the symbol that would need to be printed on the packaging or labels of all of their products. There were no cost savings for a grocery to use it, unless at least 70% of the grocery&apos;s products had the barcode printed on the product by the manufacturer. IBM projected that 75% would be needed in 1975. Yet, although this was achieved, there were still scanning machines in fewer than 200 grocery stores by 1977.<sup id=\"cite_ref-Selmeier_15-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Selmeier-15\">[15]</a></sup>\\n' +\n    '</p><p>Economic studies conducted for the grocery industry committee projected over $40 million in savings to the industry from scanning by the mid-1970s. Those numbers were not achieved in that time-frame and some predicted the demise of barcode scanning. The usefulness of the barcode required the adoption of expensive scanners by a critical mass of retailers while manufacturers simultaneously adopted barcode labels. Neither wanted to move first and results were not promising for the first couple of years, with <i>Business Week</i> proclaiming &quot;The Supermarket Scanner That Failed&quot; in a 1976 article.<sup id=\"cite_ref-Varchaver_14-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Varchaver-14\">[14]</a></sup><sup id=\"cite_ref-16\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-16\">[16]</a></sup>\\n' +\n    '</p><p>On the other hand, experience with barcode scanning in those stores revealed additional benefits. The detailed sales information acquired by the new systems allowed greater responsiveness to customer habits, needs and preferences. This was reflected in the fact that about 5 weeks after installing barcode scanners, sales in grocery stores typically started climbing and eventually leveled off at a 10&#x2013;12% increase in sales that never dropped off. There was also a 1&#x2013;2% decrease in operating cost for those stores, and this enabled them to lower prices and thereby to increase market share. It was shown in the field that the <a href=\"https://en.wikipedia.org/wiki/Return_on_investment\">return on investment</a> for a barcode scanner was 41.5%. By 1980, 8,000 stores per year were converting.<sup id=\"cite_ref-Selmeier_15-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Selmeier-15\">[15]</a></sup>\\n' +\n    '</p><p><a href=\"https://en.wikipedia.org/wiki/Sims_Supermarket\">Sims Supermarkets</a> were the first location in Australia to use barcodes, starting in 1979.<sup id=\"cite_ref-17\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-17\">[17]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Industrial_adoption\">Industrial adoption</span></h2>\\n' +\n    '<p>In 1981, the <a href=\"https://en.wikipedia.org/wiki/United_States_Department_of_Defense\">United States Department of Defense</a> adopted the use of <a href=\"https://en.wikipedia.org/wiki/Code_39\">Code 39</a> for marking all products sold to the United States military. This system, Logistics Applications of Automated Marking and Reading Symbols (LOGMARS), is still used by DoD and is widely viewed as the catalyst for widespread adoption of barcoding in industrial uses.<sup id=\"cite_ref-18\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-18\">[18]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Use\">Use</span></h2>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:EAN-13-ISBN-13.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/EAN-13-ISBN-13.svg/220px-EAN-13-ISBN-13.svg.png\" width=\"220\" height=\"140\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/EAN-13-ISBN-13.svg/330px-EAN-13-ISBN-13.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/EAN-13-ISBN-13.svg/440px-EAN-13-ISBN-13.svg.png 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:EAN-13-ISBN-13.svg\" class=\"internal\"></a></div><a href=\"https://en.wikipedia.org/wiki/International_Article_Number_(EAN)\" class=\"mw-redirect\">EAN-13 ISBN barcode</a></div></div></div>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:LB2-ADULT-L3_Assembled.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/en/thumb/a/ad/LB2-ADULT-L3_Assembled.jpg/220px-LB2-ADULT-L3_Assembled.jpg\" width=\"220\" height=\"95\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/en/a/ad/LB2-ADULT-L3_Assembled.jpg 1.5x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:LB2-ADULT-L3_Assembled.jpg\" class=\"internal\"></a></div>Barcode on a patient identification wristband</div></div></div>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:Barcodedmail.JPG\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Barcodedmail.JPG/220px-Barcodedmail.JPG\" width=\"220\" height=\"147\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Barcodedmail.JPG/330px-Barcodedmail.JPG 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Barcodedmail.JPG/440px-Barcodedmail.JPG 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:Barcodedmail.JPG\" class=\"internal\"></a></div>Barcoded parcel</div></div></div>\\n' +\n    '<p>Barcodes are widely used around the world in many contexts. In stores, UPC barcodes are pre-printed on most items other than fresh produce from a <a href=\"https://en.wikipedia.org/wiki/Grocery_store\">grocery store</a>. This speeds up processing at check-outs and helps track items and also reduces instances of <a href=\"https://en.wikipedia.org/wiki/Shoplifting\">shoplifting</a> involving price tag swapping, although shoplifters can now print their own barcodes.<sup id=\"cite_ref-19\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-19\">[19]</a></sup> Barcodes that encode a book&apos;s <a href=\"https://en.wikipedia.org/wiki/International_Standard_Book_Number\">ISBN</a> are also widely pre-printed on books, journals and other printed materials. In addition, retail chain membership cards use barcodes to identify customers, allowing for customized marketing and greater understanding of individual consumer shopping patterns. At the point of sale, shoppers can get product discounts or special marketing offers through the address or e-mail address provided at registration.\\n' +\n    '</p><p>Barcodes are widely <a href=\"https://en.wikipedia.org/wiki/Barcode_technology_in_healthcare\">used in the healthcare and hospital settings</a>, ranging from patient identification (to access patient data, including medical history, drug allergies, etc.) to creating <a href=\"https://en.wikipedia.org/wiki/SOAP_note\">SOAP Notes</a><sup id=\"cite_ref-20\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-20\">[20]</a></sup> with barcodes to medication management. They are also used to facilitate the separation and indexing of documents that have been imaged in batch scanning applications, track the organization of <a href=\"https://en.wikipedia.org/wiki/Species\">species</a> in biology,<sup id=\"cite_ref-21\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-21\">[21]</a></sup> and integrate with in-motion <a href=\"https://en.wikipedia.org/wiki/Checkweigher\" class=\"mw-redirect\">checkweighers</a> to identify the item being weighed in a <a href=\"https://en.wikipedia.org/wiki/Conveyor\" class=\"mw-redirect\">conveyor</a> line for <a href=\"https://en.wikipedia.org/wiki/Data_collection\">data collection</a>.\\n' +\n    '</p><p>They can also be used to keep track of objects and people; they are used to keep track of <a href=\"https://en.wikipedia.org/wiki/Rental_car\" class=\"mw-redirect\">rental cars</a>, <a href=\"https://en.wikipedia.org/wiki/Checked_baggage\">airline luggage</a>, <a href=\"https://en.wikipedia.org/wiki/Nuclear_waste\" class=\"mw-redirect\">nuclear waste</a>, <a href=\"https://en.wikipedia.org/wiki/Registered_mail\">registered mail</a>, <a href=\"https://en.wikipedia.org/wiki/Express_mail\">express mail</a> and parcels. Barcoded tickets (which may be printed by the customer on their home printer, or stored on their mobile device) allow the holder to enter sports arenas, cinemas, theatres, fairgrounds, and transportation, and are used to record the arrival and departure of vehicles from rental facilities etc. This can allow proprietors to identify duplicate or fraudulent tickets more easily. Barcodes are widely used in shop floor control applications software where employees can scan work orders and track the time spent on a job.\\n' +\n    '</p><p>Barcodes are also used in some kinds of non-contact 1D and 2D <a href=\"https://en.wikipedia.org/wiki/Position_sensor\">position sensors</a>. A series of barcodes are used in some kinds of absolute 1D <a href=\"https://en.wikipedia.org/wiki/Linear_encoder\">linear encoder</a>. The barcodes are packed close enough together that the reader always has one or two barcodes in its field of view. As a kind of <a href=\"https://en.wikipedia.org/wiki/Fiducial_marker\">fiducial marker</a>, the relative position of the barcode in the field of view of the reader gives incremental precise positioning, in some cases with <a href=\"https://en.wikipedia.org/wiki/Sub-pixel_resolution\">sub-pixel resolution</a>. The data decoded from the barcode gives the absolute coarse position. An &quot;address carpet&quot;, such as Howell&apos;s binary pattern and the <a href=\"https://en.wikipedia.org/wiki/Anoto\">Anoto</a> dot pattern, is a 2D barcode designed so that a reader, even though only a tiny portion of the complete carpet is in the field of view of the reader, can find its absolute X,Y position and rotation in the carpet.<sup id=\"cite_ref-22\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-22\">[22]</a></sup><sup id=\"cite_ref-23\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-23\">[23]</a></sup>\\n' +\n    '</p><p>2D barcodes can embed a <a href=\"https://en.wikipedia.org/wiki/Hyperlink\">hyperlink</a> to a web page. A mobile device with an inbuilt camera might be used to read the pattern and browse the linked website, which can help a shopper find the best price for an item in the vicinity. Since 2005, airlines use an IATA-standard 2D barcode on boarding passes (<a href=\"https://en.wikipedia.org/wiki/Bar_Coded_Boarding_Pass\" class=\"mw-redirect\">Bar Coded Boarding Pass (BCBP)</a>), and since 2008 2D barcodes sent to mobile phones enable electronic boarding passes.<sup id=\"cite_ref-24\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-24\">[24]</a></sup>\\n' +\n    '</p><p>Some applications for barcodes have fallen out of use. In the 1970s and 1980s, software source code was occasionally encoded in a barcode and printed on paper (<a href=\"https://en.wikipedia.org/wiki/Cauzin_Softstrip\">Cauzin Softstrip</a> and Paperbyte<sup id=\"cite_ref-25\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-25\">[25]</a></sup> are barcode symbologies specifically designed for this application), and the 1991 <i><a href=\"https://en.wikipedia.org/wiki/Barcode_Battler\">Barcode Battler</a></i> computer game system used any standard barcode to generate combat statistics.\\n' +\n    '</p><p>Artists have used barcodes in art, such as <a href=\"https://en.wikipedia.org/wiki/Scott_Blake\">Scott Blake&apos;s</a> Barcode Jesus, as part of the <a href=\"https://en.wikipedia.org/wiki/Post-modernism\" class=\"mw-redirect\">post-modernism</a> movement.\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Symbologies\">Symbologies</span></h2>\\n' +\n    '<p>The mapping between messages and barcodes is called a <i><a href=\"https://en.wikipedia.org/wiki/Symbology\" class=\"mw-redirect\">symbology</a></i>. The specification of a symbology includes the encoding of the message into bars and spaces, any required start and stop markers, the size of the quiet zone required to be before and after the barcode, and the computation of a <a href=\"https://en.wikipedia.org/wiki/Checksum\">checksum</a>.\\n' +\n    '</p><p>Linear symbologies can be classified mainly by two properties:\\n' +\n    '</p>\\n' +\n    '<dl><dt>Continuous vs. discrete</dt></dl>\\n' +\n    '<ul><li>Characters in discrete symbologies are composed of <i>n</i> bars and <i>n</i>&#xA0;&#x2212;&#xA0;1 spaces.  There is an additional space between characters, but it does not convey information, and may have any width as long as it is not confused with the end of the code.</li>\\n' +\n    '<li>Characters in continuous symbologies are composed of <i>n</i> bars and <i>n</i> spaces, and usually abut, with one character ending with a space and the next beginning with a bar, or vice versa.  A special end pattern that has bars on both ends is required to end the code.</li></ul>\\n' +\n    '<dl><dt>Two-width vs. many-width</dt></dl>\\n' +\n    '<ul><li>A two-width, also called a <b>binary bar code</b>, contains bars and spaces of two widths, &quot;wide&quot; and &quot;narrow&quot;.  The precise width of the wide bars and spaces is not critical; typically it is permitted to be anywhere between 2 and 3 times the width of the narrow equivalents.</li>\\n' +\n    '<li>Some other symbologies use bars of two different heights (<a href=\"https://en.wikipedia.org/wiki/POSTNET\">POSTNET</a>), or the presence or absence of bars (<a href=\"https://en.wikipedia.org/wiki/CPC_Binary_Barcode\">CPC Binary Barcode</a>).  These are normally also considered binary bar codes.</li>\\n' +\n    '<li>Bars and spaces in many-width symbologies are all multiples of a basic width called the <i>module</i>; most such codes use four widths of 1, 2, 3 and 4 modules.</li></ul>\\n' +\n    '<p>Some symbologies use interleaving. The first character is encoded using black bars of varying width. The second character is then encoded by varying the width of the white spaces between these bars. Thus characters are encoded in pairs over the same section of the barcode. <a href=\"https://en.wikipedia.org/wiki/Interleaved_2_of_5\">Interleaved 2 of 5</a> is an example of this.\\n' +\n    '</p><p>Stacked symbologies repeat a given linear symbology vertically.\\n' +\n    '</p><p>The most common among the many 2D symbologies are matrix codes, which feature square or dot-shaped modules arranged on a grid pattern. 2D symbologies also come in circular and other patterns and may employ <a href=\"https://en.wikipedia.org/wiki/Steganography\">steganography</a>, hiding modules within an image (for example, <a href=\"https://en.wikipedia.org/w/index.php?title=DataGlyphs&amp;action=edit&amp;redlink=1\" class=\"new\">DataGlyphs</a>).\\n' +\n    '</p><p>Linear symbologies are optimized for laser scanners, which sweep a light beam across the barcode in a straight line, reading a <i>slice</i> of the barcode light-dark patterns.  Scanning at an angle makes the modules appear wider, but does not change the width ratios. Stacked symbologies are also optimized for laser scanning, with the laser making multiple passes across the barcode.\\n' +\n    '</p><p>In the 1990s development of <a href=\"https://en.wikipedia.org/wiki/Charge-coupled_device\">charge-coupled device</a> (CCD) imagers to read barcodes was pioneered by <a href=\"https://en.wikipedia.org/wiki/Welch_Allyn\">Welch Allyn</a>. Imaging does not require moving parts, as a laser scanner does. In 2007, linear imaging had begun to supplant laser scanning as the preferred scan engine for its performance and durability.\\n' +\n    '</p><p>2D symbologies cannot be read by a laser, as there is typically no sweep pattern that can encompass the entire symbol. They must be scanned by an image-based scanner employing a CCD or other digital camera sensor technology.\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Barcode_readers\">Barcode readers</span></h2>\\n' +\n    '<div class=\"hatnote navigation-not-searchable\">Main article: <a href=\"https://en.wikipedia.org/wiki/Barcode_reader\">Barcode reader</a></div>\\n' +\n    '<div class=\"thumb tright\"><div class=\"thumbinner\"><a href=\"https://en.wikipedia.org/wiki/File:GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG/220px-GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG\" width=\"220\" height=\"188\" class=\"thumbimage\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG/330px-GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG/440px-GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG 2x\"></a>  <div class=\"thumbcaption\"><div class=\"magnify\"><a href=\"https://en.wikipedia.org/wiki/File:GTIN_Barcodes_of_coke_bottles_-_what_you_see_and_what_the_barcode_scanner_see_2_IMG_2908_2913_2919.JPG\" class=\"internal\"></a></div><a href=\"https://en.wikipedia.org/wiki/Global_Trade_Item_Number\">GTIN</a> barcodes on Coke bottles. The images at right show how the <a href=\"https://en.wikipedia.org/wiki/Laser\">laser</a> of barcode readers &quot;see&quot; the images behind a red filter.</div></div></div>\\n' +\n    '<p>The earliest, and still the cheapest, barcode scanners are built from a fixed light and a single <a href=\"https://en.wikipedia.org/wiki/Photosensor\" class=\"mw-redirect\">photosensor</a> that is manually moved across the barcode. Barcode scanners can be classified into three categories based on their connection to the computer. The older type is the <a href=\"https://en.wikipedia.org/wiki/RS-232\">RS-232</a> barcode scanner. This type requires special programming for transferring the input data to the application program. Keyboard interface scanners connect to a computer using a <a href=\"https://en.wikipedia.org/wiki/PS/2_port\">PS/2</a> or <a href=\"https://en.wikipedia.org/wiki/AT_keyboard\" class=\"mw-redirect\">AT keyboard</a>&#x2013;compatible adaptor cable (a &quot;<a href=\"https://en.wikipedia.org/wiki/Keyboard_wedge\" class=\"mw-redirect\">keyboard wedge</a>&quot;). The barcode&apos;s data is sent to the computer as if it had been typed on the keyboard.\\n' +\n    '</p><p>Like the keyboard interface scanner, <a href=\"https://en.wikipedia.org/wiki/USB\">USB</a> scanners do not need custom code for transferring input data to the application program. On PCs running Windows the <a href=\"https://en.wikipedia.org/wiki/Human_interface_device\">human interface device</a> emulates the data merging action of a hardware &quot;keyboard wedge&quot;, and the scanner automatically behaves like an additional keyboard.\\n' +\n    '</p><p>Most modern smartphones are able to decode barcode using their built-in camera. Google&apos;s mobile <a href=\"https://en.wikipedia.org/wiki/Android_(operating_system)\">Android</a> operating system can use their own <a href=\"https://en.wikipedia.org/wiki/Google_Lens\">Google Lens</a> application to scan QR codes, or third party apps like <a href=\"https://en.wikipedia.org/wiki/Barcode_Scanner_(application)\">Barcode Scanner</a> to read both one-dimensional barcodes and QR codes. Nokia&apos;s <a href=\"https://en.wikipedia.org/wiki/Symbian\">Symbian</a> operating system featured a barcode scanner,<sup id=\"cite_ref-26\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-26\">[26]</a></sup> while mbarcode<sup id=\"cite_ref-27\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-27\">[27]</a></sup> is a <a href=\"https://en.wikipedia.org/wiki/QR_code\">QR code</a> reader for the <a href=\"https://en.wikipedia.org/wiki/Maemo\">Maemo</a> operating system. In Apple <a href=\"https://en.wikipedia.org/wiki/IOS_11\">iOS 11</a>, the native camera app can decode QR codes and can link to URLs, join wireless networks, or perform other operations depending on the QR Code contents.<sup id=\"cite_ref-28\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-28\">[28]</a></sup> Other paid and free apps are available with scanning capabilities for other symbologies or for earlier iOS versions.<sup id=\"cite_ref-29\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-29\">[29]</a></sup> With <a href=\"https://en.wikipedia.org/wiki/BlackBerry\">BlackBerry</a> devices, the App World application can natively scan barcodes and load any recognized Web URLs on the device&apos;s Web browser. <a href=\"https://en.wikipedia.org/wiki/Windows_Phone_7.5\" class=\"mw-redirect\">Windows Phone 7.5</a> is able to scan barcodes through the <a href=\"https://en.wikipedia.org/wiki/Bing_(search_engine)\" class=\"mw-redirect\">Bing</a> search app. However, these devices are not designed specifically for the capturing of barcodes. As a result, they do not decode nearly as quickly or accurately as a dedicated barcode scanner or <a href=\"https://en.wikipedia.org/wiki/Portable_data_terminal\">portable data terminal</a>.<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Quality_control_and_verification\">Quality control and verification</span></h2>\\n' +\n    '<p>It is common for producers and users of bar codes to have a <a href=\"https://en.wikipedia.org/wiki/Quality_management_system\">quality management system</a> which  includes <a href=\"https://en.wikipedia.org/wiki/Verification_and_validation\">verification and validation</a> of bar codes.<sup id=\"cite_ref-30\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-30\">[30]</a></sup>   Barcode verification examines scanability and the quality of the barcode in comparison to industry standards and specifications.<sup id=\"cite_ref-31\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-31\">[31]</a></sup> Barcode verifiers are primarily used by businesses that print and use barcodes. Any trading partner in the <a href=\"https://en.wikipedia.org/wiki/Supply_chain\">supply chain</a> can test barcode quality. It is important to verify a barcode to ensure that any reader in the supply chain can successfully interpret a barcode with a low error rate. Retailers levy large penalties for non-compliant barcodes. These chargebacks can reduce a manufacturer&apos;s revenue by 2% to 10%.<sup id=\"cite_ref-32\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-32\">[32]</a></sup>\\n' +\n    '</p><p>A barcode verifier works the way a reader does, but instead of simply decoding a barcode, a verifier performs a series of tests. For linear barcodes these tests are:\\n' +\n    '</p>\\n' +\n    '<ul><li>Edge contrast (EC)<sup id=\"cite_ref-:3_33-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>The difference between the space reflectance (Rs) and adjoining bar reflectance (Rb).  EC=Rs-Rb</li></ul></li>\\n' +\n    '<li>Minimum bar reflectance (Rb)<sup id=\"cite_ref-:3_33-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>The smallest reflectance value in a bar.</li></ul></li>\\n' +\n    '<li>Minimum space reflectance (Rs)<sup id=\"cite_ref-:3_33-2\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>The smallest reflectance value in a space.</li></ul></li>\\n' +\n    '<li>Symbol contrast (SC)<sup id=\"cite_ref-:3_33-3\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>Symbol Contrast is the difference in reflectance values of the lightest space (including the quiet zone) and the darkest bar of the symbol. The greater the difference, the higher the grade. The parameter is graded as either A, B, C, D, or F.  SC=Rmax-Rmin</li></ul></li>\\n' +\n    '<li>Minimum edge contrast (ECmin)<sup id=\"cite_ref-:3_33-4\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>The difference between the space reflectance (Rs) and adjoining bar reflectance (Rb).  EC=Rs-Rb</li></ul></li>\\n' +\n    '<li>Modulation (MOD)<sup id=\"cite_ref-:3_33-5\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>The parameter is graded either A, B, C, D, or F. This grade is based on the relationship between minimum edge contrast (ECmin) and symbol contrast (SC).  MOD=ECmin/SC  The greater the difference between minimum edge contrast and symbol contrast, the lower the grade.  Scanners and verifiers perceive the narrower bars and spaces to have less intensity than wider bars and spaces; the comparison of the lesser intensity of narrow elements to the wide elements is called modulation. This condition is affected by aperture size.</li></ul></li>\\n' +\n    '<li>Inter-character gap<sup id=\"cite_ref-:3_33-6\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>In discrete barcodes, the space that disconnects the two contiguous characters. When present, inter-character gaps are considered spaces (elements) for purposes of edge determination and reflectance parameter grades.</li></ul></li>\\n' +\n    '<li>Defects</li>\\n' +\n    '<li>Decode<sup id=\"cite_ref-:3_33-7\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>Extracting the information which has been encoded in a bar code symbol.</li></ul></li>\\n' +\n    '<li>Decodability<sup id=\"cite_ref-:3_33-8\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup>\\n' +\n    '<ul><li>Can be graded as A, B, C, D, or F. The Decodability grade indicates the amount of error in the width of the most deviant element in the symbol. The less deviation in the symbology, the higher the grade. Decodability is a measure of print accuracy using the symbology reference decode algorithm.</li></ul></li></ul>\\n' +\n    '<p>2D matrix symbols look at the parameters:\\n' +\n    '</p>\\n' +\n    '<ul><li>Symbol contrast<sup id=\"cite_ref-:3_33-9\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup></li>\\n' +\n    '<li>Modulation<sup id=\"cite_ref-:3_33-10\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup></li>\\n' +\n    '<li>Decode<sup id=\"cite_ref-:3_33-11\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:3-33\">[33]</a></sup></li>\\n' +\n    '<li>Unused error correction</li>\\n' +\n    '<li>Fixed (finder) pattern damage</li>\\n' +\n    '<li>Grid non-uniformity</li>\\n' +\n    '<li>Axial non-uniformity<sup id=\"cite_ref-34\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-34\">[34]</a></sup></li></ul>\\n' +\n    '<p>Depending on the parameter, each <a href=\"https://en.wikipedia.org/wiki/ANSI\" class=\"mw-redirect\">ANSI</a> test is graded from 0.0 to 4.0 (F to A), or given a pass or fail mark. Each grade is determined by analyzing the <a href=\"https://en.wikipedia.org/w/index.php?title=Scan_reflectance_profile&amp;action=edit&amp;redlink=1\" class=\"new\">scan reflectance profile</a> (SRP), an analog graph of a single scan line across the entire symbol. The lowest of the 8 grades is the scan grade, and the overall ISO symbol grade is the average of the individual scan grades. For most applications a 2.5 (C) is the minimal acceptable symbol grade.<sup id=\"cite_ref-35\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-35\">[35]</a></sup>\\n' +\n    '</p><p>Compared with a reader, a verifier measures a barcode&apos;s optical characteristics to international and industry standards. The measurement must be repeatable and consistent. Doing so requires constant conditions such as distance, illumination angle, sensor angle and verifier <a href=\"https://en.wikipedia.org/wiki/Aperture\">aperture</a>. Based on the verification results, the production process can be adjusted to print higher quality barcodes that will scan down the supply chain.\\n' +\n    '</p><p>Bar code validation may include evaluations after use (and abuse) testing such as sunlight, abrasion, impact, moisture, etc.<sup id=\"cite_ref-36\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-36\">[36]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Barcode_verifier_standards\">Barcode verifier standards</span></h3>\\n' +\n    '<p>Barcode verifier standards are defined by the <a href=\"https://en.wikipedia.org/wiki/International_Organization_for_Standardization\">International Organization for Standardization</a> (ISO), in ISO/IEC 15426-1 (linear) or ISO/IEC 15426-2 (2D).<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> The current international barcode quality specification is ISO/IEC 15416 (linear) and ISO/IEC 15415 (2D).<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> The <a href=\"https://en.wikipedia.org/wiki/European_Standard\">European Standard</a> EN 1635 has been withdrawn and replaced by ISO/IEC 15416. The original U.S. barcode quality specification was <a href=\"https://en.wikipedia.org/wiki/ANSI\" class=\"mw-redirect\">ANSI</a> X3.182. (UPCs used in the US &#x2013; ANSI/UCC5).<sup class=\"noprint Inline-Template Template-Fact\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Citation_needed\"><span>citation needed</span></a></i>]</sup> As of 2011 the ISO workgroup JTC1 SC31 was developing a <a href=\"https://en.wikipedia.org/wiki/Direct_part_marking\">Direct Part Marking (DPM)</a> quality standard: ISO/IEC TR 29158.<sup id=\"cite_ref-37\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-37\">[37]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Benefits\">Benefits</span></h2>\\n' +\n    '<p>In point-of-sale management, barcode systems can provide detailed up-to-date information on the business, accelerating decisions and with more confidence. For example:\\n' +\n    '</p>\\n' +\n    '<ul><li>Fast-selling items can be identified quickly and automatically reordered.</li>\\n' +\n    '<li>Slow-selling items can be identified, preventing inventory build-up.</li>\\n' +\n    '<li>The effects of merchandising changes can be monitored, allowing fast-moving, more profitable items to occupy the best space.</li>\\n' +\n    '<li>Historical data can be used to predict seasonal fluctuations very accurately.</li>\\n' +\n    '<li>Items may be repriced on the shelf to reflect both sale prices and price increases.</li>\\n' +\n    '<li>This technology also enables the profiling of individual consumers, typically through a voluntary registration of discount cards. While pitched as a benefit to the consumer, this practice is considered to be potentially dangerous by privacy advocates.<sup class=\"noprint Inline-Template\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Avoid_weasel_words\" class=\"mw-redirect\"><span>which?</span></a></i>]</sup></li></ul>\\n' +\n    '<p>Besides sales and inventory tracking, barcodes are very useful in logistics and supply chain management.\\n' +\n    '</p>\\n' +\n    '<ul><li>When a manufacturer packs a box for shipment, a Unique Identifying Number (UID) can be assigned to the box.</li>\\n' +\n    '<li>A database can link the UID to relevant information about the box; such as order number, items packed, quantity packed, destination, etc.</li>\\n' +\n    '<li>The information can be transmitted through a communication system such as <a href=\"https://en.wikipedia.org/wiki/Electronic_Data_Interchange\" class=\"mw-redirect\">Electronic Data Interchange</a> (EDI) so the retailer has the information about a shipment before it arrives.</li>\\n' +\n    '<li>Shipments that are sent to a Distribution Center (DC) are tracked before forwarding. When the shipment reaches its final destination, the UID gets scanned, so the store knows the shipment&apos;s source, contents, and cost.</li></ul>\\n' +\n    '<p>Barcode scanners are relatively low cost and extremely accurate compared to key-entry, with only about 1 substitution error in 15,000 to 36 trillion characters entered.<sup id=\"cite_ref-38\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-38\">[38]</a></sup><sup class=\"noprint Inline-Template\">[<i><a href=\"https://en.wikipedia.org/wiki/Wikipedia:Reliable_sources\"><span>unreliable source?</span></a></i>]</sup> The exact error rate depends on the type of barcode.\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Types_of_barcodes\">Types of barcodes</span></h2>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Linear_barcodes\">Linear barcodes</span></h3>\\n' +\n    '<p>A first generation, &quot;one dimensional&quot; barcode that is made up of lines and spaces of various widths that create specific patterns.\\n' +\n    '</p>\\n' +\n    '<table class=\"wikitable\">\\n' +\n    '\\n' +\n    '<tbody><tr>\\n' +\n    '<th>Example</th>\\n' +\n    '<th>Symbology</th>\\n' +\n    '<th>Continuous or discrete</th>\\n' +\n    '<th>Bar widths</th>\\n' +\n    '<th>Uses\\n' +\n    '</th></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Australia_Post_4-state_barcode.png\" class=\"image\"><img alt=\"Australia Post 4-state barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Australia_Post_4-state_barcode.png/128px-Australia_Post_4-state_barcode.png\" width=\"128\" height=\"20\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Australia_Post_4-state_barcode.png/192px-Australia_Post_4-state_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/c/c3/Australia_Post_4-state_barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Australia_Post\">Australia Post</a> barcode</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>An Australia Post barcode as used on a business reply paid envelope and applied by automated sorting machines to other mail when initially processed in fluorescent ink .\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Codabar.svg\" class=\"image\"><img alt=\"Codabar.svg\" src=\"https://upload.wikimedia.org/wikipedia/en/thumb/d/d1/Codabar.svg/128px-Codabar.svg.png\" width=\"128\" height=\"37\" srcset=\"https://upload.wikimedia.org/wikipedia/en/thumb/d/d1/Codabar.svg/192px-Codabar.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/en/thumb/d/d1/Codabar.svg/256px-Codabar.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Codabar\">Codabar</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Old format used in libraries and blood banks and on airbills (out of date, but still widely used in libraries)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Two-out-of-five_code\">Code 25 &#x2013; Non-interleaved 2 of 5</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Industrial\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Barcode2of5example.svg\" class=\"image\"><img alt=\"Barcode2of5example.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Barcode2of5example.svg/128px-Barcode2of5example.svg.png\" width=\"128\" height=\"45\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Barcode2of5example.svg/192px-Barcode2of5example.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Barcode2of5example.svg/256px-Barcode2of5example.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Interleaved_2_of_5\">Code 25 &#x2013; Interleaved 2 of 5</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Wholesale, libraries International standard ISO/IEC 16390\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code11_barcode.png\" class=\"image\"><img alt=\"Code11 barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Code11_barcode.png/128px-Code11_barcode.png\" width=\"128\" height=\"64\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Code11_barcode.png/192px-Code11_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/Code11_barcode.png/256px-Code11_barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Code_11\">Code 11</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Telephones (out of date)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code32_01234567.png\" class=\"image\"><img alt=\"Code32 01234567.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Code32_01234567.png/128px-Code32_01234567.png\" width=\"128\" height=\"80\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Code32_01234567.png/192px-Code32_01234567.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/5/5e/Code32_01234567.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Farmacode&amp;action=edit&amp;redlink=1\" class=\"new\">Farmacode</a> or Code 32</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Italian pharmacode &#x2013; use <a href=\"https://en.wikipedia.org/wiki/Code_39\">Code 39</a> (no international standard available)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code_3_of_9.svg\" class=\"image\"><img alt=\"Code 3 of 9.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Code_3_of_9.svg/128px-Code_3_of_9.svg.png\" width=\"128\" height=\"50\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Code_3_of_9.svg/192px-Code_3_of_9.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Code_3_of_9.svg/256px-Code_3_of_9.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Code_39\">Code 39</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Various &#x2013; international standard ISO/IEC 16388\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code_49_wikipedia.png\" class=\"image\"><img alt=\"Code 49 wikipedia.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Code_49_wikipedia.png/128px-Code_49_wikipedia.png\" width=\"128\" height=\"79\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Code_49_wikipedia.png/192px-Code_49_wikipedia.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Code_49_wikipedia.png/256px-Code_49_wikipedia.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Code_49\" class=\"mw-redirect\">Code 49</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Various\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code_93_wikipedia.png\" class=\"image\"><img alt=\"Code 93 wikipedia.png\" src=\"https://upload.wikimedia.org/wikipedia/en/thumb/a/a9/Code_93_wikipedia.png/128px-Code_93_wikipedia.png\" width=\"128\" height=\"86\" srcset=\"https://upload.wikimedia.org/wikipedia/en/thumb/a/a9/Code_93_wikipedia.png/192px-Code_93_wikipedia.png 1.5x, https://upload.wikimedia.org/wikipedia/en/thumb/a/a9/Code_93_wikipedia.png/256px-Code_93_wikipedia.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Code_93\">Code 93</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Various\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code_128B-2009-06-02.svg\" class=\"image\"><img alt=\"Code 128B-2009-06-02.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Code_128B-2009-06-02.svg/128px-Code_128B-2009-06-02.svg.png\" width=\"128\" height=\"50\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Code_128B-2009-06-02.svg/192px-Code_128B-2009-06-02.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Code_128B-2009-06-02.svg/256px-Code_128B-2009-06-02.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Code_128\">Code 128</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Various &#x2013; International Standard ISO/IEC 15417\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/CPC_Binary_Barcode\">CPC Binary</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Dx-film-edge-barcode.jpg\" class=\"image\"><img alt=\"Dx-film-edge-barcode.jpg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Dx-film-edge-barcode.jpg/128px-Dx-film-edge-barcode.jpg\" width=\"128\" height=\"102\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Dx-film-edge-barcode.jpg/192px-Dx-film-edge-barcode.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Dx-film-edge-barcode.jpg/256px-Dx-film-edge-barcode.jpg 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/DX_encoding#DX_film_edge_barcode\">DX film edge barcode</a></td>\\n' +\n    '<td>Neither</td>\\n' +\n    '<td>Tall/short</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Color_print_film\">Color print film</a>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Issn_barcode.png\" class=\"image\"><img alt=\"Issn barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/Issn_barcode.png/128px-Issn_barcode.png\" width=\"128\" height=\"79\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/Issn_barcode.png/192px-Issn_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/Issn_barcode.png/256px-Issn_barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/EAN_2\" class=\"mw-redirect\">EAN 2</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Addon code (magazines), <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved &#x2013; not an own symbology &#x2013; to be used only with an EAN/UPC according to ISO/IEC 15420\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Isbn_add5.png\" class=\"image\"><img alt=\"Isbn add5.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Isbn_add5.png/128px-Isbn_add5.png\" width=\"128\" height=\"66\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Isbn_add5.png/192px-Isbn_add5.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Isbn_add5.png/256px-Isbn_add5.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/EAN_5\" class=\"mw-redirect\">EAN 5</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Addon code (books), <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved &#x2013; not an own symbology &#x2013; to be used only with an EAN/UPC according to ISO/IEC 15420\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:EAN8.svg\" class=\"image\"><img alt=\"EAN8.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/EAN8.svg/128px-EAN8.svg.png\" width=\"128\" height=\"125\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/EAN8.svg/192px-EAN8.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/EAN8.svg/256px-EAN8.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/EAN-8\">EAN-8</a>, <a href=\"https://en.wikipedia.org/wiki/EAN-13\" class=\"mw-redirect\">EAN-13</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Worldwide retail, <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved &#x2013; International Standard ISO/IEC 15420\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Facing_Identification_Mark\">Facing Identification Mark</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>USPS business reply mail\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Gs1-128_example.svg\" class=\"image\"><img alt=\"Gs1-128 example.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Gs1-128_example.svg/128px-Gs1-128_example.svg.png\" width=\"128\" height=\"42\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Gs1-128_example.svg/192px-Gs1-128_example.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Gs1-128_example.svg/256px-Gs1-128_example.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/GS1-128\">GS1-128</a> (formerly named UCC/EAN-128), incorrectly referenced as <a href=\"https://en.wikipedia.org/wiki/EAN_128\" class=\"mw-redirect\">EAN 128</a> and <a href=\"https://en.wikipedia.org/wiki/UCC_128\" class=\"mw-redirect\">UCC 128</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Various, <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved &#x2013; just an application of the Code 128 (ISO/IEC 15417) using the ANS MH10.8.2 AI Datastructures. It is not a separate symbology.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Databar_14_00075678164125.png\" class=\"image\"><img alt=\"Databar 14 00075678164125.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Databar_14_00075678164125.png/128px-Databar_14_00075678164125.png\" width=\"128\" height=\"93\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Databar_14_00075678164125.png/192px-Databar_14_00075678164125.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Databar_14_00075678164125.png/256px-Databar_14_00075678164125.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/GS1_DataBar\">GS1 DataBar</a>, formerly Reduced Space Symbology (RSS)</td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Various, <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Intelligent_Mail_Barcode_Wiki22.png\" class=\"image\"><img alt=\"Intelligent Mail Barcode Wiki22.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Intelligent_Mail_Barcode_Wiki22.png/128px-Intelligent_Mail_Barcode_Wiki22.png\" width=\"128\" height=\"46\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Intelligent_Mail_Barcode_Wiki22.png/192px-Intelligent_Mail_Barcode_Wiki22.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Intelligent_Mail_Barcode_Wiki22.png/256px-Intelligent_Mail_Barcode_Wiki22.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Intelligent_Mail_barcode\">Intelligent Mail barcode</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>United States Postal Service, replaces both POSTNET and PLANET symbols (formerly named <a href=\"https://en.wikipedia.org/wiki/OneCode\" class=\"mw-redirect\">OneCode</a>)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:ITF-14.svg\" class=\"image\"><img alt=\"ITF-14.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/ITF-14.svg/128px-ITF-14.svg.png\" width=\"128\" height=\"40\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/ITF-14.svg/192px-ITF-14.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/ITF-14.svg/256px-ITF-14.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/ITF-14\">ITF-14</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Non-retail packaging levels, <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved &#x2013; is just an Interleaved 2/5 Code (ISO/IEC 16390) with a few additional specifications, according to the GS1 General Specifications\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:ITF-6_barcode.svg\" class=\"image\"><img alt=\"ITF-6 barcode.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/ITF-6_barcode.svg/128px-ITF-6_barcode.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/ITF-6_barcode.svg/192px-ITF-6_barcode.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/ITF-6_barcode.svg/256px-ITF-6_barcode.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/ITF-6\">ITF-6</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Interleaved_2_of_5\">Interleaved 2 of 5</a> barcode to encode an addon to <a href=\"https://en.wikipedia.org/wiki/ITF-14\">ITF-14</a> and ITF-16 barcodes. The code is used to encode additional data such as items quantity or container weight\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:EAN-13-5901234123457.svg\" class=\"image\"><img alt=\"EAN-13-5901234123457.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/EAN-13-5901234123457.svg/128px-EAN-13-5901234123457.svg.png\" width=\"128\" height=\"93\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/EAN-13-5901234123457.svg/192px-EAN-13-5901234123457.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/EAN-13-5901234123457.svg/256px-EAN-13-5901234123457.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Japan_Article_Number\" class=\"mw-redirect\">JAN</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Used in Japan, similar to and compatible with <a href=\"https://en.wikipedia.org/wiki/EAN-13\" class=\"mw-redirect\">EAN-13</a> (ISO/IEC 15420)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Japan_Post_barcode.png\" class=\"image\"><img alt=\"Japan Post barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Japan_Post_barcode.png/128px-Japan_Post_barcode.png\" width=\"128\" height=\"9\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Japan_Post_barcode.png/192px-Japan_Post_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Japan_Post_barcode.png/256px-Japan_Post_barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Japan_Post\">Japan Post</a> barcode</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>Japan Post\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:KarTrak_ACI_codes.svg\" class=\"image\"><img alt=\"KarTrak ACI codes.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/KarTrak_ACI_codes.svg/128px-KarTrak_ACI_codes.svg.png\" width=\"128\" height=\"322\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/KarTrak_ACI_codes.svg/192px-KarTrak_ACI_codes.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/KarTrak_ACI_codes.svg/256px-KarTrak_ACI_codes.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/KarTrak\">KarTrak</a> ACI</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Coloured bars</td>\\n' +\n    '<td>Used in North America on railroad rolling equipment\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:MSI-barcode.png\" class=\"image\"><img alt=\"MSI-barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/MSI-barcode.png/128px-MSI-barcode.png\" width=\"128\" height=\"56\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/MSI-barcode.png/192px-MSI-barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/MSI-barcode.png/256px-MSI-barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/MSI_Barcode\">MSI</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Used for warehouse shelves and inventory\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Pharmacode_example.svg\" class=\"image\"><img alt=\"Pharmacode example.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Pharmacode_example.svg/128px-Pharmacode_example.svg.png\" width=\"128\" height=\"142\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Pharmacode_example.svg/192px-Pharmacode_example.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/Pharmacode_example.svg/256px-Pharmacode_example.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Pharmacode\">Pharmacode</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Pharmaceutical packaging (no international standard available)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Planet_Barcode_Format.png\" class=\"image\"><img alt=\"Planet Barcode Format.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Planet_Barcode_Format.png/128px-Planet_Barcode_Format.png\" width=\"128\" height=\"55\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Planet_Barcode_Format.png/192px-Planet_Barcode_Format.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Planet_Barcode_Format.png/256px-Planet_Barcode_Format.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Postal_Alpha_Numeric_Encoding_Technique\">PLANET</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Tall/short</td>\\n' +\n    '<td>United States Postal Service (no international standard available)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Plessey_barcode.svg\" class=\"image\"><img alt=\"Plessey barcode.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Plessey_barcode.svg/128px-Plessey_barcode.svg.png\" width=\"128\" height=\"23\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Plessey_barcode.svg/192px-Plessey_barcode.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Plessey_barcode.svg/256px-Plessey_barcode.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Plessey_Code\">Plessey</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Catalogs, store shelves, inventory (no international standard available)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Canada_Post_d52.01_domestic_barcode.png\" class=\"image\"><img alt=\"Canada Post d52.01 domestic barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Canada_Post_d52.01_domestic_barcode.png/128px-Canada_Post_d52.01_domestic_barcode.png\" width=\"128\" height=\"16\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Canada_Post_d52.01_domestic_barcode.png/192px-Canada_Post_d52.01_domestic_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/8/84/Canada_Post_d52.01_domestic_barcode.png/256px-Canada_Post_d52.01_domestic_barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/PostBar\">PostBar</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>Canadian Post office\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:POSTNET_BAR.svg\" class=\"image\"><img alt=\"POSTNET BAR.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/POSTNET_BAR.svg/6px-POSTNET_BAR.svg.png\" width=\"6\" height=\"14\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/POSTNET_BAR.svg/9px-POSTNET_BAR.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/POSTNET_BAR.svg/12px-POSTNET_BAR.svg.png 2x\"></a> <a href=\"https://en.wikipedia.org/wiki/File:POSTNET_1.svg\" class=\"image\"><img alt=\"POSTNET 1.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/POSTNET_1.svg/30px-POSTNET_1.svg.png\" width=\"30\" height=\"14\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/POSTNET_1.svg/45px-POSTNET_1.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/POSTNET_1.svg/60px-POSTNET_1.svg.png 2x\"></a> <a href=\"https://en.wikipedia.org/wiki/File:POSTNET_2.svg\" class=\"image\"><img alt=\"POSTNET 2.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/POSTNET_2.svg/30px-POSTNET_2.svg.png\" width=\"30\" height=\"14\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/POSTNET_2.svg/45px-POSTNET_2.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/POSTNET_2.svg/60px-POSTNET_2.svg.png 2x\"></a> <a href=\"https://en.wikipedia.org/wiki/File:POSTNET_3.svg\" class=\"image\"><img alt=\"POSTNET 3.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/POSTNET_3.svg/30px-POSTNET_3.svg.png\" width=\"30\" height=\"14\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/POSTNET_3.svg/45px-POSTNET_3.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/POSTNET_3.svg/60px-POSTNET_3.svg.png 2x\"></a> <a href=\"https://en.wikipedia.org/wiki/File:POSTNET_BAR.png\" class=\"image\"><img alt=\"POSTNET BAR.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/4/43/POSTNET_BAR.png\" width=\"6\" height=\"14\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/POSTNET\">POSTNET</a></td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>Tall/short</td>\\n' +\n    '<td>United States Postal Service (no international standard available)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Address_with_RM4SCC_barcode.svg\" class=\"image\"><img alt=\"Address with RM4SCC barcode.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Address_with_RM4SCC_barcode.svg/128px-Address_with_RM4SCC_barcode.svg.png\" width=\"128\" height=\"88\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Address_with_RM4SCC_barcode.svg/192px-Address_with_RM4SCC_barcode.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Address_with_RM4SCC_barcode.svg/256px-Address_with_RM4SCC_barcode.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/RM4SCC\">RM4SCC</a> / KIX</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>Royal Mail / <a href=\"https://en.wikipedia.org/wiki/PostNL\">PostNL</a>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Royal_Mail_mailmark_C_barcode.png\" class=\"image\"><img alt=\"Royal Mail mailmark C barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Royal_Mail_mailmark_C_barcode.png/128px-Royal_Mail_mailmark_C_barcode.png\" width=\"128\" height=\"13\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Royal_Mail_mailmark_C_barcode.png/192px-Royal_Mail_mailmark_C_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Royal_Mail_mailmark_C_barcode.png/256px-Royal_Mail_mailmark_C_barcode.png 2x\"></a></td>\\n' +\n    '<td>RM Mailmark C</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>Royal Mail\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Royal_Mail_mailmark_L_barcode.png\" class=\"image\"><img alt=\"Royal Mail mailmark L barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Royal_Mail_mailmark_L_barcode.png/128px-Royal_Mail_mailmark_L_barcode.png\" width=\"128\" height=\"10\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Royal_Mail_mailmark_L_barcode.png/192px-Royal_Mail_mailmark_L_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Royal_Mail_mailmark_L_barcode.png/256px-Royal_Mail_mailmark_L_barcode.png 2x\"></a></td>\\n' +\n    '<td>RM Mailmark L</td>\\n' +\n    '<td>Discrete</td>\\n' +\n    '<td>4 bar heights</td>\\n' +\n    '<td>Royal Mail\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Telepen_barcode.png\" class=\"image\"><img alt=\"Telepen barcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Telepen_barcode.png/128px-Telepen_barcode.png\" width=\"128\" height=\"30\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Telepen_barcode.png/192px-Telepen_barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Telepen_barcode.png/256px-Telepen_barcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Telepen\">Telepen</a></td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Two</td>\\n' +\n    '<td>Libraries (UK)\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:UPC_A.svg\" class=\"image\"><img alt=\"UPC A.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/UPC_A.svg/128px-UPC_A.svg.png\" width=\"128\" height=\"92\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/UPC_A.svg/192px-UPC_A.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/UPC_A.svg/256px-UPC_A.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Universal_Product_Code\">Universal Product Code</a> (UPC-A and UPC-E)</td>\\n' +\n    '<td>Continuous</td>\\n' +\n    '<td>Many</td>\\n' +\n    '<td>Worldwide retail, <a href=\"https://en.wikipedia.org/wiki/GS1\">GS1</a>-approved &#x2013; International Standard ISO/IEC 15420\\n' +\n    '</td></tr></tbody></table>\\n' +\n    '<h3><span id=\"Matrix_.282D.29_barcodes\"></span><span class=\"mw-headline\" id=\"Matrix_(2D)_barcodes\"><span class=\"anchor\" id=\"2D_barcodes\"></span> Matrix (2D) barcodes</span></h3>\\n' +\n    '<p>A <i>matrix code</i>, also termed a <i>2D barcode</i> or simply a <i>2D code</i>, is a two-dimensional way to represent information. It is similar to a linear (1-dimensional) barcode, but can represent more data per unit area.\\n' +\n    '</p>\\n' +\n    '<table class=\"wikitable\">\\n' +\n    '\\n' +\n    '<tbody><tr>\\n' +\n    '<th>Example</th>\\n' +\n    '<th>Name</th>\\n' +\n    '<th>Notes\\n' +\n    '</th></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Ar_code.png\" class=\"image\"><img alt=\"Ar code.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Ar_code.png/128px-Ar_code.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Ar_code.png/192px-Ar_code.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Ar_code.png/256px-Ar_code.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/ARToolKit\">AR Code</a></td>\\n' +\n    '<td>A type of marker used for placing content inside <a href=\"https://en.wikipedia.org/wiki/Augmented_reality\">augmented reality</a> applications. Some AR Codes can contain QR codes inside, so that content AR content can be linked to.<sup id=\"cite_ref-39\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-39\">[39]</a></sup> See also <a href=\"https://en.wikipedia.org/wiki/ARTag\">ARTag</a>.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Azteccodeexample.svg\" class=\"image\"><img alt=\"Azteccodeexample.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Azteccodeexample.svg/128px-Azteccodeexample.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Azteccodeexample.svg/192px-Azteccodeexample.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Azteccodeexample.svg/256px-Azteccodeexample.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Aztec_Code\">Aztec Code</a></td>\\n' +\n    '<td>Designed by Andrew Longacre at Welch Allyn (now Honeywell Scanning and Mobility). Public domain. &#x2013; International Standard: ISO/IEC 24778\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:BCode_barcode_1683.png\" class=\"image\"><img alt=\"A bCode matrix barcode encoding the identifier 1683\" src=\"https://upload.wikimedia.org/wikipedia/commons/4/44/BCode_barcode_1683.png\" width=\"62\" height=\"62\"></a>\\n' +\n    '</td>\\n' +\n    '<td>bCode\\n' +\n    '</td>\\n' +\n    '<td>A barcode designed for the study of insect behavior.<sup id=\"cite_ref-40\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-40\">[40]</a></sup> Encodes an 11 bit identifier and 16 bits of read error detection and error correction information. Predominately used for marking <a href=\"https://en.wikipedia.org/wiki/Honey_bee\">honey bees</a>, but can also be applied to other animals.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=BEEtag&amp;action=edit&amp;redlink=1\" class=\"new\">BEEtag</a>\\n' +\n    '</td>\\n' +\n    '<td>A 25 bit (5x5) code matrix of black and white pixels that is unique to each tag surrounded by a white pixel border and a black pixel border. The 25-bit matrix consists of a 15-bit identity code, and a 10-bit error check.<sup id=\"cite_ref-41\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-41\">[41]</a></sup> It is designed to be a low-cost, image-based tracking system for the study of animal behavior and locomotion.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=BeeTagg&amp;action=edit&amp;redlink=1\" class=\"new\">BeeTagg</a>\\n' +\n    '</td>\\n' +\n    '<td>A 2D barcode with honeycomb structures suitable for mobile tagging and was developed by the Swiss company connvision AG.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Bokode\">Bokode</a>\\n' +\n    '</td>\\n' +\n    '<td>A type of <a href=\"https://en.wikipedia.org/wiki/Automatic_identification_and_data_capture\">data tag</a> which holds much more information than a barcode over the same area. They were developed by a team led by <a href=\"https://en.wikipedia.org/wiki/Ramesh_Raskar\">Ramesh Raskar</a> at the <a href=\"https://en.wikipedia.org/wiki/MIT_Media_Lab\">MIT Media Lab</a>. The bokode pattern is a tiled series of <a href=\"https://en.wikipedia.org/wiki/Data_Matrix\">Data Matrix</a> codes.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Boxing_4kv6_0.png\" class=\"image\"><img alt=\"Boxing 4kv6 0.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Boxing_4kv6_0.png/128px-Boxing_4kv6_0.png\" width=\"128\" height=\"68\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Boxing_4kv6_0.png/192px-Boxing_4kv6_0.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Boxing_4kv6_0.png/256px-Boxing_4kv6_0.png 2x\"></a>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Boxing_barcode\">Boxing</a>\\n' +\n    '</td>\\n' +\n    '<td>A high-capacity 2D barcode is used on <a href=\"https://en.wikipedia.org/w/index.php?title=PiqlFilm&amp;action=edit&amp;redlink=1\" class=\"new\">piqlFilm</a> by Piql AS<sup id=\"cite_ref-42\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-42\">[42]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td>Code 1</td>\\n' +\n    '<td>Public domain. Code 1 is currently used in the health care industry for medicine labels and the recycling industry to encode container content for sorting.<sup id=\"cite_ref-43\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-43\">[43]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Code_16K_wikipedia.png\" class=\"image\"><img alt=\"Code 16K wikipedia.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Code_16K_wikipedia.png/128px-Code_16K_wikipedia.png\" width=\"128\" height=\"157\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Code_16K_wikipedia.png/192px-Code_16K_wikipedia.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Code_16K_wikipedia.png/256px-Code_16K_wikipedia.png 2x\"></a>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Code_16K&amp;action=edit&amp;redlink=1\" class=\"new\">Code 16K</a>\\n' +\n    '</td>\\n' +\n    '<td>The Code 16K (1988) is a multi-row bar code developed by Ted Williams at Laserlight Systems (USA) in 1992. In the US and France, the code is used in the electronics industry to identify chips and printed circuit boards. Medical applications in the USA are well known. Williams also developed Code 128, and the structure of 16K is based on Code 128. Not coincidentally, 128 squared happened to equal 16,000 or 16K for short. Code 16K resolved an inherent problem with Code 49.  Code 49&apos;s structure requires a large amount of memory for encoding and decoding tables and algorithms. 16K is a stacked symbology.<sup id=\"cite_ref-2-Dimensional_Bar_Code_Page_44-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-2-Dimensional_Bar_Code_Page-44\">[44]</a></sup><sup id=\"cite_ref-45\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-45\">[45]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td>ColorCode</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=ColorZip&amp;action=edit&amp;redlink=1\" class=\"new\">ColorZip</a><sup id=\"cite_ref-46\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-46\">[46]</a></sup> developed colour barcodes that can be read by camera phones from TV screens; mainly used in Korea.<sup id=\"cite_ref-47\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-47\">[47]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td>Color Construct Code</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Color_Construct_Code&amp;action=edit&amp;redlink=1\" class=\"new\">Color Construct Code</a> is one of the few barcode symbologies designed to take advantage of multiple colors.<sup id=\"cite_ref-48\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-48\">[48]</a></sup><sup id=\"cite_ref-49\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-49\">[49]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:PhotoTAN_mit_Orientierungsmarkierungen.svg\" class=\"image\"><img alt=\"PhotoTAN mit Orientierungsmarkierungen.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/PhotoTAN_mit_Orientierungsmarkierungen.svg/128px-PhotoTAN_mit_Orientierungsmarkierungen.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/PhotoTAN_mit_Orientierungsmarkierungen.svg/192px-PhotoTAN_mit_Orientierungsmarkierungen.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/PhotoTAN_mit_Orientierungsmarkierungen.svg/256px-PhotoTAN_mit_Orientierungsmarkierungen.svg.png 2x\"></a></td>\\n' +\n    '<td>Cronto Visual Cryptogram\\n' +\n    '</td>\\n' +\n    '<td>The Cronto Visual Cryptogram (also called photoTAN) is a specialized color barcode, spun out from research at the <a href=\"https://en.wikipedia.org/wiki/University_of_Cambridge\">University of Cambridge</a> by Igor Drokov, <a href=\"https://en.wikipedia.org/wiki/Steven_Murdoch\">Steven Murdoch</a>, and Elena Punskaya.<sup id=\"cite_ref-cronto_50-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-cronto-50\">[50]</a></sup> It is used for transaction signing in e-banking; the barcode contains encrypted transaction data which is then used as a <a href=\"https://en.wikipedia.org/wiki/Challenge%E2%80%93response_authentication\">challenge</a> to compute a <a href=\"https://en.wikipedia.org/wiki/Transaction_authentication_number\">transaction authentication number</a> using a <a href=\"https://en.wikipedia.org/wiki/Security_token\">security token</a>.<sup id=\"cite_ref-51\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-51\">[51]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/CyberCode\">CyberCode</a></td>\\n' +\n    '<td>From Sony.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td>d-touch</td>\\n' +\n    '<td>readable when printed on deformable gloves and stretched and distorted<sup id=\"cite_ref-52\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-52\">[52]</a></sup><sup id=\"cite_ref-53\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-53\">[53]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=DataGlyphs&amp;action=edit&amp;redlink=1\" class=\"new\">DataGlyphs</a></td>\\n' +\n    '<td>From Palo Alto Research Center (also termed Xerox PARC).<sup id=\"cite_ref-54\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-54\">[54]</a></sup>\\n' +\n    '<p>Patented.<sup id=\"cite_ref-55\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-55\">[55]</a></sup>\\n' +\n    'DataGlyphs can be embedded into a half-tone image or background shading pattern in a way that is almost perceptually invisible, similar to <a href=\"https://en.wikipedia.org/wiki/Steganography\">steganography</a>.<sup id=\"cite_ref-56\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-56\">[56]</a></sup><sup id=\"cite_ref-57\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-57\">[57]</a></sup>\\n' +\n    '</p>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Datamatrix.svg\" class=\"image\"><img alt=\"Datamatrix.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Datamatrix.svg/128px-Datamatrix.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Datamatrix.svg/192px-Datamatrix.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/e/e8/Datamatrix.svg/256px-Datamatrix.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Data_Matrix\">Data Matrix</a></td>\\n' +\n    '<td>From <a href=\"https://en.wikipedia.org/w/index.php?title=Microscan_Systems&amp;action=edit&amp;redlink=1\" class=\"new\">Microscan Systems</a>, formerly RVSI Acuity CiMatrix/Siemens. Public domain. Increasingly used throughout the United States. Single segment Data Matrix is also termed <a href=\"https://en.wikipedia.org/wiki/Semacode\">Semacode</a>. &#x2013; International Standard: ISO/IEC 16022.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Datastrip_Code\" class=\"mw-redirect\">Datastrip Code</a></td>\\n' +\n    '<td>From Datastrip, Inc.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Digimarc#Digimarc_Barcode\">Digimarc Barcode</a>\\n' +\n    '</td>\\n' +\n    '<td>The Digimarc Barcode is a unique identifier, or code, based on imperceptible patterns that can be applied to marketing materials, including packaging, displays, ads in magazines, circulars, radio and television<sup id=\"cite_ref-58\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-58\">[58]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Digital_paper\">digital paper</a></td>\\n' +\n    '<td>patterned paper used in conjunction with a <a href=\"https://en.wikipedia.org/wiki/Digital_pen\">digital pen</a> to create handwritten digital documents. The printed dot pattern uniquely identifies the position coordinates on the paper.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:DotCode_Wikipedia.png\" class=\"image\"><img alt=\"DotCode Wikipedia.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/DotCode_Wikipedia.png/128px-DotCode_Wikipedia.png\" width=\"128\" height=\"90\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/e/e2/DotCode_Wikipedia.png 1.5x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=DotCode&amp;action=edit&amp;redlink=1\" class=\"new\">DotCode</a></td>\\n' +\n    '<td>Standardized as AIM Dotcode Rev 3.0. Public domain. Used to track individual cigarette and pharmaceutical packages.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Dot_Code_A&amp;action=edit&amp;redlink=1\" class=\"new\">Dot Code A</a></td>\\n' +\n    '<td>Also known as <i>Philips Dot Code</i>.<sup id=\"cite_ref-59\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-59\">[59]</a></sup> Patented in 1988.<sup id=\"cite_ref-60\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-60\">[60]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a class=\"external text\" href=\"https://web.archive.org/web/20170216045744/https://sites.gs1us.org/mobilescan/home\">DWCode</a>\\n' +\n    '</td>\\n' +\n    '<td>Introduced by GS1 US and GS1 Germany, the DWCode is a unique, imperceptible data carrier that is repeated across the entire graphics design of a package<sup id=\"cite_ref-61\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-61\">[61]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:EZcode_Example.png\" class=\"image\"><img alt=\"Example of an EZcode.\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/90/EZcode_Example.png/128px-EZcode_Example.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/9/90/EZcode_Example.png 1.5x\"></a></td>\\n' +\n    '<td>EZcode</td>\\n' +\n    '<td>Designed for decoding by cameraphones;<sup id=\"cite_ref-62\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-62\">[62]</a></sup> from ScanLife.<sup id=\"cite_ref-Steeman_63-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Steeman-63\">[63]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Han_Xin_2D_Barcode.svg\" class=\"image\"><img alt=\"Han Xin 2D Barcode.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Han_Xin_2D_Barcode.svg/128px-Han_Xin_2D_Barcode.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Han_Xin_2D_Barcode.svg/192px-Han_Xin_2D_Barcode.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/Han_Xin_2D_Barcode.svg/256px-Han_Xin_2D_Barcode.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Han_Xin_Barcode&amp;action=edit&amp;redlink=1\" class=\"new\">Han Xin Barcode</a></td>\\n' +\n    '<td>Barcode designed to encode <a href=\"https://en.wikipedia.org/wiki/Chinese_characters\">Chinese characters</a> introduced by <a href=\"https://en.wikipedia.org/wiki/Association_for_Automatic_Identification_and_Mobility\">Association for Automatic Identification and Mobility</a> in 2011.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:High_Capacity_Color_Barcode_Tag.svg\" class=\"image\"><img alt=\"High Capacity Color Barcode Tag.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/High_Capacity_Color_Barcode_Tag.svg/128px-High_Capacity_Color_Barcode_Tag.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/High_Capacity_Color_Barcode_Tag.svg/192px-High_Capacity_Color_Barcode_Tag.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/High_Capacity_Color_Barcode_Tag.svg/256px-High_Capacity_Color_Barcode_Tag.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/High_Capacity_Color_Barcode\">High Capacity Color Barcode</a></td>\\n' +\n    '<td><b>HCCB</b> was developed by <a href=\"https://en.wikipedia.org/wiki/Microsoft\">Microsoft</a>; licensed by <a href=\"https://en.wikipedia.org/wiki/International_Standard_Audiovisual_Number_International_Agency\" class=\"mw-redirect\">ISAN-IA</a>.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=HueCode&amp;action=edit&amp;redlink=1\" class=\"new\">HueCode</a></td>\\n' +\n    '<td>From Robot Design Associates. Uses greyscale or colour.<sup id=\"cite_ref-64\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-64\">[64]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=InterCode&amp;action=edit&amp;redlink=1\" class=\"new\">InterCode</a></td>\\n' +\n    '<td>From <a href=\"https://en.wikipedia.org/w/index.php?title=Iconlab,_Inc&amp;action=edit&amp;redlink=1\" class=\"new\">Iconlab, Inc</a>. The standard 2D barcode in South Korea. All 3 South Korean mobile carriers put the scanner program of this code into their handsets to access mobile internet, as a default embedded program.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '<p><a href=\"https://en.wikipedia.org/wiki/File:JAB-code.png\" class=\"image\"><img alt=\"JAB-code.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/JAB-code.png/128px-JAB-code.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ae/JAB-code.png/192px-JAB-code.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/a/ae/JAB-code.png 2x\"></a>\\n' +\n    '</p>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/QR_code#JAB_code\">JAB Code</a>\\n' +\n    '</td>\\n' +\n    '<td><b>J</b>ust <b>A</b>nother <b>B</b>ar Code is a colored 2D barcode. Square or rectangle. License free\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:MaxiCode.svg\" class=\"image\"><img alt=\"MaxiCode.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/MaxiCode.svg/128px-MaxiCode.svg.png\" width=\"128\" height=\"123\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/MaxiCode.svg/192px-MaxiCode.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/MaxiCode.svg/256px-MaxiCode.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/MaxiCode\">MaxiCode</a></td>\\n' +\n    '<td>Used by <a href=\"https://en.wikipedia.org/wiki/United_Parcel_Service\">United Parcel Service</a>. Now public domain.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=MCode&amp;action=edit&amp;redlink=1\" class=\"new\">mCode</a>\\n' +\n    '</td>\\n' +\n    '<td>Designed by NextCode Corporation, specifically to work with mobile phones and mobile services.<sup id=\"cite_ref-65\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-65\">[65]</a></sup> It is implementing an independent error detection technique preventing false decoding, it uses a variable-size error correction polynomial, which depends on the exact size of the code.<sup id=\"cite_ref-:0_66-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:0-66\">[66]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Mobile_Multi-Coloured_Composite\" class=\"mw-redirect\">MMCC</a></td>\\n' +\n    '<td>Designed to disseminate high capacity mobile phone content via existing colour print and electronic media, without the need for network connectivity\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:NexCode.png\" class=\"image\"><img alt=\"NexCode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/NexCode.png/128px-NexCode.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/a/ac/NexCode.png 1.5x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=NexCode&amp;action=edit&amp;redlink=1\" class=\"new\">NexCode</a></td>\\n' +\n    '<td>NexCode is developed and patented by S5 Systems.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/Nintendo_e-Reader#Dot_code\">Nintendo e-Reader#Dot code</a></td>\\n' +\n    '<td>Developed by <a href=\"https://en.wikipedia.org/wiki/Olympus_Corporation\">Olympus Corporation</a> to store songs, images, and mini-games for <a href=\"https://en.wikipedia.org/wiki/Game_Boy_Advance\">Game Boy Advance</a> on <a href=\"https://en.wikipedia.org/wiki/Pok%C3%A9mon_Trading_Card_Game\">Pok&#xE9;mon trading cards</a>.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Better_Sample_PDF417.png\" class=\"image\"><img alt=\"Better Sample PDF417.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Better_Sample_PDF417.png/128px-Better_Sample_PDF417.png\" width=\"128\" height=\"56\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Better_Sample_PDF417.png/192px-Better_Sample_PDF417.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Better_Sample_PDF417.png/256px-Better_Sample_PDF417.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/PDF417\">PDF417</a></td>\\n' +\n    '<td>Originated by <a href=\"https://en.wikipedia.org/wiki/Symbol_Technologies\">Symbol Technologies</a>. Public domain. &#x2013; International standard: <a href=\"https://en.wikipedia.org/wiki/ISO\" class=\"mw-redirect\">ISO</a>/<a href=\"https://en.wikipedia.org/wiki/International_Electrotechnical_Commission\">IEC</a> 15438\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Qode.png\" class=\"image\"><img alt=\"Qode example.\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Qode.png/128px-Qode.png\" width=\"128\" height=\"138\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/e/e4/Qode.png 1.5x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Qode_(barcode)&amp;action=edit&amp;redlink=1\" class=\"new\">Qode</a></td>\\n' +\n    '<td>American proprietary and patented 2D barcode from NeoMedia Technologies, Inc.<sup id=\"cite_ref-Steeman_63-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Steeman-63\">[63]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:QR_code_for_mobile_English_Wikipedia.svg\" class=\"image\"><img alt=\"QR code for mobile English Wikipedia.svg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/QR_code_for_mobile_English_Wikipedia.svg/128px-QR_code_for_mobile_English_Wikipedia.svg.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/QR_code_for_mobile_English_Wikipedia.svg/192px-QR_code_for_mobile_English_Wikipedia.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/QR_code_for_mobile_English_Wikipedia.svg/256px-QR_code_for_mobile_English_Wikipedia.svg.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/QR_code\">QR code</a></td>\\n' +\n    '<td>Initially developed, patented and owned by <a href=\"https://en.wikipedia.org/wiki/Denso_Wave\" class=\"mw-redirect\">Denso Wave</a> for automotive components management; they have chosen not to exercise their <a href=\"https://en.wikipedia.org/wiki/Patent_right\" class=\"mw-redirect\">patent rights</a>. Can encode <a href=\"https://en.wikipedia.org/wiki/Latin_script\">Latin</a> and Japanese Kanji and Kana characters, music, images, URLs, emails. De facto standard for Japanese cell phones. Used with <a href=\"https://en.wikipedia.org/wiki/BlackBerry_Messenger\" class=\"mw-redirect\">BlackBerry Messenger</a> to pick up contacts rather than using a PIN code. The most frequently used type of code to scan with smartphones. Public Domain. &#x2013; International Standard: ISO/IEC 18004\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td>Screencode</td>\\n' +\n    '<td>Developed and patented<sup id=\"cite_ref-67\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-67\">[67]</a></sup><sup id=\"cite_ref-68\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-68\">[68]</a></sup> by <a href=\"https://en.wikipedia.org/wiki/Hewlett-Packard\">Hewlett-Packard</a> Labs. A time-varying 2D pattern using to encode data via brightness fluctuations in an image, for the purpose of high bandwidth data transfer from computer displays to smartphones via smartphone camera input.  Inventors <a href=\"https://en.wikipedia.org/w/index.php?title=Timothy_Kindberg&amp;action=edit&amp;redlink=1\" class=\"new\">Timothy Kindberg</a> and <a href=\"https://en.wikipedia.org/w/index.php?title=John_Collomosse&amp;action=edit&amp;redlink=1\" class=\"new\">John Collomosse</a>, publicly disclosed at ACM HotMobile 2008.<sup id=\"cite_ref-69\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-69\">[69]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:Shotcode.png\" class=\"image\"><img alt=\"Shotcode.png\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Shotcode.png/128px-Shotcode.png\" width=\"128\" height=\"128\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Shotcode.png/192px-Shotcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Shotcode.png/256px-Shotcode.png 2x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/ShotCode\">ShotCode</a></td>\\n' +\n    '<td>Circular barcodes for <a href=\"https://en.wikipedia.org/wiki/Camera_phone\">camera phones</a>.  Originally from High Energy Magic Ltd in name Spotcode. Before that most likely termed TRIPCode.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td>Snapcode, also called Boo-R code</td>\\n' +\n    '<td>used by <a href=\"https://en.wikipedia.org/wiki/Snapchat\">Snapchat</a>, <a href=\"https://en.wikipedia.org/wiki/Spectacles_(product)\">Spectacles</a>, etc. US9111164B1<sup id=\"cite_ref-70\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-70\">[70]</a></sup><sup id=\"cite_ref-71\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-71\">[71]</a></sup><sup id=\"cite_ref-72\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-72\">[72]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td>Snowflake Code\\n' +\n    '</td>\\n' +\n    '<td>A proprietary code developed by Electronic Automation Ltd. in 1981. It is possible to encode more than 100 numeric digits in a space of only 5mm x 5mm. User selectable error correction allows up to 40% of the code to be destroyed and still remain readable. The code is used in the pharmaceutical industry and has an advantage that it can be applied to products and materials in a wide variety of ways, including printed labels, ink-jet printing, laser-etching, indenting or hole punching.<sup id=\"cite_ref-2-Dimensional_Bar_Code_Page_44-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-2-Dimensional_Bar_Code_Page-44\">[44]</a></sup><sup id=\"cite_ref-73\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-73\">[73]</a></sup><sup id=\"cite_ref-74\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-74\">[74]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/File:SPARQCode-sample.gif\" class=\"image\"><img alt=\"SPARQCode-sample.gif\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/65/SPARQCode-sample.gif/128px-SPARQCode-sample.gif\" width=\"128\" height=\"148\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/6/65/SPARQCode-sample.gif 1.5x\"></a></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/wiki/SPARQCode\">SPARQCode</a></td>\\n' +\n    '<td>QR code encoding standard from MSKYNET, Inc.\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td>\\n' +\n    '</td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=Trillcode&amp;action=edit&amp;redlink=1\" class=\"new\">Trillcode</a>\\n' +\n    '</td>\\n' +\n    '<td>Designed for mobile phone scanning.<sup id=\"cite_ref-75\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-75\">[75]</a></sup> Developed by Lark Computer, a Romanian company.<sup id=\"cite_ref-:0_66-1\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-:0-66\">[66]</a></sup>\\n' +\n    '</td></tr>\\n' +\n    '<tr>\\n' +\n    '<td></td>\\n' +\n    '<td><a href=\"https://en.wikipedia.org/w/index.php?title=VOICEYE&amp;action=edit&amp;redlink=1\" class=\"new\">VOICEYE</a></td>\\n' +\n    '<td>Developed and patented by VOICEYE, Inc. in South Korea, it aims to allow blind and visually impaired people to access printed information. It also claims to be the 2D barcode that has the world&apos;s largest storage capacity.\\n' +\n    '</td></tr></tbody></table>\\n' +\n    '<h3><span class=\"mw-headline\" id=\"Example_images\">Example images</span></h3>\\n' +\n    '<ul class=\"gallery mw-gallery-traditional\">\\n' +\n    '\\t<li class=\"gallerycaption\">First, Second and Third Generation Barcodes</li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:UPC-A-036000291452.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/UPC-A-036000291452.png/120px-UPC-A-036000291452.png\" width=\"120\" height=\"87\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/UPC-A-036000291452.png/180px-UPC-A-036000291452.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/UPC-A-036000291452.png/240px-UPC-A-036000291452.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>GTIN-12 number encoded in UPC-A barcode symbol. First and last digit are always placed outside the symbol to indicate Quiet Zones that are necessary for barcode scanners to work properly\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:EAN-13-5901234123457.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/EAN-13-5901234123457.svg/120px-EAN-13-5901234123457.svg.png\" width=\"120\" height=\"87\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/EAN-13-5901234123457.svg/180px-EAN-13-5901234123457.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/EAN-13-5901234123457.svg/240px-EAN-13-5901234123457.svg.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>EAN-13 (GTIN-13) number encoded in EAN-13 barcode symbol. First digit is always placed outside the symbol, additionally right quiet zone indicator (&gt;) is used to indicate Quiet Zones that are necessary for barcode scanners to work properly\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Code93.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Code93.png/120px-Code93.png\" width=\"120\" height=\"53\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Code93.png/180px-Code93.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Code93.png/240px-Code93.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>&quot;Wikipedia&quot; encoded in <a href=\"https://en.wikipedia.org/wiki/Code_93\">Code 93</a>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Code39.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Code39.png/120px-Code39.png\" width=\"120\" height=\"51\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Code39.png/180px-Code39.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/4/4f/Code39.png/240px-Code39.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>&quot;*WIKI39*&quot; encoded in <a href=\"https://en.wikipedia.org/wiki/Code_39\">Code 39</a>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Wikipedia_barcode_128.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Wikipedia_barcode_128.svg/120px-Wikipedia_barcode_128.svg.png\" width=\"120\" height=\"74\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Wikipedia_barcode_128.svg/180px-Wikipedia_barcode_128.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/f/f7/Wikipedia_barcode_128.svg/240px-Wikipedia_barcode_128.svg.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>&apos;Wikipedia&quot; encoded in <a href=\"https://en.wikipedia.org/wiki/Code_128\">Code 128</a>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Codablock-F_Example.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Codablock-F_Example.png/120px-Codablock-F_Example.png\" width=\"120\" height=\"71\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Codablock-F_Example.png/180px-Codablock-F_Example.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/Codablock-F_Example.png/240px-Codablock-F_Example.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>An example of a <i>stacked barcode</i>. Specifically a &quot;Codablock&quot; barcode.\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Better_Sample_PDF417.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Better_Sample_PDF417.png/120px-Better_Sample_PDF417.png\" width=\"120\" height=\"52\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Better_Sample_PDF417.png/180px-Better_Sample_PDF417.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/0/07/Better_Sample_PDF417.png/240px-Better_Sample_PDF417.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p><a href=\"https://en.wikipedia.org/wiki/PDF417\">PDF417</a> sample\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Lorem_Ipsum.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Lorem_Ipsum.png/120px-Lorem_Ipsum.png\" width=\"120\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Lorem_Ipsum.png/180px-Lorem_Ipsum.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Lorem_Ipsum.png/240px-Lorem_Ipsum.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p><a href=\"https://en.wikipedia.org/wiki/Lorem_ipsum\">Lorem ipsum</a> <a href=\"https://en.wikipedia.org/wiki/Boilerplate_text\">boilerplate text</a> as four segment <a href=\"https://en.wikipedia.org/wiki/Data_Matrix\">Data Matrix</a> 2D\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Azteccodeexample.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Azteccodeexample.svg/120px-Azteccodeexample.svg.png\" width=\"120\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Azteccodeexample.svg/180px-Azteccodeexample.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Azteccodeexample.svg/240px-Azteccodeexample.svg.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>&quot;This is an example Aztec symbol for Wikipedia&quot; encoded in <a href=\"https://en.wikipedia.org/wiki/Aztec_Code\">Aztec Code</a>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:EZcode.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/9/99/EZcode.png\" width=\"120\" height=\"120\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>Text &apos;EZcode&apos;\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:High_Capacity_Color_Barcode.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/High_Capacity_Color_Barcode.png/120px-High_Capacity_Color_Barcode.png\" width=\"120\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/High_Capacity_Color_Barcode.png/180px-High_Capacity_Color_Barcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/High_Capacity_Color_Barcode.png/240px-High_Capacity_Color_Barcode.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>High Capacity Color Barcode of the URL for Wikipedia&apos;s article on <a href=\"https://en.wikipedia.org/wiki/High_Capacity_Color_Barcode\">High Capacity Color Barcode</a>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Dataglyph511140.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Dataglyph511140.png/120px-Dataglyph511140.png\" width=\"120\" height=\"98\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Dataglyph511140.png/180px-Dataglyph511140.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Dataglyph511140.png/240px-Dataglyph511140.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>&quot;Wikipedia, The Free Encyclopedia&quot; in several languages encoded in <a href=\"https://en.wikipedia.org/w/index.php?title=DataGlyph&amp;action=edit&amp;redlink=1\" class=\"new\">DataGlyphs</a>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:35mm_film_audio_macro.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/35mm_film_audio_macro.jpg/120px-35mm_film_audio_macro.jpg\" width=\"120\" height=\"87\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/35mm_film_audio_macro.jpg/180px-35mm_film_audio_macro.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/35mm_film_audio_macro.jpg/240px-35mm_film_audio_macro.jpg 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>Two different 2D barcodes used in film: <a href=\"https://en.wikipedia.org/wiki/Dolby_Digital\">Dolby Digital</a> between the sprocket holes with the &quot;Double-D&quot; logo in the middle, and <a href=\"https://en.wikipedia.org/wiki/Sony_Dynamic_Digital_Sound\">Sony Dynamic Digital Sound</a> in the blue area to the left of the sprocket holes\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:WikiQRCode.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/WikiQRCode.png/120px-WikiQRCode.png\" width=\"120\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/ce/WikiQRCode.png/180px-WikiQRCode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/c/ce/WikiQRCode.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>The <a href=\"https://en.wikipedia.org/wiki/QR_Code\" class=\"mw-redirect\">QR Code</a> for the Wikipedia URL. &quot;Quick Response&quot;, the most popular 2D barcode. It is open in that the specification is disclosed and the patent is not exercised.<sup id=\"cite_ref-76\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-76\">[76]</a></sup>\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:MaxiCode.svg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/MaxiCode.svg/120px-MaxiCode.svg.png\" width=\"120\" height=\"115\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/MaxiCode.svg/180px-MaxiCode.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/MaxiCode.svg/240px-MaxiCode.svg.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p><a href=\"https://en.wikipedia.org/wiki/MaxiCode\">MaxiCode</a> example. This encodes the string &quot;Wikipedia, The Free Encyclopedia&quot;\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Shotcode.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Shotcode.png/120px-Shotcode.png\" width=\"120\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Shotcode.png/180px-Shotcode.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Shotcode.png/240px-Shotcode.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p><a href=\"https://en.wikipedia.org/wiki/ShotCode\">ShotCode</a> sample\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Twibright_Optar_Detail_Scanned.png\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Twibright_Optar_Detail_Scanned.png/120px-Twibright_Optar_Detail_Scanned.png\" width=\"120\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Twibright_Optar_Detail_Scanned.png/180px-Twibright_Optar_Detail_Scanned.png 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Twibright_Optar_Detail_Scanned.png/240px-Twibright_Optar_Detail_Scanned.png 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>detail of <a href=\"https://en.wikipedia.org/w/index.php?title=Twibright_Optar&amp;action=edit&amp;redlink=1\" class=\"new\">Twibright Optar</a> scan from laser printed paper, carrying 32 kbit/s Ogg Vorbis digital music (48 seconds per A4 page)\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:KarTrak_code.jpg\" class=\"image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/KarTrak_code.jpg/120px-KarTrak_code.jpg\" width=\"120\" height=\"90\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/KarTrak_code.jpg/180px-KarTrak_code.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/KarTrak_code.jpg/240px-KarTrak_code.jpg 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '<p>A <a href=\"https://en.wikipedia.org/wiki/KarTrak\">KarTrak</a> railroad <a href=\"https://en.wikipedia.org/wiki/Automatic_Equipment_Identification\" class=\"mw-redirect\">Automatic Equipment Identification</a> label on a caboose in Florida\\n' +\n    '</p>\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '</ul>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"In_popular_culture\">In popular culture</span></h2>\\n' +\n    '<p>In architecture, a building in <a href=\"https://en.wikipedia.org/wiki/Lingang_New_City\" class=\"mw-redirect\">Lingang New City</a> by German architects <a href=\"https://en.wikipedia.org/wiki/Gerkan,_Marg_and_Partners\">Gerkan, Marg and Partners</a> incorporates a barcode design,<sup id=\"cite_ref-77\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-77\">[77]</a></sup> as does a shopping mall called <a class=\"external text\" href=\"https://web.archive.org/web/20111026031424/http://www.marlen-dress.ru/img/schtrih-kod.jpg\"><i>Shtrikh-kod</i></a> (Russian for <i>barcode</i>) in Narodnaya ulitsa (&quot;People&apos;s Street&quot;) in the <a href=\"https://en.wikipedia.org/wiki/Administrative_divisions_of_Saint_Petersburg#Nevskiy_District\">Nevskiy district</a> of <a href=\"https://en.wikipedia.org/wiki/St._Petersburg\" class=\"mw-redirect\">St. Petersburg</a>, Russia.<sup id=\"cite_ref-78\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-78\">[78]</a></sup>\\n' +\n    '</p><p>In media, in 2011, the <a href=\"https://en.wikipedia.org/wiki/National_Film_Board_of_Canada\">National Film Board of Canada</a> and <a href=\"https://en.wikipedia.org/wiki/ARTE_France\" class=\"mw-redirect\">ARTE France</a> launched a web documentary entitled <i>Barcode.tv</i>, which allows users to view films about everyday objects by scanning the product&apos;s barcode with their <a href=\"https://en.wikipedia.org/wiki/IPhone\">iPhone</a> camera.<sup id=\"cite_ref-NFB_blog_79-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-NFB_blog-79\">[79]</a></sup><sup id=\"cite_ref-Reelscreen_80-0\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-Reelscreen-80\">[80]</a></sup>\\n' +\n    '</p><p>In <a href=\"https://en.wikipedia.org/wiki/Professional_wrestling\">professional wrestling</a>, the <a href=\"https://en.wikipedia.org/wiki/WWE\">WWE</a> stable <a href=\"https://en.wikipedia.org/wiki/D-Generation_X\">D-Generation X</a> incorporated a barcode into their entrance video, as well as on a T-shirt.<sup id=\"cite_ref-81\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-81\">[81]</a></sup><sup id=\"cite_ref-82\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-82\">[82]</a></sup>\\n' +\n    '</p><p>In the TV series <i><a href=\"https://en.wikipedia.org/wiki/Dark_Angel_(2000_TV_series)\" class=\"mw-redirect\">Dark Angel</a></i>, the protagonist and the other <a href=\"https://en.wikipedia.org/wiki/Transgenics\" class=\"mw-redirect\">transgenics</a> in the Manticore X-series have barcodes on the back of their necks.\\n' +\n    '</p><p>In video games, the protagonist of the <a href=\"https://en.wikipedia.org/wiki/Hitman_(franchise)\"><i>Hitman</i> video game series</a> has a barcode tattoo on the back of his head. Also, QR codes can be scanned for an extra mission on <i><a href=\"https://en.wikipedia.org/wiki/Watch_Dogs_(video_game)\">Watch Dogs</a></i>.\\n' +\n    '</p><p>In the films <i><a href=\"https://en.wikipedia.org/wiki/Back_to_the_Future_Part_II\">Back to the Future Part II</a></i> and <i><a href=\"https://en.wikipedia.org/wiki/The_Handmaid%27s_Tale_(film)\">The Handmaid&apos;s Tale</a></i>, cars in the future are depicted with barcode <a href=\"https://en.wikipedia.org/wiki/Licence_plate\" class=\"mw-redirect\">licence plates</a>.\\n' +\n    '</p><p>In the <i>Terminator</i> films, Skynet burns barcodes onto the inside surface of the wrists of captive humans (in a similar location to the <a href=\"https://en.wikipedia.org/wiki/Identification_of_inmates_in_German_concentration_camps\">WW2 concentration camp tattoos</a>) as a unique identifier.\\n' +\n    '</p><p>In music, <a href=\"https://en.wikipedia.org/wiki/Dave_Davies\">Dave Davies</a> of <a href=\"https://en.wikipedia.org/wiki/The_Kinks\">The Kinks</a> released a solo album in 1980, <i><a href=\"https://en.wikipedia.org/wiki/AFL1-3603\">AFL1-3603</a></i>, which featured a giant barcode on the front cover in place of the musician&apos;s head. The album&apos;s name was also the barcode number.\\n' +\n    '</p><p>The April 1978 issue of <i><a href=\"https://en.wikipedia.org/wiki/Mad_Magazine\" class=\"mw-redirect\">Mad Magazine</a></i> featured a giant barcode on the cover, with the blurb &quot;[Mad] Hopes this issue jams up every computer in the country...for forcing us to deface our covers with this yecchy UPC symbol from now on!&quot;\\n' +\n    '</p><p>The 2018 videogame <i><a href=\"https://en.wikipedia.org/wiki/Judgment_(video_game)\">Judgment</a></i> features <a href=\"https://en.wikipedia.org/wiki/QR_Code\" class=\"mw-redirect\">QR Codes</a> that protagonist Takayuki Yagami can photograph with his phone camera. These are mostly to unlock parts for Yagami&apos;s <a href=\"https://en.wikipedia.org/wiki/UAV\" class=\"mw-redirect\">Drone</a>.<sup id=\"cite_ref-83\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-83\">[83]</a></sup>\\n' +\n    '</p><p>Interactive Textbooks were first published by <i>Harcourt College Publishers to Expand Education Technology with Interactive Textbooks.</i><sup id=\"cite_ref-84\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-84\">[84]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Designed_barcodes\">Designed barcodes</span></h2>\\n' +\n    '<p>Some brands integrate custom designs into barcodes (while keeping them readable) on their consumer products.\\n' +\n    '</p>\\n' +\n    '<ul class=\"gallery mw-gallery-traditional centered\">\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Design_Barcode_Grasvodka_IMG_5574.JPG\" class=\"image\"><img alt=\"Design Barcode Grasvodka IMG 5574.JPG\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Design_Barcode_Grasvodka_IMG_5574.JPG/116px-Design_Barcode_Grasvodka_IMG_5574.JPG\" width=\"116\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Design_Barcode_Grasvodka_IMG_5574.JPG/175px-Design_Barcode_Grasvodka_IMG_5574.JPG 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Design_Barcode_Grasvodka_IMG_5574.JPG/233px-Design_Barcode_Grasvodka_IMG_5574.JPG 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Barcode_Tall_Horse1.jpg\" class=\"image\"><img alt=\"Barcode Tall Horse1.jpg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/Barcode_Tall_Horse1.jpg/120px-Barcode_Tall_Horse1.jpg\" width=\"120\" height=\"102\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/Barcode_Tall_Horse1.jpg/180px-Barcode_Tall_Horse1.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/Barcode_Tall_Horse1.jpg/240px-Barcode_Tall_Horse1.jpg 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg\" class=\"image\"><img alt=\"H&#xFC;hner-Bouillon K Designbarcode 4337185009907 IMG 8716.jpg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg/115px-H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg\" width=\"115\" height=\"120\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg/172px-H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/a/ad/H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg/230px-H%C3%BChner-Bouillon_K_Designbarcode_4337185009907_IMG_8716.jpg 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Sardinendose_K_Barcode_Art_valid_IMG11829.jpg\" class=\"image\"><img alt=\"Sardinendose K Barcode Art valid IMG11829.jpg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/98/Sardinendose_K_Barcode_Art_valid_IMG11829.jpg/120px-Sardinendose_K_Barcode_Art_valid_IMG11829.jpg\" width=\"120\" height=\"78\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/9/98/Sardinendose_K_Barcode_Art_valid_IMG11829.jpg/180px-Sardinendose_K_Barcode_Art_valid_IMG11829.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/9/98/Sardinendose_K_Barcode_Art_valid_IMG11829.jpg/240px-Sardinendose_K_Barcode_Art_valid_IMG11829.jpg 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '\\t\\t<li class=\"gallerybox\"><div>\\n' +\n    '\\t\\t\\t<div class=\"thumb\"><div><a href=\"https://en.wikipedia.org/wiki/File:Barcode_peanut.jpg\" class=\"image\"><img alt=\"Barcode peanut.jpg\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Barcode_peanut.jpg/120px-Barcode_peanut.jpg\" width=\"120\" height=\"108\" srcset=\"https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Barcode_peanut.jpg/180px-Barcode_peanut.jpg 1.5x, https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Barcode_peanut.jpg/240px-Barcode_peanut.jpg 2x\"></a></div></div>\\n' +\n    '\\t\\t\\t<div class=\"gallerytext\">\\n' +\n    '\\t\\t\\t</div>\\n' +\n    '\\t\\t</div></li>\\n' +\n    '</ul>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Hoaxes_about_barcodes\">Hoaxes about barcodes</span></h2>\\n' +\n    '<p>There was minor skepticism from <a href=\"https://en.wikipedia.org/wiki/Conspiracy_theory\">conspiracy theorists</a>, who considered barcodes to be an intrusive <a href=\"https://en.wikipedia.org/wiki/Surveillance\">surveillance</a> technology, and from some Christians, pioneered by a 1982 book <i>The New Money System 666</i> by Mary Stewart Relfe, who thought the codes hid the number <a href=\"https://en.wikipedia.org/wiki/666_(number)\">666</a>, representing the &quot;<a href=\"https://en.wikipedia.org/wiki/Number_of_the_beast\">Number of the Beast</a>&quot;.<sup id=\"cite_ref-85\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-85\">[85]</a></sup> <a href=\"https://en.wikipedia.org/wiki/Old_Believers\">Old Believers</a>, a separation of the <a href=\"https://en.wikipedia.org/wiki/Russian_Orthodox_Church\">Russian Orthodox Church</a>, believe barcodes are the stamp of the <a href=\"https://en.wikipedia.org/wiki/Antichrist\">Antichrist</a>.<sup id=\"cite_ref-86\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-86\">[86]</a></sup> Television host <a href=\"https://en.wikipedia.org/wiki/Phil_Donahue\">Phil Donahue</a> described barcodes as a &quot;corporate plot against consumers&quot;.<sup id=\"cite_ref-87\" class=\"reference\"><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_note-87\">[87]</a></sup>\\n' +\n    '</p>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"See_also\">See also</span></h2>\\n' +\n    '<ul><li><a href=\"https://en.wikipedia.org/wiki/Automated_identification_and_data_capture\" class=\"mw-redirect\">Automated identification and data capture</a> (AIDC)</li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Barcode_printer\">Barcode printer</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/European_Article_Numbering-Uniform_Code_Council\" class=\"mw-redirect\">European Article Numbering-Uniform Code Council</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Global_Trade_Item_Number\">Global Trade Item Number</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Identifier\">Identifier</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Inventory_control_system\" class=\"mw-redirect\">Inventory control system</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Object_hyperlinking\">Object hyperlinking</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/Semacode\">Semacode</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/w/index.php?title=SMS_barcode&amp;action=edit&amp;redlink=1\" class=\"new\">SMS barcode</a></li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/SPARQCode\">SPARQCode</a> (QR code)</li>\\n' +\n    '<li><a href=\"https://en.wikipedia.org/wiki/List_of_GS1_country_codes\">List of GS1 country codes</a></li></ul>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"References\">References</span></h2>\\n' +\n    '<div class=\"reflist reflist-columns references-column-width\">\\n' +\n    '<ol class=\"references\">\\n' +\n    '<li id=\"cite_note-patent-1\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-patent_1-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-patent_1-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><span class=\"citation patent\"><a class=\"external text\" href=\"https://worldwide.espacenet.com/textdoc?DB=EPODOC&amp;IDX=US2612994\">US patent 2612994</a></span><span class=\"Z3988\"><span>&#xA0;</span></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-2\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-2\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.stuffyoushouldknow.com/podcasts/how-barcodes-work.htm\">&quot;How Barcodes Work&quot;</a>. <i>Stuff You Should Know</i>. 4 June 2019<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 June</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Cranstone-3\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Cranstone_3-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Cranstone_3-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFCranstone\" class=\"citation web cs1\">Cranstone, Ian. <a class=\"external text\" href=\"http://www.nakina.net/other/aci/aci.html\">&quot;A guide to ACI (Automatic Car Identification)/KarTrak&quot;</a>. <i>Canadian Freight Cars A resource page for the Canadian Freight Car Enthusiast</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 May</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Keyes-4\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Keyes_4-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFKeyes2003\" class=\"citation web cs1\">Keyes, John (22 August 2003). <a class=\"external text\" href=\"https://web.archive.org/web/20140310153027/http://johnkeyes.com/2003/08/kartrak\">&quot;KarTrak&quot;</a>. <i>John Keyes Boston photoblogger. Images from Boston, New England, and beyond</i>. John Keyes. Archived from <a class=\"external text\" href=\"http://johnkeyes.com/2003/08/kartrak\">the original</a> on 10 March 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">26 May</span> 2013</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-RobertsNYT-5\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-RobertsNYT_5-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-RobertsNYT_5-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFRoberts2019\" class=\"citation news cs1\">Roberts, Sam (11 December 2019). <a class=\"external text\" href=\"https://www.nytimes.com/2019/12/11/technology/george-laurer-dead.html?searchResultPosition=1\">&quot;George Laurer, Who Developed the Bar Code, Is Dead at 94&quot;</a>. <i>New York Times</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">13 December</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-6\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-6\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFox2011\" class=\"citation news cs1\">Fox, Margalit (15 June 2011). <a class=\"external text\" href=\"https://www.nytimes.com/2011/06/16/business/16haberman.html?_r=1&amp;hp&amp;gwh=7657EAA31B3069C9E728CC93FD2695E8\">&quot;Alan Haberman, Who Ushered in the Bar Code, Dies at 81&quot;</a>. <i>New York Times</i>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-7\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-7\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFG._F.2017\" class=\"citation news cs1\">G. F. (2 November 2017). <a class=\"external text\" href=\"https://www.economist.com/blogs/economist-explains/2017/11/economist-explains-0\">&quot;Why QR codes are on the rise&quot;</a>. <i>The Economist</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">5 February</span> 2018</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-8\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-8\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFFishman2001\" class=\"citation news cs1\">Fishman, Charles (1 August 2001). <a class=\"external text\" href=\"https://web.archive.org/web/20100112043409/http://www.americanwaymag.com/so-woodland-bar-code-bernard-silver-drexel-university\">&quot;The Killer App &#x2013; Bar None&quot;</a>. <i>American Way</i>. Archived from <a class=\"external text\" href=\"http://www.americanwaymag.com/so-woodland-bar-code-bernard-silver-drexel-university\">the original</a> on 12 January 2010<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">19 April</span> 2010</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-story-9\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-story_9-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-story_9-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-story_9-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-story_9-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-story_9-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-story_9-5\"><sup><i><b>f</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFSeideman1993\" class=\"citation cs2\">Seideman, Tony (Spring 1993), <a class=\"external text\" href=\"https://web.archive.org/web/20161016084435/http://www.bar-code.com/upc/bar_code_history.php\">&quot;Barcodes Sweep the World&quot;</a>, <i>Wonders of Modern Technology</i>, archived from <a class=\"external text\" href=\"http://www.bar-code.com/upc/bar_code_history.php\">the original</a> on 16 October 2016</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-10\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-10\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDunn2015\" class=\"citation web cs1\">Dunn, Peter (20 October 2015). <a class=\"external text\" href=\"https://www.technologyreview.com/s/601032/david-collins-sm-59/\">&quot;David Collins, SM &apos;59: Making his mark on the world with bar codes&quot;</a>. <i>technologyreview.com</i>. MIT<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 December</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-11\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-11\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGraham-White1999\" class=\"citation journal cs1\">Graham-White, Sean (August 1999). &quot;Do You Know Where Your Boxcar Is?&quot;. <i>Trains</i>. <b>59</b> (8): 48&#x2013;53.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-12\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-12\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLaurer\" class=\"citation web cs1\"><a href=\"https://en.wikipedia.org/wiki/George_Laurer\">Laurer, George</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20080925105745/http://bellsouthpwp.net/l/a/laurergj/UPC/upc_work.html\">&quot;Development of the U.P.C. Symbol&quot;</a>. Archived from <a class=\"external text\" href=\"http://bellsouthpwp.net/l/a/laurergj/UPC/upc_work.html\">the original</a> on 25 September 2008.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Nelson-13\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Nelson_13-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFNelson1997\" class=\"citation book cs1\">Nelson, Benjamin (1997). <i>Punched Cards To Bar Codes: A 200-year journey</i>. Peterborough, N.H.: Helmers. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/9780911261127\"><bdi>9780911261127</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Varchaver-14\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Varchaver_14-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Varchaver_14-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFVarchaver2004\" class=\"citation journal cs1\">Varchaver, Nicholas (31 May 2004). <a class=\"external text\" href=\"https://money.cnn.com/magazines/fortune/fortune_archive/2004/05/31/370719/index.htm\">&quot;Scanning the Globe&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/Fortune_(magazine)\">Fortune</a></i>. <a class=\"external text\" href=\"https://web.archive.org/web/20061114065720/https://money.cnn.com/magazines/fortune/fortune_archive/2004/05/31/370719/index.htm\">Archived</a> from the original on 14 November 2006<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">27 November</span> 2006</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Selmeier-15\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Selmeier_15-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Selmeier_15-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFSelmeier2009\" class=\"citation book cs1\">Selmeier, Bill (2009). <i>Spreading the Barcode</i>. Lulu. pp.&#xA0;26, 214, 236, 238, 244, 245, 236, 238, 244, 245. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-0-578-02417-2\"><bdi>978-0-578-02417-2</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-16\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-16\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFRawsthorn2010\" class=\"citation news cs1\">Rawsthorn, Alice (23 February 2010). <a class=\"external text\" href=\"https://www.nytimes.com/2010/02/28/t-magazine/womens-fashion/28talk-rawsthorn.html?_r=0\">&quot;Scan Artists&quot;</a>. <i>New York Times</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">31 July</span> 2015</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-17\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-17\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.fullyloaded.com.au/news/logistics/1407/world-hails-barcode-on-important-birthday/\">&quot;World hails barcode on important birthday&quot;</a>. <i>ATN</i>. 1 July 2014.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-18\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-18\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.adams1.com/history.html\">&quot;A Short History of Bar Code&quot;</a>. <i>BarCode 1</i>. Adams Communications<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-19\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-19\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://iwatchsystems.com/technical/2011/05/02/barcode/\">&quot;Barcode&quot;</a>. <i>iWatch Systems</i>. 2 May 2011<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-20\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-20\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFOberfield\" class=\"citation web cs1\">Oberfield, Craig. <a class=\"external text\" href=\"http://www.qnotes.com/quix/\">&quot;QNotes Barcode System&quot;</a>. <i>US Patented #5296688</i>. Quick Notes Inc<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">15 December</span> 2012</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-21\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-21\">^</a></b></span> <span class=\"reference-text\">National Geographic, May 2010, page 30</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-22\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-22\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHecht2001\" class=\"citation journal cs1\">Hecht, David L. (March 2001). <a class=\"external text\" href=\"https://web.archive.org/web/20130603223227/http://turing.plymouth.edu/~wjt/HCI/ui2.pdf\">&quot;Printed Embedded Data Graphical User Interfaces&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i><a href=\"https://en.wikipedia.org/wiki/IEEE_Computer\" class=\"mw-redirect\">IEEE Computer</a></i>. Xerox Palo Alto Research Center. <b>34</b> (3): 47&#x2013;55. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1109%2F2.910893\">10.1109/2.910893</a>. Archived from <a class=\"external text\" href=\"http://turing.plymouth.edu/~wjt/HCI/ui2.pdf\">the original</a> <span class=\"cs1-format\">(PDF)</span> on 3 June 2013.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-23\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-23\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHowellKotay2000\" class=\"citation web cs1\">Howell, Jon; Kotay, Keith (March 2000). <a class=\"external text\" href=\"http://www.cs.dartmouth.edu/reports/abstracts/TR2000-364/\">&quot;Landmarks for absolute localization&quot;</a>. <i>Dartmouth Computer Science Technical Report TR2000-364</i>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-24\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-24\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.iata.org/\">&quot;IATA.org&quot;</a>. IATA.org. 21 November 2011<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-25\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-25\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation news cs1\"><a class=\"external text\" href=\"http://primepuzzle.com/waduzitdo/waduzitdo.html\">&quot;Paperbyte Bar Codes for Waduzitdo&quot;</a>. <i><a href=\"https://en.wikipedia.org/wiki/Byte_(magazine)\">Byte magazine</a></i>. September 1978. p.&#xA0;172.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-26\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-26\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://web.archive.org/web/20110714030851/http://europe.nokia.com/support/product-support/nokia-n80/phone-software/smartphone\">&quot;Nokia N80 Support&quot;</a>. <i>Nokia Europe</i>. Archived from <a class=\"external text\" href=\"http://europe.nokia.com/support/product-support/nokia-n80/phone-software/smartphone\">the original</a> on 14 July 2011.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-27\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-27\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://maemo.org/packages/view/mbarcode/\">&quot;package overview for mbarcode&quot;</a>. Maemo.org<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 July</span> 2010</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-28\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-28\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSargent2017\" class=\"citation web cs1\">Sargent, Mikah (24 September 2017). <a class=\"external text\" href=\"https://www.imore.com/how-use-qr-codes-ios-11\">&quot;How to use QR codes in iOS 11&quot;</a>. iMore<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 October</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-29\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-29\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.iphoneness.com/iphone-apps/5-best-barcode-iphone-applications/\">&quot;15+ Best Barcode Scanner iPhone Applications&quot;</a>. <i>iPhoneness</i>. 3 March 2017<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">1 October</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-30\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-30\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDavid2018\" class=\"citation cs2\">David, H (28 November 2018), <a class=\"external text\" href=\"http://www.labelingnews.com/2018/11/barcodes-validation-vs-verification-in-gs1/\">&quot;Barcodes &#x2013; Validation vs Verification in GS1&quot;</a>, <i>Labeling News</i><span class=\"reference-accessdate\">, retrieved <span class=\"nowrap\">6 June</span> 2020</span></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-31\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-31\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.bar-code.com/verifiers/LaymansGuidetoANSI.pdf\">&quot;Layman&apos;s Guide to ANSI, CEN, and ISO Barcode Print Quality Documents&quot;</a> <span class=\"cs1-format\">(PDF)</span>. Association for Automatic Identification and Data Capture Technologies (AIM). 2002<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">23 November</span> 2017</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-32\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-32\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFZieger2003\" class=\"citation journal cs1\">Zieger, Anne (October 2003). <a class=\"external text\" href=\"https://archive.today/20120708192857/http://findarticles.com/p/articles/mi_m0DIS/is_10_4/ai_109518393/\">&quot;Retailer chargebacks: is there an upside? Retailer compliance initiatives can lead to efficiency&quot;</a>. <i>Frontline Solutions</i>. Archived from <a class=\"external text\" href=\"http://findarticles.com/p/articles/mi_m0DIS/is_10_4/ai_109518393/\">the original</a> on 8 July 2012.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-:3-33\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-1\"><sup><i><b>b</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-2\"><sup><i><b>c</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-3\"><sup><i><b>d</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-4\"><sup><i><b>e</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-5\"><sup><i><b>f</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-6\"><sup><i><b>g</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-7\"><sup><i><b>h</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-8\"><sup><i><b>i</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-9\"><sup><i><b>j</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-10\"><sup><i><b>k</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:3_33-11\"><sup><i><b>l</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFCorp\" class=\"citation web cs1\">Corp, Express. <a class=\"external text\" href=\"https://www.expresscorp.com/Barcode-Glossary\">&quot;Barcode Glossary | Express&quot;</a>. <i>Express Corp</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">11 December</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-34\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-34\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBar_Code_Verification_Best_Practice_work_team2010\" class=\"citation journal cs1\">Bar Code Verification Best Practice work team (May 2010). <a class=\"external text\" href=\"http://www.gs1.org/docs/barcodes/GS1_DataMatrix_Introduction_and_technical_overview.pdf\">&quot;GS1 DataMatrix: An introduction and technical overview of the most advanced GS1 Application Identifiers compliant symbology&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>Global Standards 1</i>. <b>1</b> (17): 34&#x2013;36. <a class=\"external text\" href=\"https://web.archive.org/web/20110720135555/http://www.gs1.org/docs/barcodes/GS1_DataMatrix_Introduction_and_technical_overview.pdf\">Archived</a> <span class=\"cs1-format\">(PDF)</span> from the original on 20 July 2011<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 August</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-35\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-35\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGS1_Bar_Code_Verification_Best_Practice_work_team2009\" class=\"citation journal cs1\">GS1 Bar Code Verification Best Practice work team (May 2009). <a class=\"external text\" href=\"http://www.gs1.org/docs/barcodes/GS1_Bar_Code_Verification.pdf\">&quot;GS1 Bar Code Verification for Linear Symbols&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>Global Standards 1</i>. <b>4</b> (3): 23&#x2013;32<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">2 August</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-36\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-36\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGarner2019\" class=\"citation cs2\">Garner, J (2019), <a class=\"external text\" href=\"https://www.osti.gov/servlets/purl/1524857\"><i>Results of Data Matrix Barcode Testing for Field Applications</i></a>, Oak Ridge National Laboratory<span class=\"reference-accessdate\">, retrieved <span class=\"nowrap\">6 June</span> 2020</span></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-37\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-37\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.iso.org/iso/iso_technical_committee.html?commid=45332\">&quot;Technical committees &#x2013; JTC 1/SC 31 &#x2013; Automatic identification and data capture techniques&quot;</a>. ISO<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-38\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-38\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFHarmonAdams1989\" class=\"citation book cs1\">Harmon, Craig K.; Adams, Russ (1989). <i>Reading Between The Lines:An Introduction to Bar Code Technology</i>. Peterborough, NH: Helmers. p.&#xA0;13. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-911261-00-1\"><bdi>0-911261-00-1</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-39\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-39\">^</a></b></span> <span class=\"reference-text\"><a class=\"external text\" href=\"https://jeromeetienne.github.io/AR.js/three.js/examples/arcode.html#%7B%22urlQrCode%22%3A%22https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FBarcode%22%2C%22hideUiEnabled%22%3Afalse%7D\">&quot;AR Code Generator&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-40\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-40\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFGernatRaoMiddendorfDankowicz2018\" class=\"citation journal cs1\">Gernat, Tim; Rao, Vikyath D.; Middendorf, Martin; Dankowicz, Harry; Goldenfeld, Nigel; Robinson, Gene E. (13 February 2018). <a class=\"external text\" href=\"https://www.pnas.org/content/115/7/1433\">&quot;Automated monitoring of behavior reveals bursty interaction patterns and rapid spreading dynamics in honeybee social networks&quot;</a>. <i>Proceedings of the National Academy of Sciences</i>. <b>115</b> (7): 1433&#x2013;1438. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1073%2Fpnas.1713568115\">10.1073/pnas.1713568115</a>. <a href=\"https://en.wikipedia.org/wiki/ISSN_(identifier)\" class=\"mw-redirect\">ISSN</a>&#xA0;<a class=\"external text\" href=\"https://www.worldcat.org/issn/0027-8424\">0027-8424</a>. <a href=\"https://en.wikipedia.org/wiki/PMC_(identifier)\" class=\"mw-redirect\">PMC</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5816157\">5816157</a></span>. <a href=\"https://en.wikipedia.org/wiki/PMID_(identifier)\" class=\"mw-redirect\">PMID</a>&#xA0;<a class=\"external text\" href=\"https://pubmed.ncbi.nlm.nih.gov/29378954\">29378954</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-41\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-41\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFCombesMountcastleGravishCrall2015\" class=\"citation journal cs1\">Combes, Stacey A.; Mountcastle, Andrew M.; Gravish, Nick; Crall, James D. (2 September 2015). <a class=\"external text\" href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4558030\">&quot;BEEtag: A Low-Cost, Image-Based Tracking System for the Study of Animal Behavior and Locomotion&quot;</a>. <i>PLOS ONE</i>. <b>10</b> (9): e0136487. <a href=\"https://en.wikipedia.org/wiki/Bibcode_(identifier)\" class=\"mw-redirect\">Bibcode</a>:<a class=\"external text\" href=\"https://ui.adsabs.harvard.edu/abs/2015PLoSO..1036487C\">2015PLoSO..1036487C</a>. <a href=\"https://en.wikipedia.org/wiki/Doi_(identifier)\" class=\"mw-redirect\">doi</a>:<a class=\"external text\" href=\"https://doi.org/10.1371%2Fjournal.pone.0136487\">10.1371/journal.pone.0136487</a>. <a href=\"https://en.wikipedia.org/wiki/ISSN_(identifier)\" class=\"mw-redirect\">ISSN</a>&#xA0;<a class=\"external text\" href=\"https://www.worldcat.org/issn/1932-6203\">1932-6203</a>. <a href=\"https://en.wikipedia.org/wiki/PMC_(identifier)\" class=\"mw-redirect\">PMC</a>&#xA0;<span class=\"cs1-lock-free\"><a class=\"external text\" href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4558030\">4558030</a></span>. <a href=\"https://en.wikipedia.org/wiki/PMID_(identifier)\" class=\"mw-redirect\">PMID</a>&#xA0;<a class=\"external text\" href=\"https://pubmed.ncbi.nlm.nih.gov/26332211\">26332211</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-42\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-42\">^</a></b></span> <span class=\"reference-text\"><a class=\"external free\" href=\"https://github.com/piql/boxing\">https://github.com/piql/boxing</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-43\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-43\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAdams2009\" class=\"citation web cs1\">Adams, Russ (15 June 2009). <a class=\"external text\" href=\"http://www.adams1.com/stack.html\">&quot;2-Dimensional Bar Code Page&quot;</a>. <a class=\"external text\" href=\"https://web.archive.org/web/20110707082929/http://www.adams1.com/stack.html\">Archived</a> from the original on 7 July 2011<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">6 June</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-2-Dimensional_Bar_Code_Page-44\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-2-Dimensional_Bar_Code_Page_44-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-2-Dimensional_Bar_Code_Page_44-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.adams1.com/stack.html\">&quot;2-Dimensional Bar Code Page&quot;</a>. <i>www.adams1.com</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-45\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-45\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.gomaro.ch/ftproot/Code%2016k.pdf\">&quot;Code 16K Specs&quot;</a> <span class=\"cs1-format\">(PDF)</span>. <i>www.gomaro.ch</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-46\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-46\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.colorzip.com/\">&quot;Colorzip.com&quot;</a>. Colorzip.com<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-47\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-47\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://adverlab.blogspot.com/2006/01/barcodes-for-tv-commercials.html\">&quot;Barcodes for TV Commercials&quot;</a>. Adverlab. 31 January 2006<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 June</span> 2009</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-48\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-48\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://web.archive.org/web/20120829213507/http://www.colourcodetech.com/about.html\">&quot;About&quot;</a>. Colour Code Technologies. Archived from <a class=\"external text\" href=\"http://www.colourcodetech.com/about.html\">the original</a> on 29 August 2012<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">4 November</span> 2012</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-49\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-49\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://archive.today/20130221173001/http://www.colorccode.net/?q=faq\">&quot;Frequently Asked Questions&quot;</a>. ColorCCode. Archived from <a class=\"external text\" href=\"http://www.colorccode.net/?q=faq\">the original</a> on 21 February 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">4 November</span> 2012</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-cronto-50\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-cronto_50-0\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.cam.ac.uk/research/news/new-system-to-combat-online-banking-fraud\">&quot;New system to combat online banking fraud&quot;</a>. <a href=\"https://en.wikipedia.org/wiki/University_of_Cambridge\">University of Cambridge</a>. 18 April 2013<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">21 January</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-51\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-51\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation cs2\"><a class=\"external text\" href=\"https://www.onespan.com/products/transaction-signing/cronto\"><i>Cronto Visual Transaction Signing</i></a>, OneSpan<span class=\"reference-accessdate\">, retrieved <span class=\"nowrap\">6 December</span> 2019</span></cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-52\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-52\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation cs2\"><a class=\"external text\" href=\"https://web.archive.org/web/20080302032843/http://web.media.mit.edu/~enrico/research/research.php?projectTitle=d-touch\"><i>d-touch topological fiducial recognition</i></a>, MIT, archived from <a class=\"external text\" href=\"http://web.media.mit.edu/~enrico/research/research.php?projectTitle=d-touch\">the original</a> on 2 March 2008</cite><span class=\"Z3988\"></span>.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-53\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-53\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation cs2\"><a class=\"external text\" href=\"https://web.archive.org/web/20080621191310/http://web.media.mit.edu/~enrico/research/research.php?projectTitle=Sleight%20of%20Hands\"><i>d-touch markers are applied to deformable gloves</i></a>, MIT, archived from <a class=\"external text\" href=\"http://web.media.mit.edu/~enrico/research/research.php?projectTitle=Sleight%20of%20Hands\">the original</a> on 21 June 2008</cite><span class=\"Z3988\"></span>.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-54\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-54\">^</a></b></span> <span class=\"reference-text\">See <a class=\"external text\" href=\"http://www.xerox.com/Static_HTML/xsis/dataglph.htm\">Xerox.com</a> for details.</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-55\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-55\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.microglyphs.com/english/html/dataglyphs.shtml\">&quot;DataGlyphs: Embedding Digital Data&quot;</a>. Microglyphs. 3 May 2006<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-56\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-56\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.tauzero.com/Rob_Tow/DataGlyph.html\">&quot;<span class=\"cs1-kern-left\">&quot;</span>DataGlyph&quot; Embedded Digital Data&quot;</a>. Tauzero<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-57\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-57\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.xerox.com/Static_HTML/xsis/dataglph.htm\">&quot;DataGlyphs&quot;</a>. Xerox<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-58\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-58\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.digimarc.com/docs/default-source/solution-briefs/barcodebrief.pdf?sfvrsn=4\">&quot;Better Barcodes, Better Business&quot;</a> <span class=\"cs1-format\">(PDF)</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-59\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-59\">^</a></b></span> <span class=\"reference-text\"><a class=\"external text\" href=\"https://www.barcode.ro/tutorials/barcodes/dotcode-a.html\">Dot Code A</a> at barcode.ro</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-60\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-60\">^</a></b></span> <span class=\"reference-text\"><a class=\"external text\" href=\"http://www.adams1.com/patents/US4745269.pdf\">Dot Code A Patent</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-61\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-61\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.prnewswire.com/news-releases/gs1-germany-and-digimarc-announce-collaboration-to-bring-dwcode-to-the-german-market-300331518.html\">&quot;GS1 Germany and Digimarc Announce Collaboration to Bring DWCode to the German Market&quot;</a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-62\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-62\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.scanbuy.com/\">&quot;Scanbuy&quot;</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Steeman-63\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Steeman_63-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Steeman_63-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFSteeman\" class=\"citation web cs1\">Steeman, Jeroen. <a class=\"external text\" href=\"https://web.archive.org/web/20140109233243/http://blog.qr4.nl/Online-QR-Code_Decoder.aspx\">&quot;Online QR Code Decoder&quot;</a>. Archived from <a class=\"external text\" href=\"http://blog.qr4.nl/Online-QR-Code_Decoder.aspx\">the original</a> on 9 January 2014<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">9 January</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-64\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-64\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://web.archive.org/web/20081103113810/http://www.adams1.com/pub/russadam/stack.html\">&quot;BarCode-1 2-Dimensional Bar Code Page&quot;</a>. Adams. Archived from <a class=\"external text\" href=\"http://www.adams1.com/pub/russadam/stack.html\">the original</a> on 3 November 2008<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 June</span> 2009</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-65\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-65\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://grs.weebly.com/2d-barcodes.html\">&quot;Global Research Solutions &#x2013; 2D Barcodes&quot;</a>. <i>grs.weebly.com</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-:0-66\"><span class=\"mw-cite-backlink\">^ <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:0_66-0\"><sup><i><b>a</b></i></sup></a> <a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-:0_66-1\"><sup><i><b>b</b></i></sup></a></span> <span class=\"reference-text\"><cite id=\"CITEREFKatoTanChai2010\" class=\"citation book cs1\">Kato, Hiroko; Tan, Keng T.; Chai, Douglas (8 April 2010). <a class=\"external text\" href=\"https://books.google.com/books?id=gHhPiMwiUX8C&amp;q=trillcode&amp;pg=PA73\"><i>Barcodes for Mobile Devices</i></a>. Cambridge University Press. <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/9781139487511\"><bdi>9781139487511</bdi></a>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-67\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-67\">^</a></b></span> <span class=\"reference-text\">\\n' +\n    '<a class=\"external text\" href=\"https://patents.justia.com/patent/9270846\">&quot;US Patent 9270846: Content encoded luminosity modulation&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-68\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-68\">^</a></b></span> <span class=\"reference-text\">\\n' +\n    '<a class=\"external text\" href=\"https://patents.justia.com/patent/8180163\">&quot;US Patent 8180163: Encoder and decoder and methods of encoding and decoding sequence information with inserted monitor flags&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-69\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-69\">^</a></b></span> <span class=\"reference-text\">\\n' +\n    '<a class=\"external text\" href=\"http://personal.ee.surrey.ac.uk/Personal/J.Collomosse/pubs/Collomosse-HOTm-2008.pdf\">&quot;Screen Codes: Visual Hyperlinks for Displays&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-70\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-70\">^</a></b></span> <span class=\"reference-text\">\\n' +\n    '<a class=\"external text\" href=\"https://www.theverge.com/2015/7/1/8861131/snapchat-update-2015-tap-to-play-story\">&quot;Snapchat is changing the way you watch snaps and add friends&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-71\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-71\">^</a></b></span> <span class=\"reference-text\">\\n' +\n    '<a class=\"external text\" href=\"https://techcrunch.com/2015/01/28/snaptags/\">&quot;Snapchat Lets You Add People Via QR Snaptags Thanks To Secret Scan.me Acquisition&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-72\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-72\">^</a></b></span> <span class=\"reference-text\">\\n' +\n    '<a class=\"external text\" href=\"https://techcrunch.com/2015/05/04/snapcode/\">&quot;How Snapchat Made QR Codes Cool Again&quot;</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-73\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-73\">^</a></b></span> <span class=\"reference-text\"><span class=\"citation patent\" id=\"CITEREFChanGB1998\"><a class=\"external text\" href=\"http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&amp;Sect2=HITOFF&amp;p=1&amp;u=/netahtml/PTO/search-bool.html&amp;r=1&amp;f=G&amp;l=50&amp;co1=AND&amp;d=PTXT&amp;s1=5825015.PN.&amp;OS=PN/5825015&amp;RS=PN/5825015\">5825015</a>, Chan, John Paul &amp; GB, &quot;United States Patent: 5825015 &#x2013; Machine readable binary codes&quot;, issued 20 October 1998</span><span class=\"Z3988\"><span>&#xA0;</span></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-74\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-74\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://pdfpiw.uspto.gov/.piw?Docid=05825015&amp;homeurl=http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO2%2526Sect2=HITOFF%2526p=1%2526u=%25252Fnetahtml%25252FPTO%25252Fsearch-bool.html%2526r=1%2526f=G%2526l=50%2526co1=AND%2526d=PTXT%2526s1=5825015.PN.%2526OS=PN/5825015%2526RS=PN/5825015&amp;PageNum=&amp;Rtype=&amp;SectionNum=&amp;idkey=NONE&amp;Input=View+first+page\">&quot;US Patent 5825015&quot;</a>. <i>pdfpiw.uspto.gov</i>. 20 October 1998<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-75\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-75\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.barcoding.com/blog/trillcode-barcode/\">&quot;Trillcode Barcode&quot;</a>. <i>Barcoding, Inc</i>. 17 February 2009<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 January</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-76\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-76\">^</a></b></span> <span class=\"reference-text\"><a class=\"external text\" href=\"http://www.denso-wave.com/qrcode/qrstandard-e.html\">(&#x682A;)&#x30C7;&#x30F3;&#x30BD;&#x30FC;&#x30A6;&#x30A7;&#x30FC;&#x30D6;</a>, denso-wave.com <span class=\"languageicon\">(in Japanese)</span> Copyright</span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-77\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-77\">^</a></b></span> <span class=\"reference-text\"><a class=\"external text\" href=\"http://www.gmp-architekten.de/en/projects/barcode-halls-standard-facades-for-manufacturing-buildings.html\">Barcode Halls &#x2013; gmp</a> <a class=\"external text\" href=\"https://web.archive.org/web/20111018072059/http://www.gmp-architekten.de/en/projects/barcode-halls-standard-facades-for-manufacturing-buildings.html\">Archived</a> 18 October 2011 at the <a href=\"https://en.wikipedia.org/wiki/Wayback_Machine\">Wayback Machine</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-78\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-78\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://peterburg2.ru/restplaces/2530.html\">&quot;image&quot;</a>. Peterburg2.ru<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">28 November</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-NFB_blog-79\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-NFB_blog_79-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFLavigne2011\" class=\"citation web cs1\">Lavigne, Anne-Marie (5 October 2011). <a class=\"external text\" href=\"http://blog.nfb.ca/2011/10/05/introducing-barcode/\">&quot;Introducing Barcode.tv, a new interactive doc about the objects that surround us&quot;</a>. <i>NFB Blog</i>. <a href=\"https://en.wikipedia.org/wiki/National_Film_Board_of_Canada\">National Film Board of Canada</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 October</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-Reelscreen-80\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-Reelscreen_80-0\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFAnderson2011\" class=\"citation news cs1\">Anderson, Kelly (6 October 2011). <a class=\"external text\" href=\"http://realscreen.com/2011/10/06/nfb-and-arte-france-launch-bar-code/\">&quot;NFB, ARTE France launch &apos;Bar Code<span class=\"cs1-kern-right\">&apos;</span>&quot;</a>. <i>Reelscreen</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">7 October</span> 2011</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-81\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-81\">^</a></b></span> <span class=\"reference-text\"><a class=\"external autonumber\" href=\"http://www.attitudetees.com/items/dxbarcode.html\">[1]</a> <a class=\"external text\" href=\"https://web.archive.org/web/20150316205717/http://www.attitudetees.com/items/dxbarcode.html\">Archived</a> 16 March 2015 at the <a href=\"https://en.wikipedia.org/wiki/Wayback_Machine\">Wayback Machine</a></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-82\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-82\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://www.youtube.com/watch?v=BkvplmOtmX4\">&quot;Dx theme song 2009&#x2013;2010&quot;</a>. YouTube. 19 December 2009<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">10 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-83\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-83\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFDiego_Agruello2019\" class=\"citation web cs1\">Diego Agruello (27 June 2019). <a class=\"external text\" href=\"https://www.eurogamer.net/articles/2019-06-26-judgment-qr-codes-drone-parts-6032\">&quot;Judgment QR code locations to upgrade Drone Parts explained &#x2022; Eurogamer.net&quot;</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">3 August</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-84\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-84\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"https://cuecat.org/\">&quot;CueCat History&quot;</a>. <i>CueCat History</i><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">12 November</span> 2019</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-85\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-85\">^</a></b></span> <span class=\"reference-text\"><cite class=\"citation web cs1\"><a class=\"external text\" href=\"http://www.av1611.org/666/barcode.html\">&quot;What about barcodes and 666: The Mark of the Beast?&quot;</a>. Av1611.org. 1999<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">14 March</span> 2014</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-86\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-86\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFSerafino2018\" class=\"citation web cs1\">Serafino, Jay (26 July 2018). <a class=\"external text\" href=\"https://www.mentalfloss.com/article/551659/karp-lykov-russian-family-secluded-from-civilization-40-years\">&quot;The Russian Family That Cut Itself Off From Civilization for More Than 40 Years&quot;</a>. <a href=\"https://en.wikipedia.org/wiki/Mental_Floss\">Mental Floss</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">6 May</span> 2020</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '<li id=\"cite_note-87\"><span class=\"mw-cite-backlink\"><b><a href=\"https://en.wikipedia.org/wiki/2D_barcode#cite_ref-87\">^</a></b></span> <span class=\"reference-text\"><cite id=\"CITEREFBishop2004\" class=\"citation web cs1\">Bishop, Tricia (5 July 2004). <a class=\"external text\" href=\"https://web.archive.org/web/20040823004929/http://www.sfgate.com/cgi-bin/article.cgi?file=%2Fchronicle%2Farchive%2F2004%2F07%2F05%2FBUG6Q7G4AJ1.DTL&amp;type=business\">&quot;UPC bar code has been in use 30 years&quot;</a>. SFgate.com. Archived from <a class=\"external text\" href=\"http://www.sfgate.com/cgi-bin/article.cgi?file=/chronicle/archive/2004/07/05/BUG6Q7G4AJ1.DTL&amp;type=business\">the original</a> on 23 August 2004<span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">22 December</span> 2009</span>.</cite><span class=\"Z3988\"></span></span>\\n' +\n    '</li>\\n' +\n    '</ol></div>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"Further_reading\">Further reading</span></h2>\\n' +\n    '<div class=\"refbegin\">\\n' +\n    '<ul><li><i>Automating Management Information Systems: Barcode Engineering and Implementation</i> &#x2013; Harry E. Burke, Thomson Learning, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-442-20712-3\">0-442-20712-3</a></li>\\n' +\n    '<li><i>Automating Management Information Systems: Principles of Barcode Applications</i> &#x2013; Harry E. Burke, Thomson Learning, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-442-20667-4\">0-442-20667-4</a></li>\\n' +\n    '<li><i>The Bar Code Book</i> &#x2013; Roger C. Palmer, Helmers Publishing, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-911261-09-5\">0-911261-09-5</a>, 386 pages</li>\\n' +\n    '<li><i>The Bar Code Manual</i> &#x2013; Eugene F. Brighan, Thompson Learning, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-03-016173-8\">0-03-016173-8</a></li>\\n' +\n    '<li><i>Handbook of Bar Coding Systems</i> &#x2013; Harry E. Burke, Van Nostrand Reinhold Company, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/978-0-442-21430-2\">978-0-442-21430-2</a>, 219 pages</li>\\n' +\n    '<li><i>Information Technology for Retail:Automatic Identification &amp; Data Capture Systems</i> &#x2013; Girdhar Joshi, <a href=\"https://en.wikipedia.org/wiki/Oxford_University_Press\">Oxford University Press</a>, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-19-569796-0\">0-19-569796-0</a>, 416 pages</li>\\n' +\n    '<li><i>Lines of Communication</i> &#x2013; Craig K. Harmon, Helmers Publishing, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-911261-07-9\">0-911261-07-9</a>, 425 pages</li>\\n' +\n    '<li><i>Punched Cards to Bar Codes</i> &#x2013; Benjamin Nelson, Helmers Publishing, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-911261-12-5\">0-911261-12-5</a>, 434 pages</li>\\n' +\n    '<li><i>Revolution at the Checkout Counter: The Explosion of the Bar Code</i> &#x2013; Stephen A. Brown, <a href=\"https://en.wikipedia.org/wiki/Harvard_University_Press\">Harvard University Press</a>, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-674-76720-9\">0-674-76720-9</a></li>\\n' +\n    '<li><i>Reading Between The Lines</i> &#x2013; Craig K. Harmon and Russ Adams, Helmers Publishing, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-911261-00-1\">0-911261-00-1</a>, 297 pages</li>\\n' +\n    '<li><i>The Black and White Solution: Bar Code and the IBM PC</i> &#x2013; Russ Adams and Joyce Lane, Helmers Publishing, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-911261-01-X\">0-911261-01-X</a>, 169 pages</li>\\n' +\n    '<li><i>Sourcebook of Automatic Identification and Data Collection</i> &#x2013; Russ Adams, Van Nostrand Reinhold, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0-442-31850-2\">0-442-31850-2</a>, 298 pages</li>\\n' +\n    '<li><i>Inside Out: The Wonders of Modern Technology</i> &#x2013; Carol J. Amato, Smithmark Pub, <a href=\"https://en.wikipedia.org/wiki/ISBN_(identifier)\" class=\"mw-redirect\">ISBN</a>&#xA0;<a href=\"https://en.wikipedia.org/wiki/Special:BookSources/0831746572\">0831746572</a>, 1993</li></ul>\\n' +\n    '</div>\\n' +\n    '<h2><span class=\"mw-headline\" id=\"External_links\">External links</span></h2>\\n' +\n    '<table class=\"mbox-small plainlinks sistersitebox\">\\n' +\n    '<tbody><tr>\\n' +\n    '<td class=\"mbox-image\"><img alt src=\"https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/30px-Commons-logo.svg.png\" width=\"30\" height=\"40\" class=\"noviewer\" srcset=\"https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/45px-Commons-logo.svg.png 1.5x, https://upload.wikimedia.org/wikipedia/en/thumb/4/4a/Commons-logo.svg/59px-Commons-logo.svg.png 2x\"></td>\\n' +\n    '<td class=\"mbox-text plainlist\">Wikimedia Commons has media related to <span><a href=\"https://commons.wikimedia.org/wiki/Category:Barcode\" class=\"extiw\">Barcode</a></span>.</td></tr>\\n' +\n    '</tbody></table>\\n' +\n    '<ul><li><a class=\"external text\" href=\"https://curlie.org/Computers/Data_Formats/Barcodes/\">Barcode</a> at <a href=\"https://en.wikipedia.org/wiki/Curlie\" class=\"mw-redirect\">Curlie</a></li>\\n' +\n    '<li><a class=\"external text\" href=\"https://web.archive.org/web/20140705023911/http://www.maxatec-europe.com/support/resources/barcoding-glossary-of-terms/\">Barcode Glossary of Terms</a></li>\\n' +\n    '<li><a class=\"external text\" href=\"https://www.dynamsoft.com/blog/insights/the-comprehensive-guide-to-1d-and-2d-barcodes/\">Pros and cons and relative popularity of different 1D and 2D barcode codes.</a></li></ul>\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '\\n' +\n    '</div>\\n' +\n    '<div class=\"printfooter\">Retrieved from &quot;<a href=\"https://en.wikipedia.org/w/index.php?title=Barcode&amp;oldid=1025200225#Matrix_(2D)_barcodes\">https://en.wikipedia.org/w/index.php?title=Barcode&amp;oldid=1025200225#Matrix_(2D)_barcodes</a>&quot;</div></div></div>"
  },
  {
    "path": "aquila/txt_transform/test.py",
    "content": "import requests\nimport json\n\ndef process_html (html, url):\n    payload = {\n        \"html\": html,\n        \"url\": url\n    }\n\n    headers = {\n    'Content-Type': 'application/json'\n    }\n\n    # conn.request(\"POST\", \"localhost:5009/process\", json.dumps(payload), headers)\n    response = requests.request(\"POST\", \"http://localhost:5009/process\", headers=headers, data=json.dumps(payload))\n    # res = conn.getresponse()\n    # data = response.text()\n\n    if response.status_code == 200:\n        return response.json()\n    else:\n        return None\n\ndef trim_content (html):\n    payload = {\n        \"html\": html\n    }\n\n    headers = {\n    'Content-Type': 'application/json'\n    }\n\n    # conn.request(\"POST\", \"localhost:5009/process\", json.dumps(payload), headers)\n    response = requests.request(\"POST\", \"http://localhost:5008/process\", headers=headers, data=json.dumps(payload))\n    # res = conn.getresponse()\n    # data = response.text()\n\n    if response.status_code == 200:\n        return response.json()\n    else:\n        return None\n\nif __name__ == \"__main__\":\n    readablity = process_html(\"<html><h1>Bitcoin</h1><p>Bitcoin is invented by satoshi nakomoto</p><br/><p>it is powered by <a href='google.com'>mining</a></p></html>\", \"https://google.com\")\n    print(readablity)\n    content_lines = trim_content(readablity[\"data\"][\"content\"])\n    if content_lines[\"success\"] == True:\n        print(content_lines[\"result\"])"
  },
  {
    "path": "aquila/view/.dockerignore",
    "content": "node_modules\n.env*\n.next"
  },
  {
    "path": "aquila/view/.eslintrc.json",
    "content": "{\n  \"extends\": \"next/core-web-vitals\"\n}\n"
  },
  {
    "path": "aquila/view/@types/next-auth.d.ts",
    "content": "import { DefaultSession } from \"next-auth\";\n\ndeclare module \"next-auth\" {\n    interface User {\n        customerId: string;\n        firstName: string;\n        lastName: string;\n        createdAt: string;\n        accountStatus: string;\n        token: string;\n    }\n\n    interface Session {\n       user: {\n            customerId: string;\n            firstName: string;\n            lastName: string;\n            createdAt: string;\n            accountStatus: string;\n            token: string;\n       } & DefaultSession \n    } \n}\n\ndeclare module \"next-auth/jwt\" {\n    interface JWT {\n        customerId: string;\n        firstName: string;\n        lastName: string;\n        createdAt: string;\n        accountStatus: string;\n        token: string;\n    }\n}"
  },
  {
    "path": "aquila/view/Dockerfile",
    "content": "FROM node:16-alpine as builder\n\nARG NEXTAUTH_URL\nARG NEXTAUTH_SECRET\nARG NEXT_PUBLIC_AQUILA_API_URL\nARG NEXT_PUBLIC_BASE_URL\nARG NODE_ENV=production\n\nWORKDIR /app\n\nCOPY . .\n\nENV NEXTAUTH_URL=$NEXTAUTH_URL\nENV NEXTAUTH_SECRET=$NEXTAUTH_SECRET\nENV NEXT_PUBLIC_AQUILA_API_URL=$NEXT_PUBLIC_AQUILA_API_URL\nENV NEXT_PUBLIC_BASE_URL=$NEXT_PUBLIC_BASE_URL\n\nRUN yarn --frozen-lockfile\n\nRUN NODE_ENV=${NODE_ENV} yarn build\n\n\nFROM node:16-alpine\n\nWORKDIR /app\n\nCOPY --from=builder /app/next.config.js ./\nCOPY --from=builder /app/.next/standalone ./\nCOPY --from=builder /app/.next/static ./.next/static\n\nENV NEXT_TELEMETRY_DISABLED 1\n\nEXPOSE 3000\n\nCMD [\"node\", \"server.js\"]"
  },
  {
    "path": "aquila/view/README.md",
    "content": "# Aquila-Network-UI\n\n\n# ⚠️ Server and other Credentials are in workflow file.\nNever Make this Repo Public\n\n## Getting Started\n\nFirst, run the development server:\n\n```bash\nnpm run dev\n# or\nyarn dev\n```\n\n## Docker Deploy\n\n```bash\ndocker build  --build-arg NEXTAUTH_URL=http://localhost:3000 --build-arg NEXTAUTH_SECRET=secret --build-arg NEXT_PUBLIC_AQUILA_API_URL=https://aquila.api/url --build-arg NEXT_PUBLIC_BASE_URL=http://localhost:3000 -t aquila-network/aquila-network-ui .\n```\n"
  },
  {
    "path": "aquila/view/components/hoc/InitComponent.tsx",
    "content": "import { signOut, useSession, getSession } from \"next-auth/react\";\nimport { FC, useEffect } from \"react\";\nimport { useAppDispatch } from \"../../store\";\nimport { signIn, signOut as signOutAction } from \"../../store/slices/auth\";\n\ninterface InitCompoentProps {\n    children: React.ReactNode;\n}\n\nconst InitComponent: FC<InitCompoentProps> = (props) => {\n    const { status, data} = useSession();\n    const dispatch = useAppDispatch();\n\n    useEffect(() => {\n        if(status === 'authenticated') {\n            dispatch(signIn({ \n                token: data.user.token,\n                accountStatus: data.user.accountStatus,\n                customer: {\n                    customerId: data.user.customerId,\n                    firstName: data.user.firstName,\n                    lastName: data.user.lastName,\n                    createdAt: data.user.createdAt\n                }\n            })) \n        }\n        if(status === 'unauthenticated') {\n            dispatch(signOutAction()) \n        }\n    }, [status, dispatch, data])\n    return (\n        <>\n        {props.children}\n        </>\n    )\n}\n\nexport default InitComponent;"
  },
  {
    "path": "aquila/view/components/layout/base/baseLayout.tsx",
    "content": "import { FC } from 'react';\n\nimport { ProgressLoaderProvider } from '../../ui/progressLoader/ProgressLoader';\n\n\ninterface BaseLayoutProps {\n    children: React.ReactNode;\n}\n\nconst BaseLayout: FC<BaseLayoutProps> = (props) => {\n    return (\n        <>\n            <ProgressLoaderProvider>\n                {props.children}\n            </ProgressLoaderProvider>\n        </>\n    )\n}\n\nexport default BaseLayout;"
  },
  {
    "path": "aquila/view/components/layout/boxCenter/BoxCenterLayout.module.scss",
    "content": ".box-center-layout {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100vh;\n\n\t&__box {\n\t\tbackground: #fff;\n\t\twidth: 350px;\n\t\tpadding: 20px;\n\t\tborder-radius: 3px;\n\t\tbox-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;\n\t}\n\n\t&__box-header {\n\t\tdisplay: flex;\n\t\tjustify-content: center;\n\t}\n\n\t&__box-header-logo {\n\t\tcursor: pointer;\n\t\twidth: 80px;\n\t}\n\n}\n"
  },
  {
    "path": "aquila/view/components/layout/boxCenter/BoxCenterLayout.tsx",
    "content": "import Img from 'next/image';\nimport Link from 'next/link';\n\nimport Logo from '../../../public/img/logo.png';\nimport BaseLayout from '../base/baseLayout';\nimport classes from './BoxCenterLayout.module.scss';\n\nconst BoxCenterLayout = (props: any) => {\n\treturn(\n\t\t<BaseLayout>\n\t\t\t<div className={classes[\"box-center-layout\"]}>\n\t\t\t\t<div className={classes[\"box-center-layout__box\"]}>\n\t\t\t\t\t<div className={classes[\"box-center-layout__box-header\"]}>\n\t\t\t\t\t\t<div className={classes[\"box-center-layout__box-header-logo\"]}>\n\t\t\t\t\t\t\t<Link href=\"/\">\n\t\t\t\t\t\t\t\t<a>\n\t\t\t\t\t\t\t\t\t<Img src={Logo} />\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className={classes[\"box-center-layout__box-body\"]}>\n\t\t\t\t\t\t{props.children}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</BaseLayout>\n\t)\n}\n\nexport default BoxCenterLayout;"
  },
  {
    "path": "aquila/view/components/layout/childLayout/settings/Header.module.scss",
    "content": ".header {\n    display: flex;\n    gap: 15px;\n    align-items: center;\n    padding: 10px 0px;\n\n    &__info {\n        color: #202A38;\n    }\n    \n    &__info-title {\n        margin: 0px;\n        font-weight: 500;\n    }\n\n    &__info-desc {\n        margin: 0px;\n        font-size: 14px;\n        color: #415572;\n    }\n\n}"
  },
  {
    "path": "aquila/view/components/layout/childLayout/settings/Header.tsx",
    "content": "import Avatar from 'boring-avatars';\nimport { FC } from 'react';\nimport { AppState } from '../../../../store';\n\nimport classes from './Header.module.scss';\n\ninterface HeaderProps {\n    authState: AppState[\"auth\"];\n}\n\nconst Header: FC<HeaderProps> = (props) => {\n    const name = `${props.authState.customer?.firstName} ${props.authState.customer?.lastName}`;\n    return (\n        <header className={classes.header}>\n            <div className={classes.header__avatar}>\n                <Avatar variant='beam' size={45} name={name} />\n            </div>\n            <div className={classes.header__info}>\n                <h3 className={classes[\"header__info-title\"]}>{name}</h3>\n                <p className={classes[\"header__info-desc\"]}>Your account</p>\n            </div>\n        </header>\n    );\n}\n\nexport default Header;"
  },
  {
    "path": "aquila/view/components/layout/childLayout/settings/SettingsLayout.module.scss",
    "content": ".settings {\n    width: 900px;\n    margin: auto;\n    margin-top: 20px;\n\n    &__header {\n    }\n\n    &__body {\n        display: flex;\n        margin-top: 20px;\n    }\n\n    &__sidebar {\n        width: 250px;\n    }\n\n    &__content {\n        width: 100%;\n    }\n}"
  },
  {
    "path": "aquila/view/components/layout/childLayout/settings/SettingsLayout.tsx",
    "content": "import { FC } from \"react\";\nimport { AppState } from \"../../../../store\";\nimport MainLayout from \"../../main/MainLayout\";\nimport Header from \"./Header\";\n\nimport classes from './SettingsLayout.module.scss';\nimport Sidebar from \"./Sidebar\";\n\ninterface SettingsLayoutProps {\n    children: React.ReactNode;\n    authState: AppState[\"auth\"];\n}\n\nconst SettingsLayout: FC<SettingsLayoutProps> = (props) => {\n    return (\n        <MainLayout>\n            <section className={classes.settings}>\n                <section className={classes.settings__header}>\n                    <Header authState={props.authState}/>\n                </section>\n                <section className={classes.settings__body}>\n                    <aside className={classes.settings__sidebar}>\n                        <Sidebar />\n                    </aside>\n                    <main className={classes.settings__content}>\n                        {props.children}\n                    </main>\n                </section>\n            </section>\n        </MainLayout>\n    );\n}\n\nexport default SettingsLayout;"
  },
  {
    "path": "aquila/view/components/layout/childLayout/settings/Sidebar.module.scss",
    "content": ".sidebar {\n    list-style: none;\n    margin: 0px;\n    padding: 0px;\n\n    &__item {\n        padding: 10px 5px;\n    }\n\n    &__item-link {\n        font-size: 16px;\n        text-decoration: none;\n        color: #202A38;\n        transition: all .3s;\n    }\n\n\n    &__item-link:hover {\n        color: #0FBD86;\n    }\n}"
  },
  {
    "path": "aquila/view/components/layout/childLayout/settings/Sidebar.tsx",
    "content": "import Link from \"next/link\";\n\nimport classes from \"./Sidebar.module.scss\"; \n\nconst Sidebar = () => {\n    return (\n        <ul className={classes.sidebar}>\n            <li className={classes.sidebar__item}>\n                <Link href=\"/account/edit-profile\">\n                    <a className={classes[\"sidebar__item-link\"]}>Edit Profile</a>\n                </Link>\n            </li>\n            {/* <li className={classes.sidebar__item}>\n                <Link href=\"/\">\n                    <a className={classes[\"sidebar__item-link\"]}>General</a>\n                </Link>\n            </li> */}\n        </ul>\n    )\n}\n\nexport default Sidebar;"
  },
  {
    "path": "aquila/view/components/layout/main/AddLink.module.scss",
    "content": ".add-link {\n    max-width: 500px;\n    box-sizing: border-box;\n    padding: 10px;\n    box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px;\n    border: 1px solid #fff;\n    position: relative;\n    top: 30px;\n    left: 50%;\n    margin-left: -250px;\n    background: #fff;\n    border-radius: 3px;\n\n    &__close {\n        position: absolute;\n        top: 5px;\n        right: 5px;\n        font-size: 24px;\n        cursor: pointer;\n        color: #415572;\n    }\n\n    &__close:hover {\n        color: #202A38;\n    }\n\n    &__header {\n        padding: 10px;\n    }\n\n    &__header-title {\n        text-align: center;\n        font-size: 20px;\n        font-weight: 500;\n        color: #202A38;\n    }\n\n    &__body {\n        padding: 0px 10px;\n        margin-bottom: 10px;\n    }\n\n    &__form-item {\n        margin-top: 15px;\n    }\n\n    &__form-control {\n        width: 100%;\n        box-sizing: border-box;\n        padding: 5px;\n        outline: none;\n        border: 1px solid #202A38;\n        border-radius: 3px;\n    }\n\n    &__form-control-error {\n        color: #F87272;\n        margin-top: 5px;\n        font-size: 12px;\n    }\n\n    &__form-btn {\n        outline: none;\n        background: #fff;\n        padding: 5px 10px;\n        border: 1px solid #202A38;\n        border-radius: 3px;\n        color: #202A38;\n        transition: all .3s;\n        cursor: pointer;\n    }\n\n    &__form-btn:hover {\n        color: #0FBD86;\n        border-color: #0FBD86;\n    }\n    &__form-btn:disabled {\n        color: #AEBCD1;\n        border-color: #AEBCD1;;\n    }\n}"
  },
  {
    "path": "aquila/view/components/layout/main/AddLink.tsx",
    "content": "import { FC, useEffect } from 'react';\nimport { IoCloseCircleOutline } from 'react-icons/io5';\nimport { useForm } from 'react-hook-form';\nimport { } from 'react'\n\nimport Modal from '../../ui/modal/Modal';\nimport classes from './AddLink.module.scss';\nimport { AppState } from '../../../store';\n\ninterface AddLinkFromData {\n    url: string;\n}\n\ninterface AddLinkProps {\n    onClose: Function;\n    onSubmitAddLink: Function;\n    addLinkState: AppState[\"addLink\"];\n}\n\nconst AddLink: FC<AddLinkProps> = ({ onClose, onSubmitAddLink, addLinkState}) => {\n\n    const { register, getValues, setError, formState: { errors }, reset} = useForm<AddLinkFromData>();\n    useEffect(() => {\n        if(addLinkState.errors) {\n            if(addLinkState.errors.url) {\n                setError(\"url\", { type: 'custom', message: addLinkState.errors.url });\n            }\n        }\n    }, [addLinkState.errors, setError])\n    const onSubmitHandler = async (e: any) => {\n        e.preventDefault();\n        var data = getValues();\n        const status = await onSubmitAddLink(data);\n        if(status) {\n            reset();\n            onClose();\n        }\n    }\n\n    return (\n        <Modal onClose={onClose}>\n            <div className={classes[\"add-link\"]} onClick={e => e.stopPropagation()}>\n                <span onClick={(e) => onClose()} className={classes[\"add-link__close\"]}>\n                    <IoCloseCircleOutline />\n                </span>\n                <div className={classes[\"add-link__header\"]}>\n                    <h3 className={classes[\"add-link__header-title\"]}>Add Link</h3>\n                </div>\n                <form onSubmit={onSubmitHandler} className={classes[\"add-link__body\"]}>\n                    <div className={classes[\"add-link__form-item\"]}>\n                        <input {...register(\"url\")} placeholder='Enter Your Link' className={classes[\"add-link__form-control\"]} type=\"text\" />\n                        {errors.url && <p className={classes[\"add-link__form-control-error\"]}>{errors.url.message}</p>}\n                    </div>\n                    <div className={classes[\"add-link__form-item\"]}>\n                        <button disabled={addLinkState.status === \"pending\"} type=\"submit\" className={classes[\"add-link__form-btn\"]}>Add Link</button>\n                    </div>\n                </form>\n            </div>\n        </Modal>\n    )\n}\n\nexport default AddLink;"
  },
  {
    "path": "aquila/view/components/layout/main/Footer.module.scss",
    "content": ".footer {\n    padding: 20px 0px;\n    text-align: center;\n    box-sizing: border-box;\n\n    &__icon-menu {\n        list-style: none;\n        display: flex;\n        justify-content: center;\n        gap: 20px;\n        margin: 20px 0px;\n    }\n\n    &__icon-menu-link {\n        font-size: 25px;\n        color: #202A38;\n        transition: all .3s;\n    }\n\n\n    &__icon-menu-link:hover {\n        color: #0FBD86;\n    }\n}\n\n.footer-banner {\n    position: fixed;\n    bottom: 0px;\n    left: 0px;\n    right: 0px;\n    background: #F87272;\n    color: #fff;\n    padding: 10px 5px;\n    text-align: center;\n\n    &__close-btn {\n        background: none;\n        border: none;\n        outline: none;\n        color: #fff;\n        position: absolute;\n        top: 5px;\n        right: 5px;\n        cursor: pointer;\n        font-size: 16px;\n    }\n\n    &__text {\n        font-size: 14px;\n    }\n}"
  },
  {
    "path": "aquila/view/components/layout/main/Footer.tsx",
    "content": "import { FC, useState } from 'react';\nimport Link from 'next/link';\nimport { FaGithub, FaYoutube, FaMedium } from 'react-icons/fa';\nimport { FiX } from 'react-icons/fi';\n\nimport classes from './Footer.module.scss';\nimport moment from 'moment';\n\ninterface FooterProps {\n\tsignedInUser: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tcreatedAt: string;\n\t} | null;\n\taccountStatus: string | null;\n}\n\nconst Footer: FC<FooterProps> = (props) => {\n\tconst [showBanner, setShowBanner] = useState(true);\n\tconst { signedInUser, accountStatus } = props;\n\tlet accountExpiryData;\n\tif(signedInUser) {\n\t\taccountExpiryData = moment(signedInUser.createdAt).add(14, 'days').format('Mo MMMM');\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t{accountStatus === 'TEMPORARY' && showBanner && <div className={classes[\"footer-banner\"]}>\n\t\t\t\t<button onClick={() => setShowBanner(false)} className={classes[\"footer-banner__close-btn\"]}><FiX /></button>\n\t\t\t\t<p className={classes[\"footer-banner__text\"]}>{`Your Account is temporary and will be deleted automatically on ${accountExpiryData}.`}Please <Link href=\"/account/edit-profile\">Activate</Link> you account</p>\n\t\t\t</div>\n\t\t\t}\n\t\t\t<footer className={classes.footer}>\n\t\t\t\t<p>Copyright © 2022 - All right reserved by Aquila Network</p>\n\t\t\t\t<ul className={classes[\"footer__icon-menu\"]}>\n\t\t\t\t\t<li className={classes[\"footer__icon-menu-item\"]}>\n\t\t\t\t\t\t<a target=\"__blank\" href=\"https://github.com/Aquila-Network\" className={classes[\"footer__icon-menu-link\"]}><FaGithub /></a>\n\t\t\t\t\t</li>\t\n\t\t\t\t\t<li className={classes[\"footer__icon-menu-item\"]}>\n\t\t\t\t\t\t<a target=\"__blank\" href=\"https://medium.com/aquila-network\" className={classes[\"footer__icon-menu-link\"]}><FaMedium /></a>\n\t\t\t\t\t</li>\n\t\t\t\t\t<li className={classes[\"footer__icon-menu-item\"]}>\n\t\t\t\t\t\t<a target=\"__blank\" href=\"https://www.youtube.com/channel/UCcghHPcdlh0V5TdQfLHjhOA\" className={classes[\"footer__icon-menu-link\"]}><FaYoutube /></a>\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</footer>\n\t\t</>\n\t);\n}\n\nexport default Footer;"
  },
  {
    "path": "aquila/view/components/layout/main/Header.module.scss",
    "content": ".header {\n    padding: 20px 0px;\n\n    &__container {\n        margin: auto;\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n    }\n\n    &__brand-contaner {\n        order: 1;\n    }\n\n    &__brand-link {\n        display: flex;\n        text-decoration: none;\n        align-items: center;\n    }\n\n    &__brand-img-container {\n        width: 50px;\n    }\n\n    &__brand-text {\n        font-size: 16px;\n        font-weight: 500;\n        color: #202A38;\n    }\n\n    &__nav-container {\n        order: 3;\n    }\n\n    &__nav-list-container {\n        display: flex;\n        list-style: none;\n        align-items: center;\n        gap: 10px;\n    }\n\n    &__nav-mobile-menu-close {\n        display: none;\n        border: none;\n        outline: none;\n        background: none;\n        cursor: pointer;\n        font-size: 24px;\n    }\n\n    &__nav-list-item {\n        position: relative;\n    }\n\n    &__nav-list-item--mobile-menu {\n        display: none;\n    }\n\n    &__nav-list-link {\n        text-decoration: none;\n        color: #202A38;\n        transition: all .3;\n        cursor: pointer;\n        font-weight: 500\n    }\n\n    &__nav-list-link--active {\n        color: #0FBD86;\n    }\n\n    &__nav-list-link:hover {\n        color: #0FBD86;\n    }\n\n    &__nav-dropdown {\n        position: absolute;\n        list-style: none;\n        padding: 0px;\n        background: #fff;\n        min-width: 150px;\n        right: 0px;\n        margin-top: 10px;\n        box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 50px;\n        // box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;\n    }\n\n    &__nav-dropdown::before {\n        content: '';\n        width: 0px;\n        height: 0px;\n        border: 10px solid #fff;\n        border-left-color: transparent;\n        border-right-color: transparent;\n        border-top-color: transparent;\n        position: absolute;\n        top: -20px;\n        right: 10px;\n    }\n\n    &__nav-dropdown-link {\n        text-decoration: none;\n        color: #202A38;\n        font-size: 14px;\n        display: block;\n        padding: 10px 20px;\n    }\n\n    &__nav-dropdown-link:hover {\n        background: #EFF2F6;\n    }\n\n    &__mobile-menu-btn-container {\n        order: 2;\n        display: none;\n    }\n\n    &__mobile-menu-btn {\n        border: none;\n        outline: none;\n        background: none;\n        cursor: pointer;\n        font-size: 25px;\n    }\n}\n\n@media only screen and (max-width: 768px) {\n    .header {\n        &__mobile-menu-btn-container {\n            display: block;\n        }\n\n        &__nav-container {\n            position:fixed;\n            width: 100vw;\n            height: 100vh;\n            left: 0px;\n            right: 0px;\n            top: 0px;\n            bottom: 0px;\n            z-index: 200;\n            background: #fff;\n            display: none;\n        }\n\n        &__nav-container--show {\n            display: block\n        }\n\n        &__nav-list-container {\n            height: 100%;\n            flex-direction: column;\n            justify-content: center;\n        }\n\n        &__nav-mobile-menu-close {\n            display: block;\n            position: absolute;\n            top: 20px;\n            right: 20px;\n        }\n\n        &__nav-list-item {\n            padding: 20px 0px;\n        }\n\n        &__nav-list-item--profile-item {\n            display: none;\n        }\n\n        &__nav-list-item--mobile-menu {\n            display: block;\n        }\n\n        &__mobile-menu-btn {\n\n        }\n    }\n}"
  },
  {
    "path": "aquila/view/components/layout/main/Header.tsx",
    "content": "import Image from \"next/image\";\nimport Link from \"next/link\";\nimport { FC, useState } from \"react\";\nimport Avatar from 'boring-avatars';\nimport { FiMenu, FiX } from 'react-icons/fi';\n\nimport Logo from '../../../public/img/logo.png';\nimport classes from './Header.module.scss';\nimport Container from \"../../ui/layout/Container\";\nimport Modal from \"../../ui/modal/Modal\";\nimport AddLink from \"./AddLink\";\nimport { useRouter } from \"next/router\";\nimport { AppState } from \"../../../store\";\n\ninterface HeaderProps {\n\tonSignOut: Function\n\tonSubmitAddLink: Function\n\tisAuth: boolean;\n\taddLinkState: AppState[\"addLink\"];\n\tsignedInUser: {\n\t\tfirstName: string;\n\t\tlastName: string;\n\t} | null;\n}\n\n\nconst Header: FC<HeaderProps> = (props: HeaderProps) => {\n\tconst { signedInUser, onSignOut } = props;\n\tconst [toggleDropDown, setToggleDropDown] = useState(false);\n\tconst [showAddLinkModal, setAddLinkModal] = useState(false);\n\tconst [showMobileMenu, setShowMobileMenu] = useState(false);\n\tconst router = useRouter();\n\n\tconst signOutHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonSignOut();\n\t}\n\n\tconst dropDownToggleHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tsetToggleDropDown(!toggleDropDown);\n\t}\n\n\tconst addLinkHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tsetAddLinkModal(true);\n\t}\n\n\tconst onCloseModalHander = (e: any) => {\n\t\tsetAddLinkModal(false);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<header className={classes.header}>\n\t\t\t\t<Container>\n\t\t\t\t\t<div className={classes.header__container}>\n\t\t\t\t\t\t<div className={classes[\"header__brand-container\"]}>\n\t\t\t\t\t\t\t<Link href=\"/\">\n\t\t\t\t\t\t\t\t<a className={`${classes[\"header__brand-link\"]}`}>\n\t\t\t\t\t\t\t\t\t<div className={classes[\"header__brand-img-container\"]}>\n\t\t\t\t\t\t\t\t\t\t<Image src={Logo} alt=\"Aquila Network Logo\" objectFit=\"contain\" />\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<h2 className={classes[\"header__brand-text\"]}>AQUILA NETWORK</h2>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<nav className={`${classes[\"header__nav-container\"]} ${showMobileMenu ? classes[\"header__nav-container--show\"] : ''}`}>\n\t\t\t\t\t\t\t<button onClick={() => setShowMobileMenu(false)} className={classes[\"header__nav-mobile-menu-close\"]}><FiX /></button>\n\t\t\t\t\t\t\t<ul className={classes[\"header__nav-list-container\"]}>\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<Link href=\"/\"><a className={`${classes[\"header__nav-list-link\"]} ${router.pathname === '/' ? classes[\"header__nav-list-link--active\"]: ''} `} >Home</a></Link>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t{props.isAuth &&\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<Link href=\"/home\"><a className={`${classes[\"header__nav-list-link\"]} ${router.pathname === '/home' ? classes[\"header__nav-list-link--active\"]: ''}`} >My Index</a></Link>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t{props.isAuth &&\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<a href=\"#\" onClick={addLinkHandler} className={classes[\"header__nav-list-link\"]} >Add Link</a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t{props.isAuth &&\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<Link href=\"/subscription\"><a className={`${classes[\"header__nav-list-link\"]} ${router.pathname === '/subscription' ? classes[\"header__nav-list-link--active\"]: ''}`} >Subscription</a></Link>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<Link href=\"/explore\"><a className={`${classes[\"header__nav-list-link\"]} ${router.pathname === '/explore' ? classes[\"header__nav-list-link--active\"]: ''}`} >Explore</a></Link>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<a className={classes[\"header__nav-list-link\"]}  href=\"https://blog.aquila.network/\">Blog</a>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t{!props.isAuth &&\t\n\t\t\t\t\t\t\t\t<li className={classes[\"header__nav-list-item\"]}>\n\t\t\t\t\t\t\t\t\t<Link href=\"/sign-in\"><a className={`${classes[\"header__nav-list-link\"]} ${router.pathname === '/sign-in' ? classes[\"header__nav-list-link--active\"]: ''}`} >Sign In</a></Link>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t{props.isAuth &&\n\t\t\t\t\t\t\t\t<li className={`${classes[\"header__nav-list-item\"]} ${classes[\"header__nav-list-item--profile-item\"]}`}>\n\t\t\t\t\t\t\t\t\t<a href=\"#\" onClick={dropDownToggleHandler}>\n\t\t\t\t\t\t\t\t\t\t<Avatar name={signedInUser ? `${signedInUser?.firstName} ${signedInUser.lastName}` : ''} size=\"40\" variant=\"beam\" />\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t\t{toggleDropDown &&\n\t\t\t\t\t\t\t\t\t<ul className={classes[\"header__nav-dropdown\"]}>\n\t\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t\t<Link href=\"/account/edit-profile\">\n\t\t\t\t\t\t\t\t\t\t\t\t<a className={classes[\"header__nav-dropdown-link\"]}>Edit Profile</a>\n\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t</li>\t\n\t\t\t\t\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t\t\t\t\t<Link href=\"#\">\n\t\t\t\t\t\t\t\t\t\t\t\t<a onClick={signOutHandler} className={classes[\"header__nav-dropdown-link\"]}>Sign Out</a>\n\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<li className={`${classes[\"header__nav-list-item\"]} ${classes[\"header__nav-list-item--mobile-menu\"]}`}>\n\t\t\t\t\t\t\t\t\t<Link href=\"/account/edit-profile\">\n\t\t\t\t\t\t\t\t\t\t<a className={classes[\"header__nav-list-link\"]}>Edit Profile</a>\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t</li>\t\n\t\t\t\t\t\t\t\t<li className={`${classes[\"header__nav-list-item\"]} ${classes[\"header__nav-list-item--mobile-menu\"]}`}>\n\t\t\t\t\t\t\t\t\t<Link href=\"#\">\n\t\t\t\t\t\t\t\t\t\t<a onClick={signOutHandler} className={classes[\"header__nav-list-link\"]}>Sign Out</a>\n\t\t\t\t\t\t\t\t\t</Link>\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</nav>\n\t\t\t\t\t\t<div className={classes[\"header__mobile-menu-btn-container\"]}>\n\t\t\t\t\t\t\t<button onClick={() => setShowMobileMenu(true)} className={classes[\"header__mobile-menu-btn\"]}><FiMenu /></button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</Container>\n\t\t\t</header>\n\t\t\t{showAddLinkModal &&\n\t\t\t<AddLink \n\t\t\t\taddLinkState={props.addLinkState}\n\t\t\t\tonSubmitAddLink={props.onSubmitAddLink}\n\t\t\t\tonClose={onCloseModalHander}\n\t\t\t/>\n\t\t\t}\n\t\t</>\n\t)\n}\n\nexport default Header;"
  },
  {
    "path": "aquila/view/components/layout/main/MainLayout.module.scss",
    "content": ".main-layout {\n\theight: 100%;\n\tdisplay: flex;\n\tflex-direction: column;\n\tjustify-content: space-between;\n\n\t&__header--with-border {\n\t\tbox-shadow: inset 0px -1px 1px #EFF2F6;\n\t}\n\n}"
  },
  {
    "path": "aquila/view/components/layout/main/MainLayout.tsx",
    "content": "import { signOut } from 'next-auth/react';\nimport { useRouter } from 'next/router';\nimport { FC, useEffect, useState } from 'react';\nimport { useAppDispatch, useAppSelector } from '../../../store';\nimport { selectAuth } from '../../../store/slices/auth';\nimport { addLink, AddLinkData, selectAddLink } from '../../../store/slices/bookmark/addLink';\nimport { toast, ToastOptions } from 'react-toastify';\n\nimport Footer from './Footer';\nimport Header from './Header';\nimport classes from './MainLayout.module.scss';\nimport { getLoggedInCustCollections, selectGetLoggedInCustCollections } from '../../../store/slices/collection/getLoggedInCustCollections';\nimport { Omit } from '@reduxjs/toolkit/dist/tsHelpers';\nimport { useProgressLoader } from '../../ui/progressLoader/ProgressLoader';\n\ninterface MainLayoutProps {\n\tchildren: React.ReactNode;\n\theaderBorder?: boolean;\n}\n\nconst MainLayout: FC<MainLayoutProps> = ({ children, headerBorder = true}) => {\n\tconst router = useRouter();\n\tconst authState = useAppSelector(selectAuth);\n\tconst addLinkState = useAppSelector(selectAddLink)\n\tconst currentCustomerCollections = useAppSelector(selectGetLoggedInCustCollections);\n\tconst dispatch = useAppDispatch();\n\tconst [signedInUser, setSignedInUser] = useState<{ firstName: string, lastName: string, createdAt: string} | null>(null);\n\tconst { setLoader } = useProgressLoader();\n\n\tuseEffect(() => {\n\t\tif(authState.isSignedIn && authState.customer) {\n\t\t\tsetSignedInUser({\n\t\t\t\tfirstName: authState.customer.firstName,\n\t\t\t\tlastName: authState.customer.lastName,\n\t\t\t\tcreatedAt: authState.customer.createdAt\n\t\t\t})\n\t\t}\n\t}, [authState]);\n\n\n\tuseEffect(() => {\n\t\tconst toastOptions: ToastOptions = {\n\t\t\tposition: \"top-center\",\n\t\t\thideProgressBar: true,\n\t\t}\n\n\t\tif(authState.isSignedIn) {\n\t\t\tdispatch(getLoggedInCustCollections())\n\t\t\t\t.unwrap()\n\t\t\t\t.catch((e) => {\n\t\t\t\t\ttoast(e.message, { ...toastOptions, type: \"error\"});\n\t\t\t\t})\n\t\t}\n\t}, [authState, dispatch]);\n\n\n\tconst signOutHandler = async () => {\n\t\tawait signOut();\n\t\trouter.push(\"/sign-in\");\n\t}\n\n\tconst onSubmitAddLinkHandler = async (data: Omit<AddLinkData, \"collectionId\">) => {\n\t\tsetLoader(true);\n\t\tconst toastOptions: ToastOptions = {\n\t\t\tposition: \"top-center\",\n\t\t\thideProgressBar: true,\n\t\t}\n\t\tif(currentCustomerCollections.collecitons && currentCustomerCollections.collecitons[0]) {\n\t\t\tconst formData = {\n\t\t\t\turl: data.url,\n\t\t\t\tcollectionId: currentCustomerCollections.collecitons[0].id\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait dispatch(addLink(formData)).unwrap();\n\t\t\t\ttoast(\"Link added successfully\", { ...toastOptions, type: \"success\"})\n\t\t\t\tsetLoader(false);\n\t\t\t\treturn true;\n\t\t\t}catch(e) {\n\t\t\t\tif(e instanceof Error) {\n\t\t\t\t\ttoast(e.message, { ...toastOptions, type: \"error\"});\n\t\t\t\t}\n\t\t\t\tsetLoader(false);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\n\treturn (\n\t\t\t<div className={classes[\"main-layout\"]}>\n\t\t\t\t<div className={classes[\"main-layout__top\"]}>\n\t\t\t\t\t<section className={headerBorder ? classes[\"main-layout__header--with-border\"] : ''}>\n\t\t\t\t\t\t<Header \n\t\t\t\t\t\t\taddLinkState={addLinkState}\n\t\t\t\t\t\t\tonSubmitAddLink={onSubmitAddLinkHandler}\n\t\t\t\t\t\t\tsignedInUser={signedInUser}\n\t\t\t\t\t\t\tisAuth={authState.isSignedIn ? true : false}\n\t\t\t\t\t\t\tonSignOut={signOutHandler}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</section>\n\t\t\t\t\t<section className={classes[\"main-layout__body\"]}>{children}</section>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"main-layout__bottom\"]}>\n\t\t\t\t\t<section className={classes[\"main-layout__footer\"]}>\n\t\t\t\t\t\t<Footer signedInUser={signedInUser} accountStatus={authState?.accountStatus || null}  />\n\t\t\t\t\t</section>\n\t\t\t\t</div>\n\t\t\t</div>\n\t)\n}\n\nexport default MainLayout;"
  },
  {
    "path": "aquila/view/components/pages/account/editProfile/EditProfileForm.module.scss",
    "content": ".edit-profile-form {\n    &__form-group {\n        margin-bottom: 15px;\n    }\n\n    &__form-label {\n        display: block;\n        margin-bottom: 5px;\n        font-size: 18px;\n    }\n\n    &__form-control {\n        width: 100%;\n        padding: 8px 5px;\n        box-sizing: border-box;\n    }\n\n    &__form-control-error {\n        color: #F87272;\n        margin-top: 5px;\n        font-size: 12px;\n    }\n\n    &__form-btn {\n        padding: 5px 10px;\n        background: #fff;\n        outline: none;\n        border-radius: 3px;\n        font-size: 16px;\n        transition: all .3s;\n        border: 1px solid #202A38;\n        cursor: pointer;\n        display: flex;\n        align-items: center;\n    } \n\n    &__form-btn:hover {\n        border-color: #36D399;\n        color: #36D399;\n    }\n\n    &__form-btn:disabled {\n        border-color: #6D87AC;\n        color: #6D87AC;\n        cursor:not-allowed;\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/account/editProfile/EditProfileForm.tsx",
    "content": "import { FC, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { AppState } from '../../../../store';\n\nimport { Customer } from '../../../../store/slices/types/Customer';\nimport classes from './EditProfileForm.module.scss';\n\ninterface EditProfileFormProps {\n    customer: Customer;\n    accountStatus: string | null;\n    onSubmit: Function;\n    activateCustomerState: AppState[\"activateCustomer\"];\n    updateCustomerState: AppState[\"updateCustomer\"];\n}\n\ninterface EditProfileFormData {\n    firstName: string;\n    lastName: string;\n    email: string;\n    desc: string;\n    lightningAddress: string;\n}\n\nconst EditProfileForm: FC<EditProfileFormProps> = ({customer, accountStatus, onSubmit, activateCustomerState, updateCustomerState}) => {\n    const { register, getValues, setError, reset, formState: { errors } } = useForm<EditProfileFormData>({ defaultValues: {\n        firstName: customer.firstName,\n        lastName: customer.lastName,\n        email: customer.email,\n        lightningAddress: customer.lightningAddress,\n        desc: customer.desc\n    } });\n\n    useEffect(() => {\n        if(updateCustomerState.errors) {\n            if(updateCustomerState.errors.firstName) {\n                setError(\"firstName\", { type: 'custom', message: updateCustomerState.errors.firstName });\n            }\n            if(updateCustomerState.errors.lastName) {\n                setError(\"lastName\", { type: 'custom', message: updateCustomerState.errors.lastName });\n            }\n            if(updateCustomerState.errors.email) {\n                setError(\"email\", { type: 'custom', message: updateCustomerState.errors.email });\n            }\n            if(updateCustomerState.errors.desc) {\n                setError(\"desc\", { type: 'custom', message: updateCustomerState.errors.desc });\n            }\n        }\n    }, [updateCustomerState.errors, setError])\n\n    useEffect(() => {\n        if(activateCustomerState.errors) {\n            if(activateCustomerState.errors.firstName) {\n                setError(\"firstName\", { type: 'custom', message: activateCustomerState.errors.firstName });\n            }\n            if(activateCustomerState.errors.lastName) {\n                setError(\"lastName\", { type: 'custom', message: activateCustomerState.errors.lastName });\n            }\n            if(activateCustomerState.errors.email) {\n                setError(\"email\", { type: 'custom', message: activateCustomerState.errors.email });\n            }\n            if(activateCustomerState.errors.desc) {\n                setError(\"desc\", { type: 'custom', message: activateCustomerState.errors.desc });\n            }\n        }\n    }, [activateCustomerState.errors, setError])\n\n    \n\n    const submitHandler = async (e: any) => {\n        const data = getValues();\n        e.preventDefault();\n        const status = await onSubmit(data)\n        if(status){\n            reset(undefined, { keepValues: true});\n        }\n    }\n\n    return (\n        <form className={classes[\"edit-profile-form\"]} onSubmit={submitHandler}>\n            <div className={classes[\"edit-profile-form__form-group\"]}>\n                <label className={classes[\"edit-profile-form__form-label\"]}>First Name</label>\n                <input {...register(\"firstName\")} className={classes[\"edit-profile-form__form-control\"]} type=\"text\" />\n                {errors.firstName && <p className={classes[\"edit-profile-form__form-control-error\"]}>{errors.firstName.message}</p>}\n            </div>\n            <div className={classes[\"edit-profile-form__form-group\"]}>\n                <label className={classes[\"edit-profile-form__form-label\"]}>Last Name</label>\n                <input {...register(\"lastName\")} className={classes[\"edit-profile-form__form-control\"]} type=\"text\" />\n                {errors.lastName && <p className={classes[\"edit-profile-form__form-control-error\"]}>{errors.lastName.message}</p>}\n            </div>\n            <div className={classes[\"edit-profile-form__form-group\"]}>\n                <label className={classes[\"edit-profile-form__form-label\"]}>Email</label>\n                <input {...register(\"email\")} className={classes[\"edit-profile-form__form-control\"]} type=\"email\" />\n                {errors.email && <p className={classes[\"edit-profile-form__form-control-error\"]}>{errors.email.message}</p>}\n            </div>\n            <div className={classes[\"edit-profile-form__form-group\"]}>\n                <label className={classes[\"edit-profile-form__form-label\"]}>Lightning address</label>\n                <input {...register(\"lightningAddress\")} className={classes[\"edit-profile-form__form-control\"]} type=\"text\" />\n                <p className={classes[\"edit-profile-form__form-control-error\"]}>\n                    <a target=\"_blank\" rel=\"noreferrer\" href=\"https://lightningaddress.com/\">Get a Lightning address ?</a>\n                </p>\n                {errors.lightningAddress && <p className={classes[\"edit-profile-form__form-control-error\"]}>{errors.lightningAddress.message}</p>}\n            </div>\n            <div className={classes[\"edit-profile-form__form-group\"]}>\n                <label className={classes[\"edit-profile-form__form-label\"]}>Description</label>\n                <textarea {...register(\"desc\")}className={classes[\"edit-profile-form__form-control\"]} rows={5} ></textarea>\n                {errors.desc && <p className={classes[\"edit-profile-form__form-control-error\"]}>{errors.desc.message}</p>}\n            </div>  \n            <div className={classes[\"edit-profile-form__form-group\"]}>\n                <button\n                    disabled={updateCustomerState.status === \"pending\" || activateCustomerState.status === \"pending\"}\n                    className={classes[\"edit-profile-form__form-btn\"]}\n                    type=\"submit\"\n                    value=\"Save\"\n                >\n                    <span>{accountStatus === \"TEMPORARY\" ? 'Activate Account' : 'Save' }</span>\n                </button>\n            </div>\n            <div style={{marginTop: \"50px\"}} className={classes[\"edit-profile-form__form-group\"]}>\n                <label className={classes[\"edit-profile-form__form-label\"]}>Secret Key</label>\n                <input disabled className={classes[\"edit-profile-form__form-control\"]} type=\"text\" value={customer.secretKey} />\n            </div>\n        </form>\n    )\n}\n\nexport default EditProfileForm;"
  },
  {
    "path": "aquila/view/components/pages/account/editProfile/EditProfileHeader.module.scss",
    "content": ".header {\n    &__title {\n        font-size: 22px;\n        color: #202A38;\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/account/editProfile/EditProfileHeader.tsx",
    "content": "import classes from './EditProfileHeader.module.scss';\n\nconst EditProfileHeader = () => {\n    return (\n        <header className={classes.header}>\n            <h3 className={classes.header__title}>Edit Profile</h3>\n        </header>\n    )\n}\n\nexport default EditProfileHeader;"
  },
  {
    "path": "aquila/view/components/pages/account/editProfile/EditProfileWrapper.module.scss",
    "content": ".edit-profile-wrapper {\n    margin-top: 20px;\n\n    &__alert-container {\n        margin-bottom: 20px;\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/account/editProfile/EditProfileWrapper.tsx",
    "content": "import { FC } from 'react';\nimport { Oval } from 'react-loader-spinner';\nimport { AppState } from '../../../../store';\n\nimport SettingsLayout from \"../../../layout/childLayout/settings/SettingsLayout\"\nimport Alert from '../../../ui/alert/Alert';\nimport EditProfileForm from \"./EditProfileForm\"\nimport EditProfileHeader from \"./EditProfileHeader\"\nimport classes from './EditProfileWrapper.module.scss';\n\ninterface EditProfileWrapperProps {\n    currentLoggedInCustomerState: AppState[\"getCurrentLoggedInCustomer\"];\n    authState: AppState[\"auth\"];\n    updateCustomerState: AppState[\"updateCustomer\"];\n    activateCustomerState: AppState[\"activateCustomer\"];\n    onSubmit: Function\n}\n\nconst EditProfileWrapper: FC<EditProfileWrapperProps> = (props) => {\n    return (\n        <SettingsLayout authState={props.authState}>\n            <EditProfileHeader />\n            <div className={classes[\"edit-profile-wrapper\"]}>\n                {props.authState.accountStatus === \"TEMPORARY\" &&\n                <div className={classes[\"edit-profile-wrapper__alert-container\"]}>\n                    <Alert type=\"danger\" message='Your account is temporary!' />\n                </div>\n                }\n                {props.currentLoggedInCustomerState.status === \"pending\" && \n                    <Oval height={30} width=\"100%\" strokeWidth={5} color=\"#0FBD86\" strokeWidthSecondary={5} />\n                }\n\n                {props.currentLoggedInCustomerState.status === \"failed\" && \n                    <Alert message={props.currentLoggedInCustomerState.errorMessage|| \"\"} type=\"danger\" />\n                }\n                {props.currentLoggedInCustomerState.customer &&\n                    <EditProfileForm\n                        onSubmit={props.onSubmit}\n                        accountStatus={props.authState.accountStatus}\n                        customer={props.currentLoggedInCustomerState.customer}\n                        activateCustomerState={props.activateCustomerState}\n                        updateCustomerState={props.updateCustomerState}\n                    />\n                }\n            </div>\n        </SettingsLayout>\n    )\n}\n\nexport default EditProfileWrapper"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/CollectionBookmarksPageWrapper.module.scss",
    "content": ".collection-bookmarks {\n    display: flex;\n    gap: 50px;\n\n    &__search-area {\n        flex-basis: 900px;    \n    }\n\n    &__search-bar {\n        margin-top: 20px;\n        width: 600px;\n    }\n\n    &__search-results {\n        margin-top: 30px;\n    }\n\n    &__sidebar {\n        padding-top: 20vh;\n        flex: 1 1 0;\n    }\n\n    &__sidebar-close {\n        display: none;\n    }\n}\n\n@media only screen and (max-width: 1200px) {\n    .collection-bookmarks {\n        gap: 20px;\n    }\n}\n\n@media only screen and (max-width: 992px) {\n   .collection-bookmarks {\n    flex-direction: column;\n\n    &__sidebar {\n        position: fixed;\n        bottom: 0px;\n        left: 0px;\n        right: 0px;\n        padding-top: 0px;\n    }\n\n    &__search-bar {\n        width: 80%;\n    }\n\n    &__sidebar--close {\n        display: none;\n    }\n\n    &__sidebar-close {\n        display: block;\n        position: absolute;\n        background: none;\n        font-size: 18px;\n        outline: none;\n        border: none;\n        top: 25px;\n        right: 5px;\n        cursor: pointer;\n    }\n\n   } \n}"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/CollectionBookmarksPageWrapper.tsx",
    "content": "import { FC, useEffect, useState } from \"react\";\nimport { Oval } from 'react-loader-spinner';\nimport { FiX } from 'react-icons/fi';\n\nimport { AppState } from \"../../../../../store\";\nimport { Collection } from \"../../../../../store/slices/types/Collection\";\nimport { Customer } from \"../../../../../store/slices/types/Customer\";\nimport MainLayout from \"../../../../layout/main/MainLayout\"\nimport Container from \"../../../../ui/layout/Container\";\nimport classes from \"./CollectionBookmarksPageWrapper.module.scss\";\nimport SearchBar from \"./SearchBar\";\nimport SearchPageProfile from \"./SearchPageProfile\";\nimport SearchResults from \"./SearchResults\";\nimport { AuthState } from \"../../../../../store/slices/auth\";\n\ninterface CollectionBookmarksPageWrapperProps {\n    customer: Customer | null;\n    collection: Collection | null;\n    bookmarksState: AppState[\"getPublicBookmarksByCollectionId\"];\n    onSearch: Function;\n    onClickNextPage: Function;\n    onClickPrevPage: Function;\n    onSubscribe: Function;\n    isCollectionSubscribed: boolean | null;\n    isSignedIn: boolean | null;\n    currentLoggedInCustomer: AuthState['customer'] | null;\n    onUnsubscribe: Function;\n}\n\nconst CollectionBookmarksPageWrapper: FC<CollectionBookmarksPageWrapperProps> = (props) => {\n    const { collection, customer, bookmarksState, onSearch, onClickNextPage, onClickPrevPage, onSubscribe, isCollectionSubscribed, isSignedIn, onUnsubscribe, currentLoggedInCustomer } = props;\n    const [hasNext, setHasNext] = useState(false);\n    const [hasPrev, setHasPrev] = useState(false);\n    const [showSidebar, setShowSidebar] = useState(true);\n    \n    useEffect(() => {\n        if(bookmarksState.currentPage && bookmarksState.totalPages) {\n            if(bookmarksState.currentPage < bookmarksState.totalPages) {\n                setHasNext(true);\n            }else {\n                setHasNext(false);\n            }\n            if(bookmarksState.currentPage > 1) {\n                setHasPrev(true)\n            }else {\n                setHasPrev(false)\n            }\n        }\n    }, [bookmarksState])\n\n    return (\n        <MainLayout>\n            <Container>\n                <div className={classes[\"collection-bookmarks\"]}>\n                    <section className={classes[\"collection-bookmarks__search-area\"]}>\n                        <div className={classes[\"collection-bookmarks__search-bar\"]}>\n                            <SearchBar onSearch={onSearch} />\n                        </div>\n                        <div className={classes[\"collection-bookmarks__search-results\"]}>\n                            {bookmarksState.status === \"pending\" && <Oval height={30} width=\"100%\" strokeWidth={5} color=\"#0FBD86\" strokeWidthSecondary={5} />}\n                            {bookmarksState.bookmarks && <SearchResults \n                                totalRecords={bookmarksState.totalRecords}\n                                onClickNextPage={onClickNextPage}\n                                onClickPrevPage={onClickPrevPage}\n                                hasPrev={hasNext}\n                                hasNext={hasPrev}\n                                bookmarks={bookmarksState.bookmarks}\n                                />}\n                        </div>\n                    </section>\n                    <section className={`${classes[\"collection-bookmarks__sidebar\"]} ${!showSidebar? classes[\"collection-bookmarks__sidebar--close\"] : ''}`}>\n                        <button onClick={() => setShowSidebar(false)} className={classes[\"collection-bookmarks__sidebar-close\"]}><FiX /></button>\n                       {collection && customer && <SearchPageProfile\n                        collection={collection}\n                        customer={customer}\n                        onSubscribe={onSubscribe}\n                        isCollectionSubscribed={isCollectionSubscribed}\n                        isSignedIn={isSignedIn}\n                        isCurrentLoggedInCustProfile={(isSignedIn && currentLoggedInCustomer && currentLoggedInCustomer.customerId === customer.id) ? true : false}\n                        onUnsubscribe={onUnsubscribe}\n                        />}\n                    </section>\n                </div>\n            </Container>\n        </MainLayout>\n    )\n}\n\nexport default CollectionBookmarksPageWrapper;"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchBar.module.scss",
    "content": ".search-bar {\n\tpadding: 10px 5px;\n\n\t&__container {\n\t\tdisplay: flex;\n\t\tborder-bottom: 1px solid #AEBCD1;\n\t\tpadding: 10px 5px;\n\t}\n\n\t&__input {\n\t\tmargin-right: 10px;\n\t\twidth: 100%;\n\t\tborder: none;\n\t\toutline: none;\n\t}\n\n\t&__input::placeholder {\n\t\tcolor: #AEBCD1;\n\t}\n\n\t&__btn {\n\t\tborder: none;\n\t\toutline: none;\n\t\tbackground: transparent;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchBar.tsx",
    "content": "import { FC, useRef } from 'react';\nimport { IoSearch } from 'react-icons/io5';\nimport classes from './SearchBar.module.scss';\n\ninterface SearchBarProps {\n\tonSearch: Function\n}\n\nconst SearchBar: FC<SearchBarProps> = (props) => {\n\tconst { onSearch } = props;\n\tconst searchValueRef = useRef<HTMLInputElement>(null);\n\n\tconst onSubmitHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonSearch(searchValueRef.current?.value)\n\t}\n\n\treturn (\n\t\t<div className={classes[\"search-bar\"]}>\n\t\t\t<form className={classes[\"search-bar__container\"]} onSubmit={onSubmitHandler}>\n\t\t\t\t<input ref={searchValueRef} className={classes[\"search-bar__input\"]} placeholder='Search Bookmarks...' type=\"text\" />\n\t\t\t\t<button className={classes[\"search-bar__btn\"]}>\n\t\t\t\t\t<IoSearch />\n\t\t\t\t</button>\n\t\t\t</form>\n\t\t</div>\n\t)\n}\n\nexport default SearchBar;"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchPageProfile.module.scss",
    "content": ".search-profile {\n\tpadding: 15px;\n\tmargin-top: 20px;\n\tborder: 1px solid #CED7E3;\n\tbackground: #fff;\n\tborder-radius: 3px;\n\n\t&__header {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\t\tmargin-bottom: 10px;\n\t}\n\n\t&__header-subscribe-btn {\n\t\tmargin-top: 5px;\n\t\tbackground: transparent;\n\t\tborder: 1px solid #8DA2BE;\n\t\toutline: none;\n\t\tborder-radius: 3px;\n\t\tcolor: #2E3D51;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t}\n\n\t&__header-subscribe-btn:hover {\n\t\tcolor: #0FBD86;\n\t\tborder-color: #0FBD86;\n\t}\n\n\t&__header-subscribe-btn:disabled {\n\t\tcolor: #CED7E3;\n\t\tborder-color: #CED7E3;\n\t}\n\n\t&__header-avatar {\n\t\twidth: 80px;\n\t}\n\n\t&__header-left {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 10px;\n\t}\n\n\t&__header-name {\n\t\tcolor: #202A38;\n\t\tfont-size: 25px;\n\t}\n\n\t&__body-desc {\n\t\tcolor: #415572;\n\t\tmargin: 0px;\n\t\tfont-size: 14px;\n\t\tmargin-bottom: 20px;\n\t}\n\n\t&__body-bookmark-title {\n\t\tfont-size: 14px;\n\t\tmargin-bottom: 5px;\n\t\tcolor: #415572;\n\t}\n\n\t&__body-share-bookmark-box {\n\t\toverflow: hidden;\n\t\tbackground: #EFF2F6;\n\t\tposition: relative;\n\t\tbox-sizing:border-box;\n\t\tmargin: 0px auto;\n\t\tpadding: 3px 4px;\n\t\tborder-radius: 3px;\n\t}\n\n\t&__body-share-bookmark-btn {\n\t\tposition: absolute;\n\t\tright: 0px;\n\t\ttop: 0px;\n\t\tbottom: 0px;\n\t\tfont-size: 12px;\n\t\tpadding: 5px;\n\t\tcolor: #fff;\n\t\tbackground: #3ABFF8;\n\t\tborder-radius: 3px;\n\t\tcursor: pointer;\n\t\ttransition: all .3s;\n\t}\n\n\t&__body-share-bookmark-btn:hover {\n\t\tbackground: #089DDE;\n\t}\n\n\t&__body-share-bookmark-link {\n\t\twidth: 100%;\n\t\tmargin: 0px;\n\t\tborder: none;\n\t\toutline: none;\n\t\tbackground: transparent;\n\t\tfont-size: 12px;\n\t\tcolor: #415572;\n\t}\n\n\t&__body-feedback-container {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__body-feedback-txt {\n\t\tcolor: #097654;\n\t\ttext-decoration: none;\n\t\tfont-size: 14px;\n\t\ttransition: all .3s;\n\t}\n\n\t&__body-feedback-txt:hover {\n\t\tcolor: #0FBD86;\n\t}\n}\n\n@media only screen and (max-width: 992px) {\n\t.search-profile {\n\t\tpadding-top: 25px;\n\n\t\t&__header-left {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: row;\n\t\t\talign-items: center;\n\t\t\tgap: 10px;\n\t\t}\n\n\t\t&__header-avatar {\n\t\t\twidth: 40px;\n\t\t}\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchPageProfile.tsx",
    "content": "import { VscFeedback } from 'react-icons/vsc';\nimport { toast } from 'react-toastify';\nimport Avatar from \"boring-avatars\";\n\nimport classes from './SearchPageProfile.module.scss';\nimport { Customer } from '../../../../../store/slices/types/Customer';\nimport { FC, useRef, useState } from 'react';\nimport { Collection } from '../../../../../store/slices/types/Collection';\n\ninterface SearchPageProfileProps {\n\tcustomer: Customer;\n\tcollection: Collection;\n\tonSubscribe: Function;\n\tisSignedIn: boolean | null;\n\tisCurrentLoggedInCustProfile: boolean;\n\tisCollectionSubscribed: boolean | null;\n\tonUnsubscribe: Function\n}\n\nconst SearchPageProfile: FC<SearchPageProfileProps> = ({ customer, collection, onSubscribe, isSignedIn, isCollectionSubscribed, onUnsubscribe, isCurrentLoggedInCustProfile}) => {\n\n\tconst bookmarkShareLinkRef = useRef<HTMLInputElement | null>(null);\n\tconst [isSubscribing, setIsSubscribing] = useState(false);\n\tconst [isUnSubscribing, setIsUnSubscribing] = useState(false);\n\n\tconst onClickCopyBtnHandler = () => {\n\t\tnavigator.clipboard.writeText(bookmarkShareLinkRef.current?.value || \"\");\n        toast(\"Collection link copied\", { position: \"top-center\"});\n\t}\n\n\tconst onClickSubscribeHandler = async (e: any) => {\n\t\te.preventDefault()\n\t\tsetIsSubscribing(true);\n\t\tawait onSubscribe(collection.id)\n\t\tsetIsSubscribing(false);\n\t}\n\n\tconst onClickUnSubscribeHandler = async (e: any) => {\n\t\te.preventDefault()\n\t\tsetIsUnSubscribing(true);\n\t\tawait onUnsubscribe(collection.id)\n\t\tsetIsUnSubscribing(false);\n\t}\n\n\treturn (\n\t\t<div className={classes[\"search-profile\"]}>\n\t\t\t<div className={classes[\"search-profile__header\"]}>\n\t\t\t\t<div className={classes[\"search-profile__header-left\"]}>\n\t\t\t\t\t<div className={classes[\"search-profile__header-avatar\"]}>\n\t\t\t\t\t\t<Avatar size=\"100%\" variant=\"beam\" name={`${customer.firstName} ${customer.lastName}`} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3 className={classes[\"search-profile__header-name\"]}>{`${customer.firstName} ${customer.lastName} ${isCurrentLoggedInCustProfile ? '(Me)' : ''}`}</h3>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"search-profile__header-right\"]}>\n\t\t\t\t\t{!(isSignedIn && isCollectionSubscribed) && <button disabled={isSubscribing} onClick={onClickSubscribeHandler} className={classes[\"search-profile__header-subscribe-btn\"]}>Subscribe</button>}\n\t\t\t\t\t{isSignedIn && isCollectionSubscribed && <button disabled={isUnSubscribing} onClick={onClickUnSubscribeHandler} className={classes[\"search-profile__header-subscribe-btn\"]}>UnSubscribe</button>}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-profile__body\"]}>\n\t\t\t\t<p className={classes[\"search-profile__body-desc\"]}>{collection.desc}</p>\n\t\t\t\t<div className={classes[\"search-profile__body-bookmark\"]}>\n\t\t\t\t\t<p className={classes[\"search-profile__body-bookmark-title\"]}>Share this bookmark</p>\n\t\t\t\t\t<div className={classes[\"search-profile__body-share-bookmark-box\"]}>\n\t\t\t\t\t\t<input ref={bookmarkShareLinkRef} readOnly className={classes[\"search-profile__body-share-bookmark-link\"]} type=\"text\" value={`${process.env.NEXT_PUBLIC_BASE_URL}/collection/bookmark/${collection.id}`} />\n\t\t\t\t\t\t<span onClick={onClickCopyBtnHandler} className={classes[\"search-profile__body-share-bookmark-btn\"]}>Copy</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"search-profile__body-feedback-container\"]}>\n\t\t\t\t\t<a href=\"https://airtable.com/shr3QnQbBhWmIKv8p\" target=\"__blank\" className={classes[\"search-profile__body-feedback-txt\"]} >send us your feedback <VscFeedback /></a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default SearchPageProfile;"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchResultItem.module.scss",
    "content": ".search-result-item {\n\tborder-bottom: 1px solid #CED7E3;\n\tpadding-bottom: 15px;\n\tmargin-bottom: 10px;\n\tword-wrap: break-word;\n\n\t&__title-link {\n\t\tfont-size: 22px;\n\t\ttext-decoration: none;\n\t\tmargin-bottom: 2px;\n\t\tcolor: #202A38;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t}\n\n\t&__title-link:hover {\n\t\tcolor: #0FBD86;\n\t}\n\n\t&__meta-info {\n\t\tpadding-bottom: 0px;\n\t\tmargin-bottom: 0px;\n\t\tfont-size: 12px;\n\t\tcolor: #8DA2BE;\n\t}\n\n\t&__site-link {\n\t\tfont-size: 14px;\n\t\tcolor: #536E92;\n\t\ttransition: all .3s;\n\t}\n\n\t&__site-link:hover {\n\t\tcolor: #9B5094;\n\t}\n\n\t&__site-desc {\n\t\tcolor: #415572;\n\t\tmargin-top: 5px;\n\t\tmargin-bottom: 3px;\n\t\tpadding-bottom: 0px;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchResultItem.tsx",
    "content": "import moment from 'moment';\nimport { FC } from 'react';\nimport classes from './SearchResultItem.module.scss';\n\ninterface SearchResultItemProps {\n\ttitle: string;\n\turl: string;\n\tsummary: string;\n\tcreatedAt: string;\n}\n\nconst SearchResultItem: FC<SearchResultItemProps> = (props) => {\n\tconst { title, url, summary, createdAt } = props;\n\treturn (\n\t\t<div className={classes[\"search-result-item\"]}>\n\t\t\t<h3 className={classes['search-result-item__title']}><a className={classes[\"search-result-item__title-link\"]} rel=\"nofollow\" href={url}>{title}</a></h3>\n\t\t\t<p className={classes['search-result-item__meta-info']}>Updated {moment(createdAt).fromNow()}</p>\n\t\t\t<p className={classes['search-result-item__site-desc']}>{summary.length > 255 ? summary.substring(0, 255)+ '...' : summary}</p>\n\t\t\t<a rel=\"nofollow\" className={classes['search-result-item__site-link']} href={url}>{url}</a>\n\t\t</div>\n\t);\n}\n\nexport default SearchResultItem;"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchResults.module.scss",
    "content": ".search-result {\n\n\t&__results {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__item {\n\t\tmargin-bottom: 25px;\n\t}\n\n\t&__header-info-desc {\n\t\tcolor: #536E92;\n\t}\n\n\t&__pagination {\n\t\tmargin-top: 15px;\n\t\tdisplay: flex;\n\t\tgap: 10px;\n\t}\n\n\t&__pagination-link {\n\t\tfont-size: 14px;\n\t\ttext-decoration: none;\n\t\tbackground: #EFF2F6;\n\t\tcolor: #202A38;\n\t\tpadding: 5px;\n\t\ttransition: all .3s;\n\t\tborder-radius: 3px;\n\t}\n\n\t&__pagination-link:hover {\n\t\tbackground: #CED7E3;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/collection/bookmark/CollectionBookmarks/SearchResults.tsx",
    "content": "import { FC } from \"react\";\nimport { Bookmark } from \"../../../../../store/slices/types/Bookmark\";\nimport SearchResultItem from \"./SearchResultItem\";\nimport classes from './SearchResults.module.scss';\n\ninterface SearchResultsProps {\n\tbookmarks: Bookmark[];\n\thasNext: boolean;\n\thasPrev: boolean;\n\tonClickNextPage: Function;\n\tonClickPrevPage: Function;\n\ttotalRecords: number | null;\n}\n\nconst SearchResults: FC<SearchResultsProps> = (props) => {\n\tconst { bookmarks, hasNext, hasPrev, onClickNextPage, onClickPrevPage, totalRecords } = props;\n\n\tconst onNextPageHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonClickNextPage()\n\t}\n\n\tconst onPrevPageHandler = (e:any) => {\n\t\te.preventDefault();\n\t\tonClickPrevPage()\n\t}\n\n\n\treturn (\n\t\t<div className={classes[\"search-result\"]}>\n\t\t\t<div className={classes[\"search-result__header-info\"]}>\n\t\t\t\t{totalRecords !== null ? <p className={classes[\"search-result__header-info-desc\"]}>Received {totalRecords} results</p> : null}\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-result__results\"]}>\n\t\t\t\t{bookmarks.map((bookmark, index) => (\n\t\t\t\t<div key={index} className={classes[\"search-result__item\"]}>\n\t\t\t\t\t<SearchResultItem\n\t\t\t\t\t\ttitle={bookmark.title}\n\t\t\t\t\t\turl={bookmark.url}\n\t\t\t\t\t\tsummary={bookmark.summary || bookmark.description || \"\"}\n\t\t\t\t\t\tcreatedAt={bookmark.createdAt}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-result__pagination\"]}>\n\t\t\t\t\t{hasNext && <a onClick={onPrevPageHandler} className={classes[\"search-result__pagination-link\"]} href=\"#\">Previous</a>}\n\t\t\t\t\t{hasPrev && <a onClick={onNextPageHandler} className={classes[\"search-result__pagination-link\"]} href=\"#\">Next</a>}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default SearchResults;"
  },
  {
    "path": "aquila/view/components/pages/explore/Explore.module.scss",
    "content": ".explore {\n\t// width: 250px;\n\tpadding: 20px 15px;\n\tborder-radius: 3px;\n\tborder: 1px solid #ddd;\n\n\t&__header {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tmargin-bottom: 20px;\n\t\tpadding-bottom: 20px;\n\t\tborder-bottom: 2px solid #ddd;\n\t}\n\n\t&__header-title {\n\t\tcolor: #202A38;\n\t\tfont-size: 22px;\n\t\tfont-weight: 500;\n\t\ttext-decoration: none;\n\t\tmargin: 0px;\n\t}\n\n\n\t&__header-title:hover {\n\t\tcolor: #0FBD86;\n\t}\n\n\t&__header-avatar {\n\t\tmargin-right: 10px;\n\t}\n\n\t&__content-desc {\n\t\tcolor: #415572;\n\t\tfont-size: 14px;\n\t}\n\n}\n\n// @media only screen and (max-width: 1200px) {\n// \t.explore {\n// \t\twidth: 200px;\n// \t}\t\n// }\n\n// @media only screen and (max-width: 992px) {\n// \t.explore {\n// \t\twidth: 225px;\n// \t}\t\n// }\n\n// @media only screen and (max-width: 992px) {\n// \t.explore {\n// \t\twidth: 250px;\n// \t}\t\n// }"
  },
  {
    "path": "aquila/view/components/pages/explore/Explore.tsx",
    "content": "import Avatar from \"boring-avatars\";\nimport Link from \"next/link\";\nimport { FC } from \"react\";\nimport { Collection } from \"../../../store/slices/types/Collection\";\n\nimport classes from \"./Explore.module.scss\";\n\ninterface ExploreProps {\n\tcollection: Collection\n}\n\nconst Explore: FC<ExploreProps> = (props) => {\n\treturn (\n\t\t<div className={classes.explore}>\n\t\t\t<div className={classes.explore__header}>\n\t\t\t\t<div className={classes[\"explore__header-avatar\"]}>\n\t\t\t\t\t<Avatar name={`${props.collection.customer?.firstName} ${props.collection.customer?.lastName}`} />\n\t\t\t\t</div>\n\t\t\t\t<Link href={`/collection/bookmark/${props.collection.id}`}>\n\t\t\t\t\t<a className={classes[\"explore__header-title\"]}>{`${props.collection.customer?.firstName} ${props.collection.customer?.lastName}`}</a>\n\t\t\t\t</Link>\n\t\t\t</div>\n\t\t\t<div className={classes[\"explore__content\"]}>\n\t\t\t\t<p className={classes[\"explore__content-desc\"]}>{props.collection.desc}</p>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default Explore;"
  },
  {
    "path": "aquila/view/components/pages/explore/ExploreCategoryItem.module.scss",
    "content": ".explore-category-item {\n\tmargin-top: 15px;\n\n\t&__title {\n\t\tmargin-bottom: 20px;\n\t\tfont-size: 24px;\n\t}\n\n\t&__explore-list {\n\t\tdisplay: grid;\n\t\tgrid-template-columns: repeat(4, 1fr);\n\t\tjustify-items: center;\n\t\tgap: 30px;\n\t}\n}\n\n@media only  screen and (max-width: 992px)  {\n\t.explore-category-item {\n\t\t&__explore-list {\n\t\t\tgrid-template-columns: repeat(3, 1fr);\n\t\t}\n\t}\n}\n\n\n@media only  screen and (max-width: 768px)  {\n\t.explore-category-item {\n\t\t&__explore-list {\n\t\t\tgrid-template-columns: repeat(2, 1fr);\n\t\t}\n\t}\n}\n\n@media only  screen and (max-width: 576px)  {\n\t.explore-category-item {\n\t\t&__explore-list {\n\t\t\tgrid-template-columns: 1fr;\n\t\t}\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/explore/ExploreCategoryItem.tsx",
    "content": "import { FC } from \"react\";\nimport { Collection } from \"../../../store/slices/types/Collection\";\nimport Explore from \"./Explore\";\n\nimport classes from './ExploreCategoryItem.module.scss';\n\ninterface ExploreItemProps {\n\tcollections: Collection[];\n\ttitle: string;\n}\n\nconst ExploreItem: FC<ExploreItemProps> = (props) => {\n\treturn (\n\t\t<div className={classes[\"explore-category-item\"]}>\n\t\t\t<h2 className={classes[\"explore-category-item__title\"]}>{props.title}</h2>\n\t\t\t<div className={classes[\"explore-category-item__explore-list\"]}>\n\t\t\t\t{props.collections.map((item, index) => {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div key={index} className={classes[\"explore-category-item__explore-list-item\"]}>\n\t\t\t\t\t\t\t<Explore collection={item} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default ExploreItem;"
  },
  {
    "path": "aquila/view/components/pages/explore/ExploreCategoryList.module.scss",
    "content": ".explore-category-list {\n\t&__item {\n\t\tmargin-bottom: 50px;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/explore/ExploreCategoryList.tsx",
    "content": "import { FC } from \"react\";\nimport { AppState } from \"../../../store\";\nimport ExploreCategoryItem from \"./ExploreCategoryItem\";\n\nimport classes from './ExploreCategoryList.module.scss';\n\ninterface ExploreCategoryListProps {\n\tfeaturedCollectionsState: AppState[\"getFeaturedCollections\"];\n\tpublicCollectionsState: AppState[\"getAllPublicCollections\"];\n}\n\nconst ExploreCategoryList: FC<ExploreCategoryListProps> = (props) => {\n\treturn (\n\t\t<div className={classes[\"explore-category-list\"]}>\n\t\t\t{props.featuredCollectionsState.collections &&\n\t\t\t<div className={classes[\"explore-category-list__item\"]}>\n\t\t\t\t<ExploreCategoryItem title=\"Featured\" collections={props.featuredCollectionsState.collections} />\n\t\t\t</div>\n\t\t\t}\n\t\t\t{props.publicCollectionsState.collections &&\n\t\t\t<div className={classes[\"explore-category-list__item\"]}>\n\t\t\t\t<ExploreCategoryItem title=\"Public\" collections={props.publicCollectionsState.collections} />\n\t\t\t</div>\n\t\t\t}\n\t\t\t{/* <div className={classes[\"explore-category-list__item\"]}>\n\t\t\t\t<ExploreCategoryItem />\n\t\t\t</div> */}\n\t\t</div>\n\t);\n}\n\nexport default ExploreCategoryList;"
  },
  {
    "path": "aquila/view/components/pages/explore/ExplorePageWrapper.tsx",
    "content": "import { FC } from \"react\";\nimport { AppState } from \"../../../store\";\nimport MainLayout from \"../../layout/main/MainLayout\";\nimport Container from \"../../ui/layout/Container\";\nimport ExploreCategoryList from \"./ExploreCategoryList\";\n\ninterface ExplorePageWrapperProps {\n    featuredCollectionsState: AppState[\"getFeaturedCollections\"];\n    publicCollectionsState: AppState[\"getAllPublicCollections\"];\n}\n\nconst ExplorePageWrapper: FC<ExplorePageWrapperProps> = (props) => {\n    return (\n        <MainLayout>\n            <Container>\n                <ExploreCategoryList publicCollectionsState={props.publicCollectionsState} featuredCollectionsState={props.featuredCollectionsState} />\n            </Container>\n        </MainLayout>\n    )\n}\n\nexport default ExplorePageWrapper;"
  },
  {
    "path": "aquila/view/components/pages/home/HomePageWrapper.module.scss",
    "content": ".home-page {\n    display: flex;\n    gap: 50px;\n\n    &__search-area {\n        flex-basis: 800px;    \n    }\n\n    &__search-bar {\n        margin-top: 20px;\n        width: 600px;\n    }\n\n    &__search-results {\n        margin-top: 30px;\n    }\n\n    &__sidebar {\n        padding-top: 20vh;\n        flex: 1 1 0;\n    }\n    \n    &__sidebar-close {\n        display: none;\n    }\n}\n\n@media only screen and (max-width: 1200px) {\n    .home-page {\n        gap: 20px;\n    }\n}\n\n@media only screen and (max-width: 992px) {\n   .home-page {\n    flex-direction: column;\n\n    &__sidebar {\n        position: fixed;\n        bottom: 0px;\n        left: 0px;\n        right: 0px;\n        padding-top: 0px;\n    }\n\n    &__search-bar {\n        width: 80%;\n    }\n\n    &__sidebar--close {\n        display: none;\n    }\n\n    &__sidebar-close {\n        display: block;\n        position: absolute;\n        background: none;\n        font-size: 18px;\n        outline: none;\n        border: none;\n        top: 25px;\n        right: 5px;\n        cursor: pointer;\n    }\n\n   } \n}"
  },
  {
    "path": "aquila/view/components/pages/home/HomePageWrapper.tsx",
    "content": "import { FC, useEffect, useState } from \"react\";\nimport { Oval } from 'react-loader-spinner';\nimport { FiX } from 'react-icons/fi';\n\nimport { AppState } from \"../../../store\";\nimport { Collection } from \"../../../store/slices/types/Collection\";\nimport { Customer } from \"../../../store/slices/types/Customer\";\nimport MainLayout from \"../../layout/main/MainLayout\"\nimport Container from \"../../ui/layout/Container\";\nimport classes from \"./HomePageWrapper.module.scss\";\nimport SearchBar from \"./SearchBar\";\nimport SearchPageProfile from \"./SearchPageProfile\";\nimport SearchResults from \"./SearchResults\";\n\ninterface HomePageWrapperProps {\n    customer: Customer | null;\n    collection: Collection | null;\n    bookmarksState: AppState[\"getLoggedInCustBookmarksByCollectionId\"];\n    onSearch: Function;\n    onClickNextPage: Function;\n    onClickPrevPage: Function;\n    isCollectionSubscribed: boolean | null;\n    onSubscribe: Function;\n    onUnsubscribe: Function;\n}\n\nconst HomePageWrapper: FC<HomePageWrapperProps> = (props) => {\n    const { collection, customer, bookmarksState, onSearch, onClickNextPage, onClickPrevPage, onSubscribe, onUnsubscribe, isCollectionSubscribed } = props;\n    const [hasNext, setHasNext] = useState(false);\n    const [hasPrev, setHasPrev] = useState(false);\n    const [showSidebar, setShowSidebar] = useState(true);\n    \n    useEffect(() => {\n        if(bookmarksState.currentPage && bookmarksState.totalPages) {\n            if(bookmarksState.currentPage < bookmarksState.totalPages) {\n                setHasNext(true);\n            }else {\n                setHasNext(false);\n            }\n            if(bookmarksState.currentPage > 1) {\n                setHasPrev(true)\n            }else {\n                setHasPrev(false)\n            }\n        }\n    }, [bookmarksState])\n\n    return (\n        <MainLayout>\n            <Container>\n                <div className={classes[\"home-page\"]}>\n                    <section className={classes[\"home-page__search-area\"]}>\n                        <div className={classes[\"home-page__search-bar\"]}>\n                            <SearchBar onSearch={onSearch} />\n                        </div>\n                        <div className={classes[\"home-page__search-results\"]}>\n                            {bookmarksState.status === \"pending\" && <Oval height={30} width=\"100%\" strokeWidth={5} color=\"#0FBD86\" strokeWidthSecondary={5} />}\n                            {bookmarksState.bookmarks && <SearchResults \n                                totalRecords={bookmarksState.totalRecords}\n                                onClickNextPage={onClickNextPage}\n                                onClickPrevPage={onClickPrevPage}\n                                hasPrev={hasNext}\n                                hasNext={hasPrev}\n                                bookmarks={bookmarksState.bookmarks}\n                                />}\n                        </div>\n                    </section>\n                    <section className={`${classes[\"home-page__sidebar\"]} ${!showSidebar? classes[\"home-page__sidebar--close\"] : ''}`}>\n\t\t\t           <button onClick={() => setShowSidebar(false)} className={classes[\"home-page__sidebar-close\"]}><FiX /></button>\n                       {collection && customer && <SearchPageProfile \n                        collection={collection}\n                        customer={customer}\n                        onSubscribe={onSubscribe}\n                        onUnsubscribe={onUnsubscribe}\n                        isCollectionSubscribed={isCollectionSubscribed}\n                       />}\n                    </section>\n                </div>\n            </Container>\n        </MainLayout>\n    )\n}\n\nexport default HomePageWrapper;"
  },
  {
    "path": "aquila/view/components/pages/home/SearchBar.module.scss",
    "content": ".search-bar {\n\tpadding: 10px 5px;\n\n\t&__container {\n\t\tdisplay: flex;\n\t\tborder-bottom: 1px solid #AEBCD1;\n\t\tpadding: 10px 5px;\n\t}\n\n\t&__input {\n\t\tmargin-right: 10px;\n\t\twidth: 100%;\n\t\tborder: none;\n\t\toutline: none;\n\t}\n\n\t&__input::placeholder {\n\t\tcolor: #AEBCD1;\n\t}\n\n\t&__btn {\n\t\tborder: none;\n\t\toutline: none;\n\t\tbackground: transparent;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/home/SearchBar.tsx",
    "content": "import { FC, useRef } from 'react';\nimport { IoSearch } from 'react-icons/io5';\nimport classes from './SearchBar.module.scss';\n\ninterface SearchBarProps {\n\tonSearch: Function\n}\n\nconst SearchBar: FC<SearchBarProps> = (props) => {\n\tconst { onSearch } = props;\n\tconst searchValueRef = useRef<HTMLInputElement>(null);\n\n\tconst onSubmitHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonSearch(searchValueRef.current?.value)\n\t}\n\n\treturn (\n\t\t<div className={classes[\"search-bar\"]}>\n\t\t\t<form className={classes[\"search-bar__container\"]} onSubmit={onSubmitHandler}>\n\t\t\t\t<input ref={searchValueRef} className={classes[\"search-bar__input\"]} placeholder='Search Bookmarks...' type=\"text\" />\n\t\t\t\t<button className={classes[\"search-bar__btn\"]}>\n\t\t\t\t\t<IoSearch />\n\t\t\t\t</button>\n\t\t\t</form>\n\t\t</div>\n\t)\n}\n\nexport default SearchBar;"
  },
  {
    "path": "aquila/view/components/pages/home/SearchPageProfile.module.scss",
    "content": ".search-profile {\n\tpadding: 15px;\n\tmargin-top: 20px;\n\tborder: 1px solid #CED7E3;\n\tborder-radius: 3px;\n\tbackground: #fff;\n\n\t&__header {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\t\tmargin-bottom: 10px;\n\t}\n\n\t&__header-subscribe-btn {\n\t\tmargin-top: 5px;\n\t\tbackground: transparent;\n\t\tborder: 1px solid #8DA2BE;\n\t\toutline: none;\n\t\tborder-radius: 3px;\n\t\tcolor: #2E3D51;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t}\n\n\t&__header-subscribe-btn:hover {\n\t\tcolor: #0FBD86;\n\t\tborder-color: #0FBD86;\n\t}\n\n\t&__header-avatar {\n\t\twidth: 80px;\n\t}\n\n\t&__header-left {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 10px;\n\t}\n\n\t&__header-name {\n\t\tcolor: #202A38;\n\t\tfont-size: 25px;\n\t}\n\n\t&__body-desc {\n\t\tcolor: #415572;\n\t\tmargin: 0px;\n\t\tfont-size: 14px;\n\t\tmargin-bottom: 20px;\n\t}\n\n\t&__body-bookmark-title {\n\t\tfont-size: 14px;\n\t\tmargin-bottom: 5px;\n\t\tcolor: #415572;\n\t}\n\n\t&__body-share-bookmark-box {\n\t\toverflow: hidden;\n\t\tbackground: #EFF2F6;\n\t\tposition: relative;\n\t\tbox-sizing:border-box;\n\t\tmargin: 0px auto;\n\t\tpadding: 3px 4px;\n\t\tborder-radius: 3px;\n\t}\n\n\t&__body-share-bookmark-btn {\n\t\tposition: absolute;\n\t\tright: 0px;\n\t\ttop: 0px;\n\t\tbottom: 0px;\n\t\tfont-size: 12px;\n\t\tpadding: 5px;\n\t\tcolor: #fff;\n\t\tbackground: #3ABFF8;\n\t\tborder-radius: 3px;\n\t\tcursor: pointer;\n\t\ttransition: all .3s;\n\t}\n\n\t&__body-share-bookmark-btn:hover {\n\t\tbackground: #089DDE;\n\t}\n\n\t&__body-share-bookmark-link {\n\t\twidth: 100%;\n\t\tmargin: 0px;\n\t\tborder: none;\n\t\toutline: none;\n\t\tbackground: transparent;\n\t\tfont-size: 12px;\n\t\tcolor: #415572;\n\t}\n\n\t&__body-feedback-container {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__body-feedback-txt {\n\t\tcolor: #097654;\n\t\ttext-decoration: none;\n\t\tfont-size: 14px;\n\t\ttransition: all .3s;\n\t}\n\n\t&__body-feedback-txt:hover {\n\t\tcolor: #0FBD86;\n\t}\n}\n\n@media only screen and (max-width: 992px) {\n\t.search-profile {\n\t\tpadding-top: 25px;\n\n\t\t&__header-left {\n\t\t\tdisplay: flex;\n\t\t\tflex-direction: row;\n\t\t\talign-items: center;\n\t\t\tgap: 10px;\n\t\t}\n\n\t\t&__header-avatar {\n\t\t\twidth: 40px;\n\t\t}\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/home/SearchPageProfile.tsx",
    "content": "import { VscFeedback } from 'react-icons/vsc';\nimport { toast } from 'react-toastify';\nimport Avatar from \"boring-avatars\";\n\nimport classes from './SearchPageProfile.module.scss';\nimport { Customer } from '../../../store/slices/types/Customer';\nimport { FC, useRef, useState } from 'react';\nimport { Collection } from '../../../store/slices/types/Collection';\n\ninterface SearchPageProfileProps {\n\tcustomer: Customer;\n\tcollection: Collection;\n\tonSubscribe: Function;\n\tonUnsubscribe: Function;\n\tisCollectionSubscribed: boolean | null;\n}\n\nconst SearchPageProfile: FC<SearchPageProfileProps> = ({ customer, collection, onSubscribe, onUnsubscribe, isCollectionSubscribed }) => {\n\n\tconst bookmarkShareLinkRef = useRef<HTMLInputElement | null>(null);\n\tconst [isSubscribing, setIsSubscribing] = useState(false);\n\tconst [isUnSubscribing, setIsUnSubscribing] = useState(false);\n\n\tconst OnClickCopyBtnHandler = () => {\n\t\tnavigator.clipboard.writeText(bookmarkShareLinkRef.current?.value || \"\");\n        toast(\"Collection link copied\", { position: \"top-center\"});\n\t}\n\n\tconst onClickSubscribeHandler = async (e: any) => {\n\t\te.preventDefault()\n\t\tsetIsSubscribing(true);\n\t\tawait onSubscribe(collection.id)\n\t\tsetIsSubscribing(false);\n\t}\n\n\tconst onClickUnSubscribeHandler = async (e: any) => {\n\t\te.preventDefault()\n\t\tsetIsUnSubscribing(true);\n\t\tawait onUnsubscribe(collection.id)\n\t\tsetIsUnSubscribing(false);\n\t}\n\n\treturn (\n\t\t<div className={classes[\"search-profile\"]}>\n\t\t\t<div className={classes[\"search-profile__header\"]}>\n\t\t\t\t<div className={classes[\"search-profile__header-left\"]}>\n\t\t\t\t\t<div className={classes[\"search-profile__header-avatar\"]}>\n\t\t\t\t\t\t<Avatar size=\"100%\" variant=\"beam\" name={`${customer.firstName} ${customer.lastName}`} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3 className={classes[\"search-profile__header-name\"]}>{`${customer.firstName} ${customer.lastName} (Me)`}</h3>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"search-profile__header-right\"]}>\n\t\t\t\t\t{!isCollectionSubscribed && <button disabled={isSubscribing} onClick={onClickSubscribeHandler} className={classes[\"search-profile__header-subscribe-btn\"]}>Subscribe</button>}\n\t\t\t\t\t{isCollectionSubscribed && <button disabled={isUnSubscribing} onClick={onClickUnSubscribeHandler} className={classes[\"search-profile__header-subscribe-btn\"]}>UnSubscribe</button>}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-profile__body\"]}>\n\t\t\t\t<p className={classes[\"search-profile__body-desc\"]}>{collection.desc}</p>\n\t\t\t\t<div className={classes[\"search-profile__body-bookmark\"]}>\n\t\t\t\t\t<p className={classes[\"search-profile__body-bookmark-title\"]}>Share this bookmark</p>\n\t\t\t\t\t<div className={classes[\"search-profile__body-share-bookmark-box\"]}>\n\t\t\t\t\t\t<input ref={bookmarkShareLinkRef} readOnly className={classes[\"search-profile__body-share-bookmark-link\"]} type=\"text\" value={`${process.env.NEXT_PUBLIC_BASE_URL}/collection/bookmark/${collection.id}`} />\n\t\t\t\t\t\t<span onClick={OnClickCopyBtnHandler} className={classes[\"search-profile__body-share-bookmark-btn\"]}>Copy</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"search-profile__body-feedback-container\"]}>\n\t\t\t\t\t<a href=\"https://airtable.com/shr3QnQbBhWmIKv8p\" target=\"__blank\" className={classes[\"search-profile__body-feedback-txt\"]} >send us your feedback <VscFeedback /></a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default SearchPageProfile;"
  },
  {
    "path": "aquila/view/components/pages/home/SearchResultItem.module.scss",
    "content": ".search-result-item {\n\tborder-bottom: 1px solid #CED7E3;\n\tpadding-bottom: 15px;\n\tmargin-bottom: 10px;\n\tword-wrap: break-word;\n\n\t&__title {\n\t\tmargin-bottom: 2px;\n\t}\n\n\t&__title-link {\n\t\tfont-size: 22px;\n\t\tcolor: #202A38;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t\ttext-decoration: none;\n\t}\n\n\t&__title-link:hover {\n\t\tcolor: #0FBD86;\n\t}\n\n\t&__meta-info {\n\t\tpadding-bottom: 0px;\n\t\tmargin-bottom: 0px;\n\t\tfont-size: 12px;\n\t\tcolor: #8DA2BE;\n\t}\n\n\t&__site-link {\n\t\tfont-size: 14px;\n\t\tcolor: #536E92;\n\t\ttransition: all .3s;\n\t}\n\n\t&__site-link:hover {\n\t\tcolor: #9B5094;\n\t}\n\n\t&__site-desc {\n\t\tcolor: #415572;\n\t\tmargin-top: 5px;\n\t\tmargin-bottom: 3px;\n\t\tpadding-bottom: 0px;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/home/SearchResultItem.tsx",
    "content": "import { FC } from 'react';\nimport moment from 'moment';\n\nimport classes from './SearchResultItem.module.scss';\n\ninterface SearchResultItemProps {\n\ttitle: string;\n\turl: string;\n\tsummary: string;\n\tcreatedAt: string;\n}\n\nconst SearchResultItem: FC<SearchResultItemProps> = (props) => {\n\tconst { title, url, summary, createdAt } = props;\n\treturn (\n\t\t<div className={classes[\"search-result-item\"]}>\n\t\t\t<h3 className={classes['search-result-item__title']}><a className={classes[\"search-result-item__title-link\"]} href={url} rel=\"nofollow\">{title}</a></h3>\n\t\t\t<p className={classes['search-result-item__meta-info']}>Updated {moment(createdAt).fromNow()}</p>\n\t\t\t<p className={classes['search-result-item__site-desc']}>{summary.length > 255 ? summary.substring(0, 255)+'...' : summary}</p>\n\t\t\t<a rel=\"nofollow\" className={classes['search-result-item__site-link']} href={url}>{url}</a>\n\t\t</div>\n\t);\n}\n\nexport default SearchResultItem;"
  },
  {
    "path": "aquila/view/components/pages/home/SearchResults.module.scss",
    "content": ".search-result {\n\n\t&__results {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__item {\n\t\tmargin-bottom: 25px;\n\t}\n\n\t&__header-info-desc {\n\t\tcolor: #536E92;\n\t}\n\n\t&__pagination {\n\t\tmargin-top: 15px;\n\t\tdisplay: flex;\n\t\tgap: 10px;\n\t}\n\n\t&__pagination-link {\n\t\tfont-size: 14px;\n\t\ttext-decoration: none;\n\t\tbackground: #EFF2F6;\n\t\tcolor: #202A38;\n\t\tpadding: 5px;\n\t\ttransition: all .3s;\n\t\tborder-radius: 3px;\n\t}\n\n\t&__pagination-link:hover {\n\t\tbackground: #CED7E3;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/home/SearchResults.tsx",
    "content": "import { FC } from \"react\";\nimport { Bookmark } from \"../../../store/slices/types/Bookmark\";\nimport SearchResultItem from \"./SearchResultItem\";\nimport classes from './SearchResults.module.scss';\n\ninterface SearchResultsProps {\n\tbookmarks: Bookmark[];\n\thasNext: boolean;\n\thasPrev: boolean;\n\tonClickNextPage: Function;\n\tonClickPrevPage: Function;\n\ttotalRecords: number | null;\n}\n\nconst SearchResults: FC<SearchResultsProps> = (props) => {\n\tconst { bookmarks, hasNext, hasPrev, onClickNextPage, onClickPrevPage, totalRecords } = props;\n\n\tconst onNextPageHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonClickNextPage()\n\t}\n\n\tconst onPrevPageHandler = (e:any) => {\n\t\te.preventDefault();\n\t\tonClickPrevPage()\n\t}\n\n\n\treturn (\n\t\t<div className={classes[\"search-result\"]}>\n\t\t\t<div className={classes[\"search-result__header-info\"]}>\n\t\t\t\t{totalRecords !== null ? <p className={classes[\"search-result__header-info-desc\"]}>Received {totalRecords} results</p>: null}\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-result__results\"]}>\n\t\t\t\t{bookmarks.map((bookmark, index) => (\n\t\t\t\t<div key={index} className={classes[\"search-result__item\"]}>\n\t\t\t\t\t<SearchResultItem\n\t\t\t\t\t\ttitle={bookmark.title}\n\t\t\t\t\t\turl={bookmark.url}\n\t\t\t\t\t\tsummary={bookmark.summary || bookmark.description || \"\"}\n\t\t\t\t\t\tcreatedAt={bookmark.createdAt}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-result__pagination\"]}>\n\t\t\t\t\t{hasNext && <a onClick={onPrevPageHandler} className={classes[\"search-result__pagination-link\"]} href=\"#\">Previous</a>}\n\t\t\t\t\t{hasPrev && <a onClick={onNextPageHandler} className={classes[\"search-result__pagination-link\"]} href=\"#\">Next</a>}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default SearchResults;"
  },
  {
    "path": "aquila/view/components/pages/index/AllControl.module.scss",
    "content": ".all-control {\n    display: flex;\n    margin: auto;\n    max-width: 1280;\n\n    &__img-area {\n        flex-basis: 50%;\n        padding: 50px;\n        box-sizing: border-box;\n    }\n\n    &__text-area {\n        flex-basis: 50%;\n        display: flex;\n        flex-direction: column;\n        justify-content: center;\n        gap: 20px;\n        padding: 50px;\n        box-sizing: border-box;\n    }\n\n    &__title {\n        color: #202A38;\n        font-size: 25px;\n    }\n\n    &__desc {\n        color: #415572;\n        font-size: 20px;\n    }\n\n    &__desc-link {\n        color: #0FBD86;\n        text-decoration: none;\n    }\n}\n\n@media only screen and (max-width: 768px) {\n    .all-control {\n        flex-direction: column-reverse;\n        padding-left: 10px;\n        padding-right: 10px;\n        text-align: center;\n\n        &__title {\n            font-size: 18px;\n        }\n        \n        &__desc {\n            font-size: 16px;\n        }\n\n        &__img-area {\n            width: 80%;\n            margin-left: auto;\n            margin-right: auto;\n        }\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/index/AllControl.tsx",
    "content": "import Image from \"next/image\";\n\nimport classes from \"./AllControl.module.scss\";\nimport AllControlImg from \"../../../public/img/aquila-control.png\";\n\nconst AllControl = () => {\n    return (\n        <div className={classes[\"all-control\"]}>\n            <div className={classes[\"all-control__img-area\"]}>\n                <Image alt=\"All Control\" src={AllControlImg}/>\n            </div>\n            <div className={classes[\"all-control__text-area\"]}>\n                <h3 className={classes[\"all-control__title\"]}>You’ve got all the control</h3>\n                <p className={classes[\"all-control__desc\"]}>nstall a browser extension and you&apos;re ready to go.\nWe&apos;ve made our software <a className={classes[\"all-control__desc-link\"]} href=\"\" target=\"__blank\">Open Source</a> for public scrutiny &amp; trust</p>\n            </div>\n        </div>\n    )\n}\n\nexport default AllControl;"
  },
  {
    "path": "aquila/view/components/pages/index/Discover.module.scss",
    "content": ".discover {\n    margin: auto;\n    margin-top: 80px;\n    display: flex;\n    max-width: 1280px;\n    &__text-area {\n        flex-basis: 50%;\n        padding: 50px;\n        box-sizing: border-box;\n        display: flex;\n        flex-direction: column;\n        justify-content: center;\n        gap: 20px;\n    }\n\n    &__title {\n        font-size: 25px;\n        color: #202A38;\n    }\n\n    &__desc {\n        font-size: 20px;\n        color: #415572;\n    }\n\n    &__img-area {\n        flex-basis: 50%;\n    }    \n}\n\n\n@media only screen and (max-width: 768px) {\n    .discover {\n        flex-direction: column;\n        padding-left: 10px;\n        padding-right: 10px;\n        text-align: center;\n\n        &__title {\n            font-size: 18px;\n        }\n        \n        &__desc {\n            font-size: 16px;\n        }\n\n        &__img-area {\n            width: 80%;\n            margin-left: auto;\n            margin-right: auto;\n        }\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/index/Discover.tsx",
    "content": "import Image from 'next/image';\nimport classes from './Discover.module.scss';\n\nimport DiscoverImg from '../../../public/img/aquila-discover.png';\n\nconst Discover = () => {\n    return (\n        <div className={classes.discover} >\n            <div className={classes[\"discover__text-area\"]}>\n                <h4 className={classes[\"discover__title\"]}>Discover new topics and people</h4>\n                <p className={classes[\"discover__desc\"]}>Become a fan of your favorite curators.\nMaintain a pool of specialists and create a search engine out of it.</p>\n            </div>\n            <div className={classes[\"discover__img-area\"]}>\n                <Image alt=\"Discover new Topics in Aquila\" src={DiscoverImg} />\n            </div>\n        </div>\n    )\n}\n\nexport default Discover;"
  },
  {
    "path": "aquila/view/components/pages/index/Hero.module.scss",
    "content": ".hero {\n    text-align: center;\n\n    &__text-area {\n        margin-top: 50px;\n    }\n\n    &__text-main-title {\n        font-size: 70px;\n        color: #202A38;\n    }\n\n    &__text-main-desc {\n        font-size: 20px;\n        margin: auto;\n        margin-top: 30px;\n        max-width: 600px;\n        color: #536E92;\n    }\n\n    &__btn-area {\n        margin-top: 50px;\n        display: flex;\n        justify-content: center;\n        gap: 10px;\n    }\n    \n    &__img-area {\n        margin: auto;\n        margin-top: 60px;\n        max-width: 900px;\n    }\n\n    &__btn {\n        border: none;\n        background: #CED7E3;\n        padding: 10px;\n        border-radius: 3px;\n        color: #fff;\n    }\n\n    &__btn--red {\n        background: #F87272;\n    }\n\n    &__btn--blue {\n        background: #3ABFF8;\n    }\n\n    &__footer-text {\n        margin: auto;\n        margin-top: 50px;\n        max-width: 600px;\n        border-top: 1px solid #ddd;\n        border-bottom: 1px solid #ddd;\n        padding: 40px 0px;\n        font-size: 20px;\n        color: #2E3D51;\n    }\n}\n\n@media only screen and (max-width: 768px) {\n    .hero {\n        &__text-main-title {\n            font-size: 45px;\n        }\n\n        &__text-main-desc {\n            font-size: 18px;\n            line-height: 30px;\n        }\n    }\n}\n\n@media only screen and (max-width: 576px) {\n    .hero {\n        padding-left: 10px;\n        padding-right: 10px;\n\n        &__text-main-title {\n            font-size: 35px;\n        }\n\n        &__text-main-desc {\n            font-size: 16px;\n            line-height: 24px;\n        }\n\n        &__footer-text {\n            font-size: 18px;\n        }\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/index/Hero.tsx",
    "content": "import Image from 'next/image';\nimport classes from './Hero.module.scss';\n\nimport HeroImg from '../../../public/img/aquila-hero.png';\n\nconst Hero = () => {\n    return (\n        <div className={classes.hero}>\n            <div className={classes[\"hero__text-area\"]}>\n                <h2 className={classes[\"hero__text-main-title\"]}>Human curated search engine</h2>\n                <p className={classes[\"hero__text-main-desc\"]}>Build a curated list of websites, aggregate into searchable pool of ideas.\nWorks with paywall-protected websites.</p>\n            </div>\n            <div className={classes[\"hero__btn-area\"]}>\n                    <button className={`${classes[\"hero__btn\"]} ${classes[\"hero__btn--blue\"]}`}>Sign up with Telegram</button>\n                    <button className={`${classes[\"hero__btn\"]} ${classes[\"hero__btn--red\"]}`}>Sign up with Email</button>\n            </div>\n            <div className={classes[\"hero__img-area\"]}>\n                <Image src={HeroImg} alt=\"Hero Image\" objectFit=\"fill\"  />\n            </div>\n            <div className={classes[\"hero__footer-text\"]}>\n                <p>Aquila offers you a familiar search experience.\nEasily organize and share your curated list with anybody.</p>\n            </div>\n        </div>\n    )\n}\n\nexport default Hero;"
  },
  {
    "path": "aquila/view/components/pages/index/IndexPageWrapper.tsx",
    "content": "import MainLayout from \"../../layout/main/MainLayout\";\nimport AllControl from \"./AllControl\";\nimport Discover from \"./Discover\";\nimport Hero from \"./Hero\";\nimport Story from \"./Story\";\n\nconst IndexPageWrapper = () => {\n\treturn (\n\t\t<MainLayout headerBorder={false}>\n\t\t\t<Hero />\n\t\t\t<Discover />\n\t\t\t<AllControl />\n\t\t\t<Story />\n\t\t</MainLayout>\n\t)\n}\n\nexport default IndexPageWrapper;"
  },
  {
    "path": "aquila/view/components/pages/index/Story.module.scss",
    "content": ".story {\n    background: #EFF2F6;\n    padding: 100px 0px;\n    text-align: center;\n\n    &__title {\n        font-size: 24px;\n        color: #202A38;\n    }\n\n    &__link {\n        text-decoration: none;\n        color: #0FBD86;\n    }\n}\n\n\n@media only screen and (max-width: 768px) {\n    .story {\n        padding: 50px 10px;\n\n        &__title {\n            font-size: 18px;\n        }\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/index/Story.tsx",
    "content": "import classes from './Story.module.scss';\n\nconst Story = () => {\n    return (\n        <div className={classes.story}>\n            <h4 className={classes[\"story__title\"]}>Interested to read the <a className={classes[\"story__link\"]} href=\"\">story of Aquila Network</a>?</h4>\n        </div>\n    )\n}\n\nexport default Story;"
  },
  {
    "path": "aquila/view/components/pages/signIn/SignInForm.module.scss",
    "content": ".login-box {\n\n\t&__header {\n\t\tmargin: 25px 0px;\n\t}\n\n\t&__title {\n\t\tfont-size: 20px;\n\t\tcolor: #415572;\n\t\ttext-align: center;\n\t}\n\n\t&__form-item {\n\t\tmargin-bottom: 12px;\n\t}\n\n\t&__form-item--btn-container {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__form-label {\n\t\tdisplay: block;\n\t\tcolor: hsl(214, 28%, 45%);\n\t\tmargin-bottom: 4px;\n\t}\n\n\t&__form-control {\n\t\tcolor: #415572;\n\t\twidth: 100%;\n\t\tpadding: 8px 5px;\n\t\tborder: 1px solid #536E92;\n\t\tborder-radius: 3px;\n\t\tbox-sizing: border-box;\n\t}\n\n\t&__form-btn {\n\t\twidth: 100%;\n\t\tbackground: none;\n\t\toutline: none;\n\t\tborder: 1px solid #415572;\n\t\tcolor: #415572;\n\t\tpadding: 6px 0px;\n\t\tborder-radius: 3px;\n\t\ttransition: all .3s;\n\t}\n\n\t&__form-btn:hover {\n\t\tcolor: #0FBD86;\n\t\tborder: 1px solid #0FBD86;\n\t}\n\n\t&__form-btn:disabled {\n\t\tcolor: #CED7E3;\n\t\tborder-color: #CED7E3;\n\t}\n\n\t&__footer-text {\n\t\tfont-size: 12px;\n\t}\n\n\t&__footer-link {\n\t\tcolor: #0FBD86;\n\t\ttext-decoration: none;\n\t}\n\n\t&__footer-link:hover {\n\t\tcolor: #0DA575;\n\t}\n\n}"
  },
  {
    "path": "aquila/view/components/pages/signIn/SignInForm.tsx",
    "content": "import Link from 'next/link';\nimport { useRef, useState } from 'react';\nimport classes from './SignInForm.module.scss';\n\nconst SignInForm = (props:any) => {\n\tconst secretKeyRef = useRef<HTMLInputElement>(null);\n\tconst [isLoading, setIsLoading] = useState(false);\n\n\tconst submitHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tsetIsLoading(true);\n\t\tprops.onSignIn(secretKeyRef.current?.value)\n\t\t\t.then(() => {\n\t\t\t\tsetIsLoading(false);\n\t\t\t})\n\t}\n\n\treturn (\n\t\t<div className={classes[\"login-box\"]}>\n\t\t\t<form onSubmit={submitHandler}>\n\t\t\t\t<div className={classes[\"login-box__header\"]}>\n\t\t\t\t\t<h3 className={classes[\"login-box__title\"]}>Login</h3>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"login-box__form\"]}>\n\t\t\t\t\t<div className={classes[\"login-box__form-item\"]}>\n\t\t\t\t\t\t<label className={classes[\"login-box__form-label\"]}>Secret key</label>\n\t\t\t\t\t\t<input ref={secretKeyRef} className={classes[\"login-box__form-control\"]} type=\"text\" placeholder=\"Enter Secret key\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className={`${classes[\"login-box__form-item\"]} ${classes[\"login-box__form-item--btn-container\"]}`}>\n\t\t\t\t\t\t<button disabled={isLoading} type=\"submit\" className={classes[\"login-box__form-btn\"]}>Login</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"login-box__footer\"]}>\n\t\t\t\t\t<p className={classes[\"login-box__footer-text\"]}>\n\t\t\t\t\t\t<span>Don&apos;t have an account?  </span>\n\t\t\t\t\t\t<Link href=\"/sign-up\"><a className={classes[\"login-box__footer-link\"]}>Generate an account</a></Link>\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t</div>\n\t)\n}\n\nexport default SignInForm;"
  },
  {
    "path": "aquila/view/components/pages/signIn/SignInPageWrapper.tsx",
    "content": "import { FC } from \"react\";\nimport BoxCenterLayout from \"../../layout/boxCenter/BoxCenterLayout\";\nimport SignInForm from \"./SignInForm\";\n\ninterface SignInPageWrapperProps {\n\tonSignIn: Function\n}\n\nconst SignInPageWrapper: FC<SignInPageWrapperProps> = (props) => {\n\treturn (\n\t\t<BoxCenterLayout>\n\t\t\t<SignInForm onSignIn={props.onSignIn} />\n\t\t</BoxCenterLayout>\n\t)\n}\n\nexport default SignInPageWrapper;\n"
  },
  {
    "path": "aquila/view/components/pages/signUp/SecretKey.module.scss",
    "content": ".secret-key {\n    padding: 20px 0px;\n    text-align: center;\n\n    &__header {\n        padding: 5px 0px;\n    }\n\n    &__header-title {\n        font-size: 20px;\n        color: #2E3D51;\n    }\n\n    &__body {\n        margin-top: 20px;\n    }\n\n    &__body-title {\n       font-size: 16px; \n       color: #536E92;\n    }\n\n    &__key {\n        margin-top: 10px;\n        background-color: #EFF2F6;\n        font-size: 12px;\n        border-radius: 3px;\n        display: flex;\n        align-items: center;\n        justify-content: space-between;\n    }\n\n\n    &__key-text {\n        padding: 10px 5px;\n        color: #536E92;\n    }\n\n    &__copy-key {\n        padding: 0px 10px;\n        align-self: stretch;\n        align-content: center;\n        font-size: 10px;\n        border-radius: 5px;\n        background: #3ABFF8;\n        font-size: 18px;\n        display: flex;\n        align-items: center;\n        color: #fff;\n        cursor: pointer;\n        transition: all .3s;\n    }\n\n    &__copy-key:hover {\n        background: #089DDE;\n    }\n\n    &__info-text {\n        background-color:#E7FDF6;\n        font-size: 14px;\n        margin-top: 25px;\n        padding: 10px 5px;\n        border-radius: 3px;\n        color: #064732;\n    }\n\n    &__footer {\n        margin-top: 25px;\n    }\n\n    &__footer-btn {\n        text-decoration: none;\n        color: #202A38;\n        display: block;\n        border: 1px solid #202A38;\n        border-radius: 3px;\n        padding: 6px 5px;\n    }\n\n    &__footer-btn:hover {\n\t\tcolor: #0FBD86;\n\t\tborder: 1px solid #0FBD86;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/signUp/SecretKey.tsx",
    "content": "import Link from \"next/link\";\nimport { FC } from \"react\";\nimport { CgCopy } from 'react-icons/cg';\nimport { toast } from 'react-toastify';\n\nimport { AppState } from \"../../../store\";\n\nimport classes from './SecretKey.module.scss';\n\ninterface SecretKeyProps {\n    signUpState: AppState[\"signUp\"];\n}\n\nconst SecretKey: FC<SecretKeyProps> = ({ signUpState }) => {\n    const copyToClipboardHandler = () => {\n        navigator.clipboard.writeText(signUpState.customer?.secretKey || \"\");\n        toast(\"Content copied\", { position: \"top-center\"});\n    }\n\n    return (\n        <div className={classes[\"secret-key\"]}>\n            <div className={classes[\"secret-key__header\"]}>\n                <h3 className={classes[\"secret-key__header-title\"]}>Your Account has been generated</h3>\n            </div>\n            <div className={classes[\"secret-key__body\"]}>\n                <h2 className={classes[\"secret-key__body-title\"]}>Your Secret key</h2>\n                <p className={classes[\"secret-key__key\"]}>\n                    <span className={classes[\"secret-key__key-text\"]}>{signUpState.customer?.secretKey}</span>\n                    <span title=\"Copy to clipboard\" onClick={copyToClipboardHandler} className={classes[\"secret-key__copy-key\"]}><CgCopy /></span>\n                </p>\n                <p className={classes[\"secret-key__info-text\"]}>Make sure to copy your secret key. Secret key is required to login next time</p>\n            </div>\n            <div className={classes[\"secret-key__footer\"]}>\n                <Link href=\"/home\">\n                    <a className={classes[\"secret-key__footer-btn\"]}>Continue</a>\n                </Link>\n            </div>\n        </div>\n    )\n}\n\nexport default SecretKey;"
  },
  {
    "path": "aquila/view/components/pages/signUp/SignUpForm.module.scss",
    "content": ".signup-box {\n\n\t&__header {\n\t\tmargin: 25px 0px;\n\t}\n\n\t&__title {\n\t\tfont-size: 20px;\n\t\tcolor: #415572;\n\t\ttext-align: center;\n\t}\n\n\t&__form-item {\n\t\tmargin-bottom: 12px;\n\t}\n\n\t&__form-item--btn-container {\n\t\tmargin-top: 30px;\n\t}\n\n\t&__form-label {\n\t\tdisplay: block;\n\t\tcolor: hsl(214, 28%, 45%);\n\t\tmargin-bottom: 4px;\n\t}\n\n\t&__form-control {\n\t\tcolor: #415572;\n\t\twidth: 100%;\n\t\tpadding: 8px 5px;\n\t\tborder: 1px solid #536E92;\n\t\tborder-radius: 3px;\n\t\tbox-sizing: border-box;\n\t}\n\n\t&__form-error {\n\t\tmargin-top: 5px;\n\t\tcolor: #F87272;\n\t\tfont-size: 12px;\n\t}\n\n\t&__form-btn {\n\t\twidth: 100%;\n\t\tbackground: none;\n\t\toutline: none;\n\t\tborder: 1px solid #415572;\n\t\tcolor: #415572;\n\t\tpadding: 6px 0px;\n\t\tborder-radius: 3px;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t}\n\n\t&__form-btn:hover {\n\t\tcolor: #0FBD86;\n\t\tborder: 1px solid #0FBD86;\n\t}\n\n\t&__form-btn:disabled {\n\t\tcolor: #CED7E3;\n\t\tborder: 1px solid #CED7E3;\n\t\tcursor: not-allowed\n\t}\n\n\t&__footer-text {\n\t\tfont-size: 12px;\n\t}\n\n\t&__footer-link {\n\t\tcolor: #0FBD86;\n\t\ttext-decoration: none;\n\t}\n\n\t&__footer-link:hover {\n\t\tcolor: #0DA575;\n\t}\n\n}"
  },
  {
    "path": "aquila/view/components/pages/signUp/SignUpForm.tsx",
    "content": "import Link from 'next/link';\nimport { FC, useEffect, useState } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { AppState } from '../../../store';\n\nimport classes from './SignUpForm.module.scss';\n\ninterface SignUpFormProps {\n\tonSignUp: Function;\n\tname: {\n\t\tfirstName: string | null;\n\t\tlastName: string | null;\n\t},\n\tsignUpState: AppState[\"signUp\"]\n}\n\ntype FormData = {\n\tfirstName: string;\n\tlastName: string;\n}\n\nconst SignUpForm: FC<SignUpFormProps> = (props) => {\n\tconst {\n\t\tname,\n\t\tonSignUp,\n\t\tsignUpState\n\t} = props;\n\n\tconst { register, handleSubmit, setValue, setError, formState: { errors } } = useForm<FormData>();\n\tconst [ isLoading, setIsLoading] = useState(false);\n\n\tuseEffect(() => {\n\t\tif(name.firstName && name.lastName) {\n\t\t\tsetValue(\"firstName\", name.firstName);\n\t\t\tsetValue(\"lastName\", name.lastName);\n\t\t}\t\n\t}, [name.firstName, name.lastName, setValue])\n\n\tuseEffect(() => {\n\t\tif(signUpState.errors) {\n\t\t\tsignUpState.errors.firstName && setError(\"firstName\", { type: 'custom', message: signUpState.errors.firstName });\n\t\t\tsignUpState.errors.lastName && setError(\"lastName\", { type: 'custom', message: signUpState.errors.lastName });\n\t\t}\n\t}, [signUpState])\n\n\tconst onSubmitHandler = (data: any) => {\n\t\tsetIsLoading(true);\n\t\tonSignUp(data)\n\t\t\t.then(() => {\n\t\t\t\tsetIsLoading(false);\n\t\t\t})\n\t};\n\n\treturn (\n\t\t<div className={classes[\"signup-box\"]}>\n\t\t\t<form onSubmit={handleSubmit(onSubmitHandler)}>\n\t\t\t\t<div className={classes[\"signup-box__header\"]}>\n\t\t\t\t\t<h3 className={classes[\"signup-box__title\"]}>Generate Account</h3>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"signup-box__form\"]}>\n\t\t\t\t\t<div className={classes[\"signup-box__form-item\"]}>\n\t\t\t\t\t\t<label className={classes[\"signup-box__form-label\"]}>First name</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t{...register(\"firstName\", { required: true})}\n\t\t\t\t\t\t\tclassName={classes[\"signup-box__form-control\"]}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tplaceholder=\"First name\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{errors.firstName && <p className={classes[\"signup-box__form-error\"]}>{errors.firstName.message}</p>}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className={classes[\"signup-box__form-item\"]}>\n\t\t\t\t\t\t<label className={classes[\"signup-box__form-label\"]}>Signup name</label>\n\t\t\t\t\t\t<input \n\t\t\t\t\t\t\t{...register(\"lastName\", { required: true})}\n\t\t\t\t\t\t\tclassName={classes[\"signup-box__form-control\"]}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tplaceholder=\"Last name\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{errors.lastName && <p className={classes[\"signup-box__form-error\"]}>{errors.lastName.message}</p>}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className={`${classes[\"signup-box__form-item\"]} ${classes[\"signup-box__form-item--btn-container\"]}`}>\n\t\t\t\t\t\t<button disabled={isLoading} className={classes[\"signup-box__form-btn\"]}>Generate Account</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"signup-box__footer\"]}>\n\t\t\t\t\t<p className={classes[\"signup-box__footer-text\"]}>\n\t\t\t\t\t\t<span>Already have an account?  </span>\n\t\t\t\t\t\t<Link href=\"/sign-in\"><a className={classes[\"signup-box__footer-link\"]}>Login</a></Link>\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t</div>\n\t)\n}\n\nexport default SignUpForm;"
  },
  {
    "path": "aquila/view/components/pages/signUp/SignUpPageWrapper.tsx",
    "content": "import { FC } from \"react\";\n\nimport { AppState } from '../../../store/';\nimport BoxCenterLayout from \"../../layout/boxCenter/BoxCenterLayout\";\nimport SecretKey from \"./SecretKey\";\nimport SignUpForm from \"./SignUpForm\";\n\ninterface SignUpPageWrapperProps {\n\tonSignUp: Function,\n\tname: {\n\t\tfirstName: string | null;\n\t\tlastName: string | null;\n\t},\n\tsignUpState: AppState[\"signUp\"];\n\taccountCreated: boolean;\n}\n\nconst SignUpPageWrapper: FC<SignUpPageWrapperProps> = (props) => {\n\treturn (\n\t\t<BoxCenterLayout headerBorder={false}>\n\t\t\t{ !props.accountCreated &&\n\t\t\t<SignUpForm \n\t\t\t\tname={props.name}\n\t\t\t\tonSignUp={props.onSignUp}\n\t\t\t\tsignUpState={props.signUpState}\n\t\t\t/>\n\t\t\t}\n\t\t\t{ props.accountCreated && <SecretKey signUpState={props.signUpState} />\t}\n\t\t</BoxCenterLayout>\n\t)\n}\n\nexport default SignUpPageWrapper;"
  },
  {
    "path": "aquila/view/components/pages/subscription/Collection.module.scss",
    "content": ".collection {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    border: 1px solid #EFF2F6;\n    padding: 10px;\n    border-radius: 3px;\n\n    &__link {\n        color: #202A38;\n        text-decoration: none;\n        transition: all .3s;\n    }\n\n    &__link:hover {\n        color: #0FBD86;\n    }\n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/Collection.tsx",
    "content": "import Avatar from 'boring-avatars';\nimport Link from 'next/link';\nimport { FC } from 'react';\nimport classes from './Collection.module.scss';\n\ninterface CollectionProps {\n    name: string;\n    collectionId: string;\n}\n\nconst Collection: FC<CollectionProps> = (props) => {\n    const { name, collectionId } = props;\n    return (\n        <div className={classes[\"collection\"]} >\n            <Avatar name={name} />\n            <Link href={`/collection/bookmark/${collectionId}`}>\n                <a rel=\"nofollow\" className={classes[\"collection__link\"]}><h3 className={classes[\"collection__title\"]}>{name}</h3></a>\n            </Link>\n        </div>\n    )\n}\n\nexport default Collection;"
  },
  {
    "path": "aquila/view/components/pages/subscription/HomePageWrapper.tsx",
    "content": "import { FC, useEffect, useState } from \"react\";\nimport { Oval } from 'react-loader-spinner';\n\nimport { AppState } from \"../../../store\";\nimport { Collection } from \"../../../store/slices/types/Collection\";\nimport { Customer } from \"../../../store/slices/types/Customer\";\nimport MainLayout from \"../../layout/main/MainLayout\"\nimport Container from \"../../ui/layout/Container\";\nimport classes from \"./HomePageWrapper.module.scss\";\nimport SearchBar from \"./SearchBar\";\nimport SearchPageProfile from \"./SearchPageProfile\";\nimport SearchResults from \"./SearchResults\";\n\ninterface HomePageWrapperProps {\n    customer: Customer | null;\n    collection: Collection | null;\n    bookmarksState: AppState[\"getLoggedInCustBookmarksByCollectionId\"];\n    onSearch: Function;\n    onClickNextPage: Function;\n    onClickPrevPage: Function;\n}\n\nconst HomePageWrapper: FC<HomePageWrapperProps> = (props) => {\n    const { collection, customer, bookmarksState, onSearch, onClickNextPage, onClickPrevPage } = props;\n    const [hasNext, setHasNext] = useState(false);\n    const [hasPrev, setHasPrev] = useState(false);\n    \n    useEffect(() => {\n        if(bookmarksState.currentPage && bookmarksState.totalPages) {\n            if(bookmarksState.currentPage < bookmarksState.totalPages) {\n                setHasNext(true);\n            }else {\n                setHasNext(false);\n            }\n            if(bookmarksState.currentPage > 1) {\n                setHasPrev(true)\n            }else {\n                setHasPrev(false)\n            }\n        }\n    }, [bookmarksState])\n\n    return (\n        <MainLayout>\n            <Container>\n                <div className={classes[\"home-page\"]}>\n                    <section className={classes[\"home-page__search-area\"]}>\n                        <div className={classes[\"home-page__search-bar\"]}>\n                            <SearchBar onSearch={onSearch} />\n                        </div>\n                        <div className={classes[\"home-page__search-results\"]}>\n                            {bookmarksState.status === \"pending\" && <Oval height={30} width=\"100%\" strokeWidth={5} color=\"#0FBD86\" strokeWidthSecondary={5} />}\n                            {bookmarksState.bookmarks && <SearchResults \n                                totalRecords={bookmarksState.totalRecords}\n                                onClickNextPage={onClickNextPage}\n                                onClickPrevPage={onClickPrevPage}\n                                hasPrev={hasNext}\n                                hasNext={hasPrev}\n                                bookmarks={bookmarksState.bookmarks}\n                                />}\n                        </div>\n                    </section>\n                    <section className={classes[\"home-page__sidebar\"]}>\n                       {collection && customer && <SearchPageProfile collection={collection} customer={customer} />}\n                    </section>\n                </div>\n            </Container>\n        </MainLayout>\n    )\n}\n\nexport default HomePageWrapper;"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchBar.module.scss",
    "content": ".search-bar {\n\tpadding: 10px 5px;\n\n\t&__container {\n\t\tdisplay: flex;\n\t\tborder-bottom: 1px solid #AEBCD1;\n\t\tpadding: 10px 5px;\n\t}\n\n\t&__input {\n\t\tmargin-right: 10px;\n\t\twidth: 100%;\n\t\tborder: none;\n\t\toutline: none;\n\t}\n\n\t&__input::placeholder {\n\t\tcolor: #AEBCD1;\n\t}\n\n\t&__btn {\n\t\tborder: none;\n\t\toutline: none;\n\t\tbackground: transparent;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchBar.tsx",
    "content": "import { FC, useRef } from 'react';\nimport { IoSearch } from 'react-icons/io5';\nimport classes from './SearchBar.module.scss';\n\ninterface SearchBarProps {\n\tonSearch: Function\n}\n\nconst SearchBar: FC<SearchBarProps> = (props) => {\n\tconst { onSearch } = props;\n\tconst searchValueRef = useRef<HTMLInputElement>(null);\n\n\tconst onSubmitHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonSearch(searchValueRef.current?.value)\n\t}\n\n\treturn (\n\t\t<div className={classes[\"search-bar\"]}>\n\t\t\t<form className={classes[\"search-bar__container\"]} onSubmit={onSubmitHandler}>\n\t\t\t\t<input ref={searchValueRef} className={classes[\"search-bar__input\"]} placeholder='Search Bookmarks...' type=\"text\" />\n\t\t\t\t<button className={classes[\"search-bar__btn\"]}>\n\t\t\t\t\t<IoSearch />\n\t\t\t\t</button>\n\t\t\t</form>\n\t\t</div>\n\t)\n}\n\nexport default SearchBar;"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchPageProfile.module.scss",
    "content": ".search-profile {\n\tpadding: 15px;\n\tmargin-top: 20px;\n\tborder: 1px solid #CED7E3;\n\tborder-radius: 3px;\n\n\t&__header {\n\t\tdisplay: flex;\n\t\tjustify-content: space-between;\n\t\tmargin-bottom: 10px;\n\t}\n\n\t&__header-subscribe-btn {\n\t\tmargin-top: 5px;\n\t\tbackground: transparent;\n\t\tborder: 1px solid #8DA2BE;\n\t\toutline: none;\n\t\tborder-radius: 3px;\n\t\tcolor: #2E3D51;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t}\n\n\t&__header-subscribe-btn:hover {\n\t\tcolor: #0FBD86;\n\t\tborder-color: #0FBD86;\n\t}\n\n\t&__header-left {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 10px;\n\t}\n\n\t&__header-name {\n\t\tcolor: #202A38;\n\t\tfont-size: 25px;\n\t}\n\n\t&__body-desc {\n\t\tcolor: #415572;\n\t\tmargin: 0px;\n\t\tfont-size: 14px;\n\t\tmargin-bottom: 20px;\n\t}\n\n\t&__body-bookmark-title {\n\t\tfont-size: 14px;\n\t\tmargin-bottom: 5px;\n\t\tcolor: #415572;\n\t}\n\n\t&__body-share-bookmark-box {\n\t\toverflow: hidden;\n\t\tbackground: #EFF2F6;\n\t\tposition: relative;\n\t\tbox-sizing:border-box;\n\t\tmargin: 0px auto;\n\t\tpadding: 3px 4px;\n\t\tborder-radius: 3px;\n\t}\n\n\t&__body-share-bookmark-btn {\n\t\tposition: absolute;\n\t\tright: 0px;\n\t\ttop: 0px;\n\t\tbottom: 0px;\n\t\tfont-size: 12px;\n\t\tpadding: 5px;\n\t\tcolor: #fff;\n\t\tbackground: #3ABFF8;\n\t\tborder-radius: 3px;\n\t\tcursor: pointer;\n\t\ttransition: all .3s;\n\t}\n\n\t&__body-share-bookmark-btn:hover {\n\t\tbackground: #089DDE;\n\t}\n\n\t&__body-share-bookmark-link {\n\t\twidth: 100%;\n\t\tmargin: 0px;\n\t\tborder: none;\n\t\toutline: none;\n\t\tbackground: transparent;\n\t\tfont-size: 12px;\n\t\tcolor: #415572;\n\t}\n\n\t&__body-feedback-container {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__body-feedback-txt {\n\t\tcolor: #097654;\n\t\ttext-decoration: none;\n\t\tfont-size: 14px;\n\t\ttransition: all .3s;\n\t}\n\n\t&__body-feedback-txt:hover {\n\t\tcolor: #0FBD86;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchPageProfile.tsx",
    "content": "import { VscFeedback } from 'react-icons/vsc';\nimport { toast } from 'react-toastify';\nimport Avatar from \"boring-avatars\";\n\nimport classes from './SearchPageProfile.module.scss';\nimport { Customer } from '../../../store/slices/types/Customer';\nimport { FC, useRef } from 'react';\nimport { Collection } from '../../../store/slices/types/Collection';\n\ninterface SearchPageProfileProps {\n\tcustomer: Customer;\n\tcollection: Collection;\n}\n\nconst SearchPageProfile: FC<SearchPageProfileProps> = ({ customer, collection }) => {\n\n\tconst bookmarkShareLinkRef = useRef<HTMLInputElement | null>(null);\n\n\tconst OnClickCopyBtnHandler = () => {\n\t\tnavigator.clipboard.writeText(bookmarkShareLinkRef.current?.value || \"\");\n        toast(\"Collection link copied\", { position: \"top-center\"});\n\t}\n\n\treturn (\n\t\t<div className={classes[\"search-profile\"]}>\n\t\t\t<div className={classes[\"search-profile__header\"]}>\n\t\t\t\t<div className={classes[\"search-profile__header-left\"]}>\n\t\t\t\t\t<div className={classes[\"search-profile__header-avatar\"]}>\n\t\t\t\t\t\t<Avatar size=\"80\" variant=\"beam\" name={`${customer.firstName} ${customer.lastName}`} />\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3 className={classes[\"search-profile__header-name\"]}>{`${customer.firstName} ${customer.lastName}`}</h3>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"search-profile__header-right\"]}>\n\t\t\t\t\t<button className={classes[\"search-profile__header-subscribe-btn\"]}>Subscribe</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-profile__body\"]}>\n\t\t\t\t<p className={classes[\"search-profile__body-desc\"]}>{collection.desc}</p>\n\t\t\t\t<div className={classes[\"search-profile__body-bookmark\"]}>\n\t\t\t\t\t<p className={classes[\"search-profile__body-bookmark-title\"]}>Share this bookmark</p>\n\t\t\t\t\t<div className={classes[\"search-profile__body-share-bookmark-box\"]}>\n\t\t\t\t\t\t<input ref={bookmarkShareLinkRef} readOnly className={classes[\"search-profile__body-share-bookmark-link\"]} type=\"text\" value={`${process.env.NEXT_PUBLIC_BASE_URL}/collection/bookmark/${collection.id}`} />\n\t\t\t\t\t\t<span onClick={OnClickCopyBtnHandler} className={classes[\"search-profile__body-share-bookmark-btn\"]}>Copy</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className={classes[\"search-profile__body-feedback-container\"]}>\n\t\t\t\t\t<a href=\"https://airtable.com/shr3QnQbBhWmIKv8p\" target=\"__blank\" className={classes[\"search-profile__body-feedback-txt\"]} >send us your feedback <VscFeedback /></a>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nexport default SearchPageProfile;"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchResultItem.module.scss",
    "content": ".search-result-item {\n\tborder-bottom: 1px solid #CED7E3;\n\tpadding-bottom: 15px;\n\tmargin-bottom: 10px;\n\tword-wrap: break-word;\n\n\t&__title {\n\t\tmargin-bottom: 2px;\n\t\tfont-size: 22px;\n\t}\n\n\t&__title-link {\n\t\tfont-size: 22px;\n\t\tcolor: #202A38;\n\t\ttransition: all .3s;\n\t\tcursor: pointer;\n\t\ttext-decoration: none;\n\t}\n\n\t&__title-link:hover {\n\t\tcolor: #0FBD86;\n\t}\n\n\t&__meta-info {\n\t\tpadding-bottom: 0px;\n\t\tmargin-bottom: 0px;\n\t\tfont-size: 12px;\n\t\tcolor: #8DA2BE;\n\t}\n\n\t&__site-link {\n\t\tfont-size: 14px;\n\t\tcolor: #536E92;\n\t\ttransition: all .3s;\n\t}\n\n\t&__site-link:hover {\n\t\tcolor: #9B5094;\n\t}\n\n\t&__site-desc {\n\t\tcolor: #415572;\n\t\tmargin-top: 5px;\n\t\tmargin-bottom: 3px;\n\t\tpadding-bottom: 0px;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchResultItem.tsx",
    "content": "import { FC } from 'react';\nimport moment from 'moment';\n\nimport classes from './SearchResultItem.module.scss';\n\ninterface SearchResultItemProps {\n\ttitle: string;\n\turl: string;\n\tsummary: string;\n\tcreatedAt: string;\n}\n\nconst SearchResultItem: FC<SearchResultItemProps> = (props) => {\n\tconst { title, url, summary, createdAt } = props;\n\treturn (\n\t\t<div className={classes[\"search-result-item\"]}>\n\t\t\t<h3 className={classes['search-result-item__title']}><a className={classes[\"search-result-item__title-link\"]} rel=\"nofollow\" href={url} >{title}</a></h3>\n\t\t\t<p className={classes['search-result-item__meta-info']}>Updated {moment(createdAt).fromNow()}</p>\n\t\t\t<p className={classes['search-result-item__site-desc']}>{summary.length > 255 ? summary.substring(0, 255)+'...' : summary}</p>\n\t\t\t<a rel=\"nofollow\" className={classes['search-result-item__site-link']} href={url}>{url}</a>\n\t\t</div>\n\t);\n}\n\nexport default SearchResultItem;"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchResults.module.scss",
    "content": ".search-result {\n\n\t&__results {\n\t\tmargin-top: 20px;\n\t}\n\n\t&__item {\n\t\tmargin-bottom: 25px;\n\t}\n\n\t&__header-info-desc {\n\t\tcolor: #536E92;\n\t}\n\n\t&__pagination {\n\t\tmargin-top: 15px;\n\t\tdisplay: flex;\n\t\tgap: 10px;\n\t}\n\n\t&__pagination-link {\n\t\tfont-size: 14px;\n\t\ttext-decoration: none;\n\t\tbackground: #EFF2F6;\n\t\tcolor: #202A38;\n\t\tpadding: 5px;\n\t\ttransition: all .3s;\n\t\tborder-radius: 3px;\n\t}\n\n\t&__pagination-link:hover {\n\t\tbackground: #CED7E3;\n\t}\n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/SearchResults.tsx",
    "content": "import { FC } from \"react\";\nimport { Bookmark } from \"../../../store/slices/types/Bookmark\";\nimport SearchResultItem from \"./SearchResultItem\";\nimport classes from './SearchResults.module.scss';\n\ninterface SearchResultsProps {\n\tbookmarks: Bookmark[];\n\thasNext: boolean;\n\thasPrev: boolean;\n\tonClickNextPage: Function;\n\tonClickPrevPage: Function;\n\ttotalRecords: number | null;\n}\n\nconst SearchResults: FC<SearchResultsProps> = (props) => {\n\tconst { bookmarks, hasNext, hasPrev, onClickNextPage, onClickPrevPage, totalRecords } = props;\n\n\tconst onNextPageHandler = (e: any) => {\n\t\te.preventDefault();\n\t\tonClickNextPage()\n\t}\n\n\tconst onPrevPageHandler = (e:any) => {\n\t\te.preventDefault();\n\t\tonClickPrevPage()\n\t}\n\n\n\treturn (\n\t\t<div className={classes[\"search-result\"]}>\n\t\t\t<div className={classes[\"search-result__header-info\"]}>\n\t\t\t\t{totalRecords !== null ? <p className={classes[\"search-result__header-info-desc\"]}>Received {totalRecords} results</p>: null}\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-result__results\"]}>\n\t\t\t\t{bookmarks.map((bookmark, index) => (\n\t\t\t\t<div key={index} className={classes[\"search-result__item\"]}>\n\t\t\t\t\t<SearchResultItem\n\t\t\t\t\t\ttitle={bookmark.title}\n\t\t\t\t\t\turl={bookmark.url}\n\t\t\t\t\t\tsummary={bookmark.summary || bookmark.description || \"\"}\n\t\t\t\t\t\tcreatedAt={bookmark.createdAt}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t\t<div className={classes[\"search-result__pagination\"]}>\n\t\t\t\t\t{hasNext && <a onClick={onPrevPageHandler} className={classes[\"search-result__pagination-link\"]} href=\"#\">Previous</a>}\n\t\t\t\t\t{hasPrev && <a onClick={onNextPageHandler} className={classes[\"search-result__pagination-link\"]} href=\"#\">Next</a>}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default SearchResults;"
  },
  {
    "path": "aquila/view/components/pages/subscription/SubscribedCollections.module.scss",
    "content": ".subscribed-collections {\n    border: 1px solid #CED7E3;\n    border-radius: 3px;\n\n    &__header {\n        padding: 20px;\n    }\n\n    &__header-title {\n        font-size: 20px;\n        color: #202A38;\n    }\n\n    &__body {\n        padding: 20px;\n    }\n\n    &__list {\n        list-style: none;\n        display: flex;\n        flex-direction: column;\n        gap: 20px\n    }\n\n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/SubscribedCollections.tsx",
    "content": "import { FC } from \"react\";\nimport { Collection } from \"../../../store/slices/types/Collection\";\nimport { default as CollectionComponent } from \"./Collection\"\n\nimport classes from './SubscribedCollections.module.scss';\n\ninterface SubscribedCollectionsProps {\n    collections: Collection[]\n}\n\nconst SubscribedCollections: FC<SubscribedCollectionsProps> = (props) => {\n    const { collections } = props;\n    return (\n        <div className={classes[\"subscribed-collections\"]}>\n            <div className={classes[\"subscribed-collections__header\"]}>\n                <h3 className={classes[\"subscribed-collections__header-title\"]}>Subscriptions</h3>\n            </div>\n            <div className={classes[\"subscribed-collections__body\"]}>\n                <ul className={classes[\"subscribed-collections__list\"]}>\n                    {collections.map((collection) => (<li key={collection.id} className={classes[\"subscribed-collections__list-item\"]}><CollectionComponent collectionId={collection.id} name={`${collection.customer?.firstName} ${collection.customer?.lastName}`} /></li>))} \n                </ul> \n            </div>\n        </div>\n    )\n}\n\nexport default SubscribedCollections;\n"
  },
  {
    "path": "aquila/view/components/pages/subscription/SubscriptionPageWrapper.module.scss",
    "content": ".subscription-page {\n    display: flex;\n    gap: 50px;\n\n    &__search-area {\n        flex-basis: 900px;    \n    }\n\n    &__search-bar {\n        margin-top: 20px;\n        width: 600px;\n    }\n\n    &__search-results {\n        margin-top: 30px;\n    }\n\n    &__sidebar {\n        padding-top: 20vh;\n        flex: 1 1 0;\n    }\n}\n\n@media only screen and (max-width: 992px) {\n   .subscription-page {\n    gap: 0px;\n    flex-direction: column;\n    \n    &__search-area {\n        flex-basis: auto;\n    }\n\n    &__search-bar {\n        width: 80%;\n    }\n\n    &__sidebar {\n        display: none;\n    }\n   } \n}"
  },
  {
    "path": "aquila/view/components/pages/subscription/SubscriptionPageWrapper.tsx",
    "content": "import { FC, useEffect, useState } from \"react\";\nimport { Oval } from 'react-loader-spinner';\n\nimport { AppState } from \"../../../store\";\nimport { Collection } from \"../../../store/slices/types/Collection\";\nimport { Customer } from \"../../../store/slices/types/Customer\";\nimport MainLayout from \"../../layout/main/MainLayout\"\nimport Container from \"../../ui/layout/Container\";\nimport classes from \"./SubscriptionPageWrapper.module.scss\";\nimport SearchBar from \"./SearchBar\";\nimport SearchResults from \"./SearchResults\";\nimport SubscribedCollections from \"./SubscribedCollections\";\n\ninterface SubscriptionPageWrapperProps {\n    subscribedCollections: Collection[] | null;\n    bookmarksState: AppState[\"getCustomerSubscriptions\"];\n    onSearch: Function;\n    onClickNextPage: Function;\n    onClickPrevPage: Function;\n}\n\nconst SubscriptionPageWrapper: FC<SubscriptionPageWrapperProps> = (props) => {\n    const { bookmarksState, onSearch, onClickNextPage, onClickPrevPage, subscribedCollections } = props;\n    const [hasNext, setHasNext] = useState(false);\n    const [hasPrev, setHasPrev] = useState(false);\n    \n    useEffect(() => {\n        if(bookmarksState.currentPage && bookmarksState.totalPages) {\n            if(bookmarksState.currentPage < bookmarksState.totalPages) {\n                setHasNext(true);\n            }else {\n                setHasNext(false);\n            }\n            if(bookmarksState.currentPage > 1) {\n                setHasPrev(true)\n            }else {\n                setHasPrev(false)\n            }\n        }\n    }, [bookmarksState])\n\n    return (\n        <MainLayout>\n            <Container>\n                <div className={classes[\"subscription-page\"]}>\n                    <section className={classes[\"subscription-page__search-area\"]}>\n                        <div className={classes[\"subscription-page__search-bar\"]}>\n                            <SearchBar onSearch={onSearch} />\n                        </div>\n                        <div className={classes[\"subscription-page__search-results\"]}>\n                            {bookmarksState.status === \"pending\" && <Oval height={30} width=\"100%\" strokeWidth={5} color=\"#0FBD86\" strokeWidthSecondary={5} />}\n                            {bookmarksState.bookmarks && <SearchResults \n                                totalRecords={bookmarksState.totalRecords}\n                                onClickNextPage={onClickNextPage}\n                                onClickPrevPage={onClickPrevPage}\n                                hasPrev={hasNext}\n                                hasNext={hasPrev}\n                                bookmarks={bookmarksState.bookmarks}\n                                />}\n                        </div>\n                    </section>\n                    <section className={classes[\"subscription-page__sidebar\"]}>\n                        {Array.isArray(subscribedCollections) &&  <SubscribedCollections collections={subscribedCollections} />}\n                    </section>\n                </div>\n            </Container>\n        </MainLayout>\n    )\n}\n\nexport default SubscriptionPageWrapper;"
  },
  {
    "path": "aquila/view/components/ui/alert/Alert.module.scss",
    "content": ".alert {\n    padding: 10px;\n    border-radius: 3px;\n\n    &--success {\n        background: #EAFAF4;\n        color: #36D399;\n    }\n\n    &--info {\n        background: #E6F7FE;\n        color: #3ABFF8;\n    }\n\n    &--danger {\n        background: #FEE7E7;\n        color: #F87272;\n    }\n\n    &__text {\n        font-size: 14px;\n        text-align: center;\n    }\n}"
  },
  {
    "path": "aquila/view/components/ui/alert/Alert.tsx",
    "content": "import { FC } from 'react';\nimport classes from './Alert.module.scss';\n\ninterface AlertProps {\n    message: string;\n    type: \"danger\" | \"success\" | \"info\";\n}\n\nconst alertClassMap = {\n    danger: classes[\"alert--danger\"],\n    success: classes[\"alert--success\"],\n    info: classes[\"alert--info\"]\n}\n\nconst Alert: FC<AlertProps> = ({ message, type}) => {\n    return (\n        <div className={`${classes.alert} ${alertClassMap[type]}`}>\n            <p className={classes.alert__text}>{message}</p>\n        </div>\n    )\n}\n\nexport default Alert;"
  },
  {
    "path": "aquila/view/components/ui/layout/Container.module.scss",
    "content": ".container {\n    max-width: 1200px;\n    margin: 0px auto;\n}\n\n@media only screen and (max-width: 1200px) {\n    .container {\n        padding: 0px 10px;\n    }\n}"
  },
  {
    "path": "aquila/view/components/ui/layout/Container.tsx",
    "content": "import { FC } from \"react\";\n\nimport classes from './Container.module.scss';\n\ninterface ContainerProps {\n    children: React.ReactNode;\n}\n\nconst Container: FC<ContainerProps> = (props) => {\n    return <div className={classes.container}>{props.children}</div>\n}\n\nexport default Container;"
  },
  {
    "path": "aquila/view/components/ui/modal/Modal.module.scss",
    "content": ".modal {\n    width: 100%;\n    height: 100%;\n    position: fixed;\n    top: 0px;\n    left: 0px;\n    background: rgb(32, 42, 56, 0.7);\n}"
  },
  {
    "path": "aquila/view/components/ui/modal/Modal.tsx",
    "content": "import { FC, useEffect, useState } from \"react\";\nimport ReactDOM from 'react-dom';\n\nimport classes from './Modal.module.scss';\n\ninterface ModelProps {\n    children: React.ReactNode;\n    onClose: Function\n}\n\nconst Modal: FC<ModelProps> = (props) => {\n    const [mounted, setMounted] = useState(false);\n\n    const onCloseHandler = (e:any) => {\n        props.onClose();\n    }\n\n    useEffect(() => {\n        setMounted(true);\n    }, [])\n    \n\n    return mounted ? ReactDOM.createPortal(\n        <div className={classes.modal} onClick={onCloseHandler}>\n            {props.children}\n        </div>,\n        document.getElementById(\"modal\") as HTMLElement\n    ): null;\n}\n\nexport default Modal;"
  },
  {
    "path": "aquila/view/components/ui/progressLoader/ProgressLoader.module.scss",
    "content": ".progress-loader {\n    position: fixed;\n    top: 0px;\n    height: 4px;\n    display: block;\n    width: 100%;\n    background-color: rgb(15, 189, 134, 0.2);\n    border-radius: 2px;\n    overflow: hidden;\n    z-index: 3000;\n\n    &__item {\n        background-color: #0FBD86;\n    }\n    \n    &__item:before{\n        content:          '';\n        position:         absolute;\n        background-color: inherit;\n        top:              0;\n        left:             0;\n        bottom:           0;\n        will-change:      left, right;\n        animation:        progress 1.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;\n    }\n}\n\n@keyframes progress {\n    0% {\n      left: -35%;\n      right: 100%;\n    }\n    60% {\n      left: 100%;\n      right: -90%;\n    }\n    100% {\n      left: 100%;\n      right: -90%;\n    }\n  }"
  },
  {
    "path": "aquila/view/components/ui/progressLoader/ProgressLoader.tsx",
    "content": "import React, { FC, useContext, useState } from 'react';\nimport classes from './ProgressLoader.module.scss';\n\ninterface ProgressLoaderCtxValue { status: boolean, setLoader: (status: boolean) => void};\n\nconst ProgressLoaderCtx = React.createContext<ProgressLoaderCtxValue | undefined>(undefined)\n\nexport const useProgressLoader = () => {\n    const context =  useContext(ProgressLoaderCtx);\n    if(!context) {\n        throw new Error(\"useProgressLoader must use inside a ProgressLoaderProvider\");\n    }\n    return context;\n}\n\ninterface ProgressLoaderProviderProps {\n    children: React.ReactNode;\n}\n\nconst ProgressLoader = () => {\n    const { status } = useProgressLoader();\n    if (!status) return null; \n    return (\n        <div className={classes[\"progress-loader\"]}>\n            <div className={classes[\"progress-loader__item\"]}></div>\n        </div>\n    )\n}\n\nexport const ProgressLoaderProvider: FC<ProgressLoaderProviderProps> = ({ children }) => {\n    const [status, setLoader] = useState(false);\n\n    return (<ProgressLoaderCtx.Provider value={{ status, setLoader}}>\n        <ProgressLoader />\n        {children}\n    </ProgressLoaderCtx.Provider>\n    );\n}\n"
  },
  {
    "path": "aquila/view/middleware.ts",
    "content": "export { default } from 'next-auth/middleware';\n\nexport const config = {\n\tmatcher: ['/home', '/profile', '/subscription', '/account/edit-profile']\n}"
  },
  {
    "path": "aquila/view/next.config.js",
    "content": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n  reactStrictMode: true,\n  swcMinify: true,\n  output: \"standalone\"\n}\n\nmodule.exports = nextConfig\n"
  },
  {
    "path": "aquila/view/package.json",
    "content": "{\n  \"name\": \"aquila-network-ui\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\",\n    \"lint\": \"next lint\"\n  },\n  \"dependencies\": {\n    \"@reduxjs/toolkit\": \"^1.8.6\",\n    \"axios\": \"^1.1.3\",\n    \"boring-avatars\": \"^1.7.0\",\n    \"jsonwebtoken\": \"^8.5.1\",\n    \"moment\": \"^2.29.4\",\n    \"next\": \"12.3.1\",\n    \"next-auth\": \"^4.14.0\",\n    \"next-redux-wrapper\": \"^8.0.0\",\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"react-hook-form\": \"^7.37.0\",\n    \"react-icons\": \"^4.6.0\",\n    \"react-loader-spinner\": \"^5.3.4\",\n    \"react-redux\": \"^8.0.4\",\n    \"react-toastify\": \"^9.0.8\"\n  },\n  \"devDependencies\": {\n    \"@types/jsonwebtoken\": \"^8.5.9\",\n    \"@types/node\": \"18.11.0\",\n    \"@types/react\": \"18.0.21\",\n    \"@types/react-dom\": \"18.0.6\",\n    \"eslint\": \"8.25.0\",\n    \"eslint-config-next\": \"12.3.1\",\n    \"sass\": \"^1.55.0\",\n    \"typescript\": \"4.8.4\"\n  }\n}\n"
  },
  {
    "path": "aquila/view/pages/_app.tsx",
    "content": "import type { AppProps } from 'next/app';\nimport { Provider } from 'react-redux';\nimport { SessionProvider } from 'next-auth/react';\nimport { ToastContainer} from 'react-toastify';\nimport 'react-toastify/dist/ReactToastify.css';\n\nimport { wrapper } from '../store';\nimport '../styles/globals.scss';\nimport { Session } from 'next-auth';\nimport InitComponent from '../components/hoc/InitComponent';\nimport BaseLayout from '../components/layout/base/baseLayout';\n\ninterface ApplicationProps {\n  session: Session\n}\n\nfunction MyApp({ Component, pageProps: { session, ...rest} }: AppProps<ApplicationProps>) {\n  const {store, props} = wrapper.useWrappedStore(rest);\n\n  return (\n    <SessionProvider session={session}>\n      <ToastContainer />\n      <Provider store={store}>\n        <InitComponent>\n          <BaseLayout>\n            <Component {...props.pageProps} />\n          </BaseLayout>\n        </InitComponent>\n      </Provider>\n    </SessionProvider>\n  );\n}\n\nexport default MyApp;\n"
  },
  {
    "path": "aquila/view/pages/_document.tsx",
    "content": "import { Head, Html, Main, NextScript } from \"next/document\";\n\nexport default function Document() {\n    return (\n        <Html lang=\"en\">\n            <Head />\n            <body>\n                <Main />\n                <div id=\"modal\"></div>\n                <NextScript />\n            </body>\n        </Html>\n    )\n}"
  },
  {
    "path": "aquila/view/pages/account/edit-profile.tsx",
    "content": "import { signIn } from \"next-auth/react\";\nimport { useEffect } from \"react\";\nimport { toast, ToastOptions } from 'react-toastify';\n\nimport EditProfileWrapper from \"../../components/pages/account/editProfile/EditProfileWrapper\";\nimport { useProgressLoader } from \"../../components/ui/progressLoader/ProgressLoader\";\nimport { useAppDispatch, useAppSelector } from \"../../store\";\nimport { selectAuth } from \"../../store/slices/auth\";\nimport { activateCustomer, selectActivateCustomer } from \"../../store/slices/customer/activateCustomer\";\nimport { getCurrentLoggedInCustomer, selectGetCurrentLoggedInCustomer } from \"../../store/slices/customer/getCurrentLoggedInCustomer\";\nimport { selectUpdateCustomer, updateCustomer, UpdateCustomerData } from \"../../store/slices/customer/updateCustomer\";\n\nconst EditProfilePage = () => {\n    const dispatch = useAppDispatch();\n    const currentLoggedInCustomer = useAppSelector(selectGetCurrentLoggedInCustomer);\n    const authState = useAppSelector(selectAuth);\n    const updateCustomerState = useAppSelector(selectUpdateCustomer);\n    const activateCustomerState = useAppSelector(selectActivateCustomer);\n    const { setLoader } = useProgressLoader();\n\n    useEffect(() => {\n        dispatch(getCurrentLoggedInCustomer())\n    }, [])\n\n    const updateFormSubmissionHandler = async (data: UpdateCustomerData) => {\n        const toastOptions: ToastOptions = {\n\t\t\tposition: \"top-center\",\n\t\t\thideProgressBar: true,\n\t\t}\n        setLoader(true);\n        if(authState.accountStatus === \"TEMPORARY\") {\n           try {\n                const customer = await dispatch(activateCustomer(data)).unwrap()\n                setLoader(false);\n                const resp = await signIn('credentials',{ redirect: false, secretKey: customer.secretKey });\n                if(resp?.ok) {\n                    toast(\"Account Activated Successfully\", { ...toastOptions, type: \"success\"})\n                    return true;\n                }\n            }catch(e) {\n                if(e instanceof Error) {\n                    toast(e.message, { ...toastOptions, type: \"error\"});\n                }\n                setLoader(false);\n                return false;\n            }\n        }else {\n            try {\n                await dispatch(updateCustomer(data)).unwrap()\n                toast(\"Profile Updated successfully\", { ...toastOptions, type: \"success\"})\n                setLoader(false);\n                return true;\n            }catch(e) {\n                if(e instanceof Error) {\n                    toast(e.message, { ...toastOptions, type: \"error\"});\n                }\n                setLoader(false);\n                return false;\n            }\n        }\n    }\n\n    return (\n        <EditProfileWrapper \n            activateCustomerState={activateCustomerState}\n            updateCustomerState={updateCustomerState}\n            onSubmit={updateFormSubmissionHandler}\n            authState={authState}\n            currentLoggedInCustomerState={currentLoggedInCustomer}\n        />\n    )\n}\n\nexport default EditProfilePage;"
  },
  {
    "path": "aquila/view/pages/api/auth/[...nextauth].ts",
    "content": "import NextAuth, { NextAuthOptions, User } from 'next-auth';\nimport Credentials from 'next-auth/providers/credentials';\nimport jwt from 'jsonwebtoken';\n\nimport api from '../../../utils/api';\n\ninterface AuthPayload {\n\taccountStatus: string;\n\tcustomerId: string;\n\tfirstName: string;\n\tlastName: string;\n\tcreatedAt: string;\n}\n\nexport const authOptions: NextAuthOptions = {\n\tproviders: [\n\t\tCredentials({\n\t\t\tname: 'credentials',\n\t\t\tcredentials: { secretKey: {}},\n\t\t\tasync authorize(credentials){\n\t\t\t\tlet token = '';\n\t\t\t\tlet response;\n\t\t\t\ttry{\n\t\t\t\t\tresponse = await api.post('/auth/login', {\n\t\t\t\t\t\tsecretKey: credentials?.secretKey\n\t\t\t\t\t});\n\t\t\t\t\tconsole.log(response.data);\n\t\t\t\t\ttoken = response.data?.token;\n\t\t\t\t}catch(e: unknown) {\n\t\t\t\t\tthrow new Error(response?.data.message || \"Something went wrong\");\n\t\t\t\t}\n\t\t\t\tif(!token) {\n\t\t\t\t\tthrow new Error('Something went wrong');\n\t\t\t\t}\n\t\t\t\tconst data = jwt.decode(token) as unknown as AuthPayload;\n\t\t\t\treturn {\n\t\t\t\t\tcustomerId: data.customerId,\n\t\t\t\t\tfirstName: data.firstName,\n\t\t\t\t\tlastName: data.lastName,\n\t\t\t\t\tcreatedAt: data.createdAt,\n\t\t\t\t\taccountStatus: data.accountStatus,\n\t\t\t\t\ttoken: token\n\t\t\t\t} as User;\n\t\t\t\t\n\t\t\t}\n\t\t})\n\t],\n\tcallbacks: {\n\t\tsession({ session, token}) {\n\t\t\tif(token.customerId) {\n\t\t\t\tsession.user.customerId = token.customerId;\n\t\t\t}\n\t\t\tif(token.firstName) {\n\t\t\t\tsession.user.firstName = token.firstName;\n\t\t\t}\n\t\t\tif(token.lastName) {\n\t\t\t\tsession.user.lastName = token.lastName;\n\t\t\t}\n\t\t\tif(token.accountStatus) {\n\t\t\t\tsession.user.createdAt = token.createdAt;\n\t\t\t}\n\t\t\tif(token.accountStatus) {\n\t\t\t\tsession.user.accountStatus = token.accountStatus;\n\t\t\t}\n\t\t\tif(token.token) {\n\t\t\t\tsession.user.token = token.token;\n\t\t\t}\n\t\t\treturn session;\n\t\t},\n\t\tjwt({ token, user}) {\n\t\t\tif(user) {\n\t\t\t\ttoken.customerId = user.customerId;\n\t\t\t\ttoken.firstName = user.firstName;\n\t\t\t\ttoken.lastName = user.lastName;\n\t\t\t\ttoken.createdAt = user.createdAt;\n\t\t\t\ttoken.accountStatus = user.accountStatus;\n\t\t\t\ttoken.token = user.token;\n\t\t\t}\n\t\t\treturn token;\n\t\t}\n\t},\n\tpages: {\n\t\tsignIn: '/sign-in'\n\t},\n\tsession: {\n\t\tstrategy: \"jwt\",\n\t\tmaxAge: 60 * 60 * 2, // 2 hours\n\t}\n};\n\nexport default NextAuth(authOptions)"
  },
  {
    "path": "aquila/view/pages/api/hello.ts",
    "content": "// Next.js API route support: https://nextjs.org/docs/api-routes/introduction\nimport type { NextApiRequest, NextApiResponse } from 'next'\n\ntype Data = {\n  name: string\n}\n\nexport default function handler(\n  req: NextApiRequest,\n  res: NextApiResponse<Data>\n) {\n  res.status(200).json({ name: 'John Doe' })\n}\n"
  },
  {
    "path": "aquila/view/pages/collection/bookmark/[collectionId].tsx",
    "content": "import { useRouter } from \"next/router\";\nimport { useEffect, useState } from \"react\";\nimport { toast } from 'react-toastify';\n\nimport CollectionBookmarksPageWrapper from \"../../../components/pages/collection/bookmark/CollectionBookmarks/CollectionBookmarksPageWrapper\";\nimport { useProgressLoader } from \"../../../components/ui/progressLoader/ProgressLoader\";\nimport { useAppDispatch, useAppSelector } from \"../../../store\";\nimport { selectAuth } from \"../../../store/slices/auth\";\nimport {getPublicBookmarksByCollectionId, GetPublicBookmarksByCollectionIdInputOptions, selectGetPublicBookmarksByCollectionId } from \"../../../store/slices/bookmark/getPublicBookmarksByCollectionId\";\nimport { getCollectionById, selectGetCollectionById } from \"../../../store/slices/collection/getCollectionById\";\nimport { isCollectionSubscribed, selectIsCollectionSubscribed } from \"../../../store/slices/collection/isCollectionSubscribed\";\nimport { selectSubscribeCollectionById, subscribeCollectionById } from \"../../../store/slices/collection/subscribeCollectionById\";\nimport { selectUnSubscribeCollectionById, unSubscribeCollectionById, unSubscribeCollectionByIdSlice } from \"../../../store/slices/collection/unSubscribeCollectionById\";\nimport { getCustomerById, selectGetCustomerById } from \"../../../store/slices/customer/getCustomerById\";\n\n\nconst ViewCollectionBookmarks = () => {\n    const router = useRouter(); \n    const { collectionId  } = router.query as { collectionId: string};\n    const authState = useAppSelector(selectAuth);\n    // const currentLoggedInCustomerState = useAppSelector(selectGetCurrentLoggedInCustomer);\n    const getCustomerByIdState = useAppSelector(selectGetCustomerById);\n    const getPublicCollectionBookmarksState = useAppSelector(selectGetPublicBookmarksByCollectionId);\n    const getCollectionByIdState = useAppSelector(selectGetCollectionById);\n    const isCollectionSubscribedState = useAppSelector(selectIsCollectionSubscribed);\n    const subscribeCollectionByIdState = useAppSelector(selectSubscribeCollectionById);\n    const unSubscribeCollectionByIdState = useAppSelector(selectUnSubscribeCollectionById);\n    const dispatch = useAppDispatch();\n    const [query, setQuery] = useState<string | null>(null);\n    const [currentPage, setCurrentPage] = useState(1);\n    const { setLoader } = useProgressLoader();\n\n    useEffect(() => {\n        if(authState.isSignedIn) {\n            dispatch((isCollectionSubscribed(collectionId)))\n        }\n    }, [dispatch, authState.isSignedIn, collectionId, subscribeCollectionByIdState.collectionSubscription, unSubscribeCollectionByIdState.collectionSubscription])\n\n    useEffect(() => {\n        if(collectionId) {\n            dispatch(getCollectionById(collectionId));\n        }\n    }, [dispatch, collectionId])\n\n    useEffect(() => {\n        if(getCollectionByIdState.collection) {\n            dispatch(getCustomerById(getCollectionByIdState.collection.customerId))\n        }\n    }, [dispatch, getCollectionByIdState.collection])\n\n    useEffect(() => {\n        const options: GetPublicBookmarksByCollectionIdInputOptions = {\n            collectionId: collectionId,\n            page: currentPage\n        }\n        if(query) {\n            options.query = query;\n        }\n        dispatch(getPublicBookmarksByCollectionId(options))\n    }, [dispatch, query, currentPage, collectionId])\n\n    const onSearchHandler = (data: string) => {\n        if(data) {\n            setQuery(data);\n            setCurrentPage(1);\n        }else {\n            setQuery(null);\n        }\n    }\n\n    const onClickNextPageHandler = () => {\n        setCurrentPage(currentPage + 1)\n    }\n\n    const onClickPrevPageHandler = () => {\n        setCurrentPage(currentPage - 1)\n    }\n\n    const onSubscribeHandler =  async (collectionId: string) => {\n        if(!authState.isSignedIn) {\n            router.push('/sign-in');\n            return;\n        }\n        try {\n            setLoader(true);\n            const resp = await dispatch(subscribeCollectionById(collectionId)).unwrap();\n            toast(\"Collection Subscribed Successfully\", { position: \"top-center\"});\n            setLoader(false);\n            return resp;\n        }catch(e: any) {\n            setLoader(false);\n            toast(e.message || \"Something went wrong!\", { position: \"top-center\", type: \"error\"});\n            return false;\n        }\n    }\n\n    const onUnSubscribeHandler = async (collectionId: string) => {\n        try {\n            setLoader(true);\n            const resp = await dispatch(unSubscribeCollectionById(collectionId)).unwrap();\n            toast(\"Collection Unsubscribed Successfully\", { position: \"top-center\"});\n            setLoader(false);\n            return resp;\n        }catch(e: any) {\n            setLoader(false);\n            let message = e.message || \"Something went wrong!\";\n            toast(message, { position: \"top-center\"});\n            return false;\n        }\n    }\n\n\n   return <CollectionBookmarksPageWrapper\n        collection={getCollectionByIdState.collection}\n        customer={getCustomerByIdState.customer}\n        bookmarksState={getPublicCollectionBookmarksState}\n        onClickNextPage={onClickNextPageHandler}\n        onClickPrevPage={onClickPrevPageHandler}\n        onSearch={onSearchHandler}\n        onSubscribe={onSubscribeHandler}\n        onUnsubscribe={onUnSubscribeHandler}\n        isCollectionSubscribed={isCollectionSubscribedState.isSubscribed}\n        isSignedIn={authState.isSignedIn}\n        currentLoggedInCustomer={authState.customer}\n   />\n}\n\nexport default ViewCollectionBookmarks;"
  },
  {
    "path": "aquila/view/pages/explore.tsx",
    "content": "import { FC } from \"react\";\nimport { useSelector } from \"react-redux\";\n\nimport ExplorePageWrapper from \"../components/pages/explore/ExplorePageWrapper\";\nimport { Collection } from \"../store/slices/types/Collection\";\nimport { wrapper } from '../store/index';\nimport api from \"../utils/api\";\nimport { selectGetFeaturedCollections, setGetFeaturedCollections } from '../store/slices/collection/getFeaturedCollections';\nimport { selectGetAllPublicCollections, setGetAllPublicCollections } from \"../store/slices/collection/getAllPublicCollections\";\n\ninterface ExplorePageProps {\n    featuredCollections: {\n        totalRecords: number;\n        totalPages: number;\n        limit: number;\n        collections: Collection[]\n    }\n}\n\nconst ExplorePage: FC<ExplorePageProps> = (props) => {\n    const featuredCollectionsSate = useSelector(selectGetFeaturedCollections);\n    const publicCollectionsState = useSelector(selectGetAllPublicCollections);\n    return (\n        <ExplorePageWrapper\n            publicCollectionsState={publicCollectionsState}\n            featuredCollectionsState={featuredCollectionsSate}\n        />\n    )\n}\n\nexport const getStaticProps = wrapper.getStaticProps((store) => async () => {\n    const response = await api.get('/collection/public/featured');\n    const featuredCollections = response.data;\n    const publicCollectionsResp = await api.get('/collection/public');\n    const publicCollections = publicCollectionsResp.data;\n    store.dispatch(setGetFeaturedCollections(featuredCollections))\n    store.dispatch(setGetAllPublicCollections(publicCollections))\n    return {\n        props: {},\n        revalidate: 600\n    }\n})\n\nexport default ExplorePage;"
  },
  {
    "path": "aquila/view/pages/home.tsx",
    "content": "import { useEffect, useState } from \"react\";\nimport { toast } from \"react-toastify\";\nimport HomePageWrapper from \"../components/pages/home/HomePageWrapper\";\nimport { useProgressLoader } from \"../components/ui/progressLoader/ProgressLoader\";\nimport { useAppSelector, useAppDispatch } from \"../store\";\nimport {getLoggedInCustBookmarksByCollectionId, GetLoggedInCustBookmarksByCollectionIdInputOptions, selectGetLoggedInCustBookmarksByCollectionId } from \"../store/slices/bookmark/getLoggedInCustBookmarksByCollectionId\";\nimport { selectGetLoggedInCustCollections } from \"../store/slices/collection/getLoggedInCustCollections\";\nimport { isCollectionSubscribed, selectIsCollectionSubscribed } from \"../store/slices/collection/isCollectionSubscribed\";\nimport { selectSubscribeCollectionById, subscribeCollectionById } from \"../store/slices/collection/subscribeCollectionById\";\nimport { selectUnSubscribeCollectionById, unSubscribeCollectionById } from \"../store/slices/collection/unSubscribeCollectionById\";\nimport { getCurrentLoggedInCustomer, selectGetCurrentLoggedInCustomer } from \"../store/slices/customer/getCurrentLoggedInCustomer\";\n\nconst HomePage = () => {\n    const currentLoggedInCustomerState = useAppSelector(selectGetCurrentLoggedInCustomer);\n    const getLoggedInCustCollections = useAppSelector(selectGetLoggedInCustCollections)\n    const getLoggedInCustBookmarksState = useAppSelector(selectGetLoggedInCustBookmarksByCollectionId);\n    const isCollectionSubscribedState = useAppSelector(selectIsCollectionSubscribed);\n    const subscribeCollectionByIdState = useAppSelector(selectSubscribeCollectionById);\n    const unSubscribeCollectionByIdState = useAppSelector(selectUnSubscribeCollectionById);\n\n    const dispatch = useAppDispatch();\n    const [query, setQuery] = useState<string | null>(null);\n    const [currentPage, setCurrentPage] = useState(1);\n    const { setLoader } = useProgressLoader();\n\n    useEffect(() => {\n        dispatch(getCurrentLoggedInCustomer())\n    }, [dispatch])\n\n    useEffect(() => {\n        if(getLoggedInCustCollections.collecitons) {\n            dispatch((isCollectionSubscribed( getLoggedInCustCollections.collecitons[0].id)))\n        }\n    }, [dispatch, getLoggedInCustCollections.collecitons, subscribeCollectionByIdState.collectionSubscription, unSubscribeCollectionByIdState.collectionSubscription])\n\n    useEffect(() => {\n        if(getLoggedInCustCollections.collecitons && getLoggedInCustCollections.collecitons.length > 0) {\n            const options: GetLoggedInCustBookmarksByCollectionIdInputOptions = {\n                collectionId: getLoggedInCustCollections.collecitons[0].id,\n                page: currentPage\n            }\n            if(query) {\n                options.query = query;\n            }\n            dispatch(getLoggedInCustBookmarksByCollectionId(options))\n        }\n    }, [dispatch, getLoggedInCustCollections.collecitons, query, currentPage])\n\n    const onSearchHandler = (data: string) => {\n        if(data) {\n            setQuery(data);\n            setCurrentPage(1);\n        }else {\n            setQuery(null);\n        }\n    }\n\n    const onClickNextPageHandler = () => {\n        setCurrentPage(currentPage + 1)\n    }\n\n    const onClickPrevPageHandler = () => {\n        setCurrentPage(currentPage - 1)\n    }\n\n    const onSubscribeHandler =  async (collectionId: string) => {\n        try {\n            setLoader(true);\n            const resp = await dispatch(subscribeCollectionById(collectionId)).unwrap();\n            toast(\"Collection Subscribed Successfully\", { position: \"top-center\"});\n            setLoader(false);\n            return resp;\n        }catch(e: any) {\n            setLoader(false);\n            toast(e.message || \"Something went wrong!\", { position: \"top-center\", type: \"error\"});\n            return false;\n        }\n    }\n\n    const onUnSubscribeHandler = async (collectionId: string) => {\n        try {\n            setLoader(true);\n            const resp = await dispatch(unSubscribeCollectionById(collectionId)).unwrap();\n            toast(\"Collection Unsubscribed Successfully\", { position: \"top-center\"});\n            setLoader(false);\n            return resp;\n        }catch(e: any) {\n            setLoader(false);\n            let message = e.message || \"Something went wrong!\";\n            toast(message, { position: \"top-center\"});\n            return false;\n        }\n    }\n\n    return (\n        <HomePageWrapper \n            collection={getLoggedInCustCollections.collecitons && getLoggedInCustCollections.collecitons.length > 0 ? getLoggedInCustCollections.collecitons[0] : null}\n            customer={currentLoggedInCustomerState.customer}\n            bookmarksState={getLoggedInCustBookmarksState}\n            onSubscribe={onSubscribeHandler}\n            onUnsubscribe={onUnSubscribeHandler}\n            isCollectionSubscribed={isCollectionSubscribedState.isSubscribed}\n            onClickNextPage={onClickNextPageHandler}\n            onClickPrevPage={onClickPrevPageHandler}\n            onSearch={onSearchHandler}\n        />\n    );\n}\n\n// export const getServerSideProps = wrapper.getServerSideProps(store=> async (ctx) => {\n//     const session = await unstable_getServerSession(ctx.req, ctx.res, authOptions);\n//     if(session) {\n//         store.dispatch(signIn({  token: session?.user.token, accountStatus: session?.user.accountStatus, customer: {\n//             firstName: session?.user.firstName,\n//             lastName: session?.user.lastName,\n//             customerId: session?.user.customerId\n//         }}))\n//     }\n//     return {props: {}};\n// });\nexport default HomePage;"
  },
  {
    "path": "aquila/view/pages/index.tsx",
    "content": "import type { NextPage } from 'next'\nimport IndexPageWrapper from '../components/pages/index/IndexPageWrapper';\n\nconst IndexPage: NextPage = () => {\n  return (\n    <IndexPageWrapper />\n  );\n}\n\nexport default IndexPage;\n"
  },
  {
    "path": "aquila/view/pages/sign-in.tsx",
    "content": "import { NextPage } from \"next\";\nimport SignInPageWrapper from \"../components/pages/signIn/SignInPageWrapper\";\nimport { signIn } from 'next-auth/react';\nimport { useRouter } from \"next/router\";\nimport { useEffect } from \"react\";\nimport { toast } from \"react-toastify\";\n\nimport { useAppSelector } from \"../store\";\nimport { selectAuth } from \"../store/slices/auth\";\nimport { useProgressLoader } from \"../components/ui/progressLoader/ProgressLoader\";\n\nconst SignInPage: NextPage = () => {\n\tconst router = useRouter();\n\n\tconst authState = useAppSelector(selectAuth);\n\tconst { setLoader } = useProgressLoader();\n\n\tuseEffect(() => {\n\t\tif(authState.isSignedIn) {\n\t\t\trouter.push('/home');\n\t\t}\t\n\t},[router, authState]);\n\n\tconst signInHandler = async (secretKey: string) => {\n\t\tsetLoader(true);\n\t\tconst resp = await signIn('credentials',{ redirect: false, secretKey });\n\t\tif(resp?.ok) {\n\t\t\trouter.push('/home');\n\t\t\tsetLoader(false);\n\t\t\treturn;\n\t\t}\n\t\ttoast(\"Invalid credentials\", { type: \"error\", position: \"top-center\"});\n\t\tsetLoader(false);\n\t}\t\n\n\treturn <SignInPageWrapper onSignIn={signInHandler}  />\n}\n\nexport default SignInPage;"
  },
  {
    "path": "aquila/view/pages/sign-up.tsx",
    "content": "import { NextPage } from \"next\";\nimport { signIn } from \"next-auth/react\";\nimport { useRouter } from \"next/router\";\nimport { useEffect, useState } from \"react\";\nimport { toast, ToastOptions } from 'react-toastify';\n\nimport SignUpPageWrapper from \"../components/pages/signUp/SignUpPageWrapper\";\nimport { useProgressLoader } from \"../components/ui/progressLoader/ProgressLoader\";\nimport { useAppDispatch, useAppSelector } from \"../store\";\nimport { selectAuth } from \"../store/slices/auth\";\nimport { fetchNames, removeGeneratedNames, selectGeneratedName } from \"../store/slices/generateName\";\nimport { selectSignUp, signUp } from \"../store/slices/signup\";\n\nconst SignUpPage: NextPage = () => {\n\tconst dispatch = useAppDispatch();\n\tconst router = useRouter();\n\tconst authState = useAppSelector(selectAuth);\n\tconst signUpState = useAppSelector(selectSignUp);\n\tconst [accountCreated, setAccountCreated] = useState(false);\n\tconst { setLoader } = useProgressLoader();\n\n\tuseEffect(() => {\n\t\tif(authState.isSignedIn && !accountCreated) {\n\t\t\trouter.replace('/home');\n\t\t}\n\t}, [router, authState])\n\n\tuseEffect(() => {\n\t\tdispatch(fetchNames());\n\t\treturn () => {\n\t\t\tdispatch(removeGeneratedNames());\n\t\t}\n\t}, [dispatch])\n\n\t\n\n\tconst generatedName = useAppSelector(selectGeneratedName);\n\n\tconst signUpHandler = async (data: any) => {\n\t\tconst toastOptions: ToastOptions = {\n\t\t\tposition: \"top-center\",\n\t\t\thideProgressBar: true,\n\t\t}\n\t\tsetLoader(true);\n\t\ttry{\n\t\t\tconst signUpResult = await dispatch(signUp(data)).unwrap()\n\t\t\tsetLoader(false);\n\t\t\ttoast(\"Account Genreated\", { ...toastOptions, type: \"success\"})\n\t\t\tconst result = await signIn(\"credentials\", {secretKey: signUpResult.secretKey, redirect: false});\n\t\t\tdebugger;\n\t\t\tif(result?.ok) {\n\t\t\t\tsetAccountCreated(true);\n\t\t\t}\n\t\t\treturn true;\n\t\t}catch(e: any) {\n\t\t\tdebugger;\n\t\t\tsetLoader(false);\n\t\t\ttoast(e.message, { ...toastOptions, type: \"error\"});\n\t\t\treturn false;\n\t\t}\n\t} \n\n\treturn (\n\t\t<SignUpPageWrapper\n\t\t\tonSignUp={signUpHandler}\n\t\t\tsignUpState={signUpState}\n\t\t\tname={{firstName: generatedName.firstName, lastName: generatedName.lastName}}\n\t\t\taccountCreated={accountCreated}\n\t\t/>\n\t);\n}\n\nexport default SignUpPage;"
  },
  {
    "path": "aquila/view/pages/subscription.tsx",
    "content": "import { useEffect, useState } from \"react\";\n\nimport SubscriptionPageWrapper from \"../components/pages/subscription/SubscriptionPageWrapper\";\nimport { useAppSelector, useAppDispatch } from \"../store\";\nimport { getCustomerSubscriptions, GetCustomerSubscriptionsInputOptions, selectGetCustomerSubscriptions } from \"../store/slices/collection/getCustomerSubscriptions\";\nimport { getSubscribedCollections, selectGetSubscribedCollections } from \"../store/slices/collection/getSubscribedCollections\";\n\nconst SubscriptionPage = () => {\n    const getCustomerSubscriptionsState = useAppSelector(selectGetCustomerSubscriptions);\n    const getSubscribedCollectionsState = useAppSelector(selectGetSubscribedCollections);\n    const dispatch = useAppDispatch();\n    const [query, setQuery] = useState<string | null>(null);\n    const [currentPage, setCurrentPage] = useState(1);\n\n    useEffect(() => {\n        dispatch(getSubscribedCollections())\n    }, [dispatch])\n\n    useEffect(() => {\n            const options: GetCustomerSubscriptionsInputOptions = {\n                page: currentPage\n            }\n            if(query) {\n                options.query = query;\n            }\n            dispatch(getCustomerSubscriptions(options))\n    }, [dispatch, query, currentPage])\n\n    const onSearchHandler = (data: string) => {\n        if(data) {\n            setQuery(data);\n            setCurrentPage(1);\n        }else {\n            setQuery(null);\n        }\n    }\n\n    const onClickNextPageHandler = () => {\n        setCurrentPage(currentPage + 1)\n    }\n\n    const onClickPrevPageHandler = () => {\n        setCurrentPage(currentPage - 1)\n    }\n\n    return (\n        <SubscriptionPageWrapper\n            subscribedCollections={getSubscribedCollectionsState.collecitons}\n            bookmarksState={getCustomerSubscriptionsState}\n            onClickNextPage={onClickNextPageHandler}\n            onClickPrevPage={onClickPrevPageHandler}\n            onSearch={onSearchHandler}\n        />\n    )\n}\n\nexport default SubscriptionPage;"
  },
  {
    "path": "aquila/view/pages/test.tsx",
    "content": "const TestPage = () => {\n    return <h1>Protected</h1>;\n}\n\nexport default TestPage;"
  },
  {
    "path": "aquila/view/store/index.ts",
    "content": "import { Action, configureStore, ThunkAction } from \"@reduxjs/toolkit\"\nimport { createWrapper } from \"next-redux-wrapper\";\nimport { TypedUseSelectorHook, useDispatch, useSelector } from \"react-redux\";\n\nimport authReducer from './slices/auth';\nimport getCurrentLoggedInCustomerReducer from \"./slices/customer/getCurrentLoggedInCustomer\";\nimport generatedNameReducer from './slices/generateName';\nimport signUpReducer from './slices/signup';\nimport addLinkReducer from './slices/bookmark/addLink';\nimport getLoggedInCustCollectionsReducer from './slices/collection/getLoggedInCustCollections';\nimport activateCustomerReducer from './slices/customer/activateCustomer';\nimport updateCustomerReducer from './slices/customer/updateCustomer';\nimport getFeaturedCollectionsReducer from \"./slices/collection/getFeaturedCollections\";\nimport getLoggedInCustBookmarksByCollectionIdReducer from \"./slices/bookmark/getLoggedInCustBookmarksByCollectionId\";\nimport getPublicBookmarksByCollectionIdReducer from \"./slices/bookmark/getPublicBookmarksByCollectionId\";\nimport getCustomerByIdReducer from './slices/customer/getCustomerById';\nimport getCollectionByIdReducer from './slices/collection/getCollectionById';\nimport subscribeCollectionByIdReducer from './slices/collection/subscribeCollectionById';\nimport isCollectionSubscribedReducer from './slices/collection/isCollectionSubscribed';\nimport unSubscribbeCollectionByIdReducer from './slices/collection/unSubscribeCollectionById';\nimport getAllPublicCollectionsReducer from \"./slices/collection/getAllPublicCollections\";\nimport getCustomerSubscriptionsReducer from './slices/collection/getCustomerSubscriptions';\nimport getSubscribedCollectionsReducer from './slices/collection/getSubscribedCollections';\n\nexport const createStore = () => {\n\treturn configureStore({\n\t\treducer: {\n\t\t\tauth: authReducer,\n\t\t\tgeneratedName: generatedNameReducer,\n\t\t\tsignUp: signUpReducer,\n\t\t\tgetCurrentLoggedInCustomer: getCurrentLoggedInCustomerReducer,\n\t\t\taddLink: addLinkReducer,\n\t\t\tgetLoggedInCustCollections: getLoggedInCustCollectionsReducer,\n\t\t\tactivateCustomer: activateCustomerReducer,\n\t\t\tupdateCustomer: updateCustomerReducer,\n\t\t\tgetFeaturedCollections: getFeaturedCollectionsReducer,\n\t\t\tgetLoggedInCustBookmarksByCollectionId: getLoggedInCustBookmarksByCollectionIdReducer,\n\t\t\tgetPublicBookmarksByCollectionId: getPublicBookmarksByCollectionIdReducer,\n\t\t\tgetCustomerById: getCustomerByIdReducer,\n\t\t\tgetCollectionById: getCollectionByIdReducer,\n\t\t\tsubscribeCollectionById: subscribeCollectionByIdReducer,\n\t\t\tisCollectionSubscribed: isCollectionSubscribedReducer,\n\t\t\tunSubscribeCollectionById: unSubscribbeCollectionByIdReducer,\n\t\t\tgetAllPublicCollections: getAllPublicCollectionsReducer,\n\t\t\tgetCustomerSubscriptions: getCustomerSubscriptionsReducer,\n\t\t\tgetSubscribedCollections: getSubscribedCollectionsReducer,\n\t\t},\n\t\tmiddleware: (getDefaultMiddleware) => getDefaultMiddleware({\n\t\t\tserializableCheck: false\n\t\t})\n\t});\n}\n\nexport const store = createStore();\n\nexport type AppStore = ReturnType<typeof createStore>;\n\nexport type AppState = ReturnType<AppStore['getState']>;\n\nexport type AppDispatch = typeof store.dispatch; \n\nexport type AppThunk<ReturnType = void> = ThunkAction<ReturnType, AppState, unknown, Action<string>>\n\nexport const useAppDispatch = () => useDispatch<AppDispatch>()\n\nexport const useAppSelector: TypedUseSelectorHook<AppState> = useSelector;\n\nexport const wrapper = createWrapper<AppStore>(createStore);\n"
  },
  {
    "path": "aquila/view/store/slices/auth.ts",
    "content": "import { createSlice, PayloadAction } from \"@reduxjs/toolkit\";\nimport { HYDRATE } from \"next-redux-wrapper\";\nimport { AppState } from \"..\";\n\nexport interface AuthState {\n\tisSignedIn: boolean | null;\n\ttoken: string | null;\n\taccountStatus: string | null;\n\tcustomer: {\n\t\tcustomerId: string;\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tcreatedAt: string;\n\t} | null;\n\tstatus: 'idle' | 'pending' | 'succeeded' | 'failed';\n}\n\ninterface SignInPayloadAction {\n\ttoken: string;\n\taccountStatus: string;\n\tcustomer: {\n\t\tcustomerId: string;\n\t\tfirstName: string;\n\t\tlastName: string;\n\t\tcreatedAt: string;\n\t}\n}\n\nconst initialState: AuthState = {\n\tisSignedIn: null,\n\ttoken: null,\n\taccountStatus: null,\n\tcustomer: null,\n\tstatus: 'idle'\n}\n\nexport const authSlice = createSlice({\n\tname: 'auth',\n\tinitialState,\n\treducers: {\n\t\tsignIn: (state, action: PayloadAction<SignInPayloadAction>) => {\n\t\t\tstate.isSignedIn = true;\n\t\t\tstate.customer = action.payload.customer;\n\t\t\tstate.token = action.payload.token;\n\t\t\tstate.accountStatus = action.payload.accountStatus;\n\t\t\tstate.status = \"succeeded\";\n\t\t},\n\t\tsignOut: (state) => {\n\t\t\tstate.isSignedIn = false\n\t\t\tstate.token = null;\n\t\t\tstate.customer = null;\n\t\t\tstate.accountStatus = null;\n\t\t\tstate.status = \"succeeded\";\n\t\t}\n\t},\n\textraReducers: {\n\t\t[HYDRATE]: (state, action) => {\n\t\t\tif(action.payload.auth.status !== \"idle\") {\n\t\t\t\treturn {\n\t\t\t\t\t...state,\n\t\t\t\t\t...action.payload.auth\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\nexport const { signIn,  signOut} = authSlice.actions;\n\nexport const selectAuth = (state: AppState) => state.auth\n\nexport default authSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/bookmark/addLink.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\n\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { AsyncThunkSubmissionError } from \"../errors/AsyncThunkSubmissionError\";\nimport { Bookmark } from \"../types/Bookmark\";\nimport { ValidationErrors } from \"../types/validationErrors\";\nimport { createSubmissionErrorFromErrObj } from \"../utils/createError\";\n\n\n\nexport interface AddLinkData {\n    url: string;\n    collectionId: string;\n}\n\ntype AddLinkReqPayload = AddLinkData;\n\ntype AddLinkResPayload = Bookmark;\n\ntype AddLinkValidationErrors = ValidationErrors<AddLinkReqPayload>;\n\ninterface AddLinkState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    bookmark: null | Bookmark;\n    errorMessage: null |string;\n    errors: AddLinkValidationErrors | null;\n}\n\nconst initialState: AddLinkState = {\n    status: 'idle',\n    bookmark: null,\n    errorMessage: null,\n    errors: null\n}\n\nexport const addLink = createAsyncThunk<Bookmark, AddLinkData, { rejectValue: AsyncThunkSubmissionError<AddLinkValidationErrors | null>}>('/bookmark/add-link', async (data, thunkApi) => {\n    try {\n        const res = await api.post<AddLinkResPayload>('/bookmark', data);\n        return res.data;\n    } catch(e) {\n        let err: AsyncThunkSubmissionError<AddLinkValidationErrors | null>= new AsyncThunkSubmissionError(\"Something went wrong\", null);\n        if(e instanceof Error) {\n            err = createSubmissionErrorFromErrObj<AddLinkValidationErrors>(e); \n        }\n        return thunkApi.rejectWithValue(err);\n    }\n});\n\nexport const addLinkSlice = createSlice({\n    name: 'addLink',\n    initialState,\n    reducers: {},\n    extraReducers: async (builder) => {\n        builder.addCase(addLink.pending, (state, action) => {\n            state.bookmark = null;\n            state.errorMessage = null;\n            state.errors = null;\n            state.status = \"pending\";\n        })\n\n        builder.addCase(addLink.fulfilled, (state, action) => {\n            state.bookmark = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n            state.errors = null;\n        })\n\n        builder.addCase(addLink.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || null;\n            state.bookmark = null;\n            if(action.payload) {\n                state.errorMessage = action.payload.message;\n                state.errors = action.payload.validationErrors;\n            }\n        })\n    }\n})\n\n\nexport const selectAddLink = (state: AppState) => state.addLink;\n\nexport default addLinkSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/bookmark/getLoggedInCustBookmarksByCollectionId.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Bookmark } from \"../types/Bookmark\";\n\n\ninterface GetLoggedInCustBookmarksByCollectionIdState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    bookmarks: null | Bookmark[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    query: string | null;\n    errorMessage: null | string;\n}\n\ninterface GetLoggedInCustBookmarksByCollectionIdData {\n    bookmarks: null | Bookmark[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    query: string | null;\n}\n\ntype GetLoggedInCustBookmarksByCollectionIdResPayload = Omit<GetLoggedInCustBookmarksByCollectionIdData, \"query\">;\n\nexport interface GetLoggedInCustBookmarksByCollectionIdInputOptions {\n    collectionId: string;\n    limit?: number;\n    query?: string;\n    page?: number;\n}\n\nexport const getLoggedInCustBookmarksByCollectionId = createAsyncThunk<GetLoggedInCustBookmarksByCollectionIdData, GetLoggedInCustBookmarksByCollectionIdInputOptions>('/bookmarks/collection/search', async (options: GetLoggedInCustBookmarksByCollectionIdInputOptions) => {\n    try{\n        const resp = await api.get<GetLoggedInCustBookmarksByCollectionIdResPayload>(`/bookmark/${options.collectionId}/search`, {params: options});\n        return {\n            ...resp.data,\n            query: options.query || null\n        }\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetLoggedInCustBookmarksByCollectionIdState = {\n    status: 'idle',\n    bookmarks: null,\n    totalPages: null,\n    totalRecords: null,\n    currentPage: null,\n    limit: null,\n    query: null,\n    errorMessage: null\n}\n\nconst getLoggedInCustBookmarksByCollectionIdSlice = createSlice({\n    name: 'getBookmarksByCollectionId',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getLoggedInCustBookmarksByCollectionId.pending, (state) => {\n            state.status = 'pending';\n            state.bookmarks = null;\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.query = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getLoggedInCustBookmarksByCollectionId.fulfilled, (state, action) => {\n            state.status = 'succeeded';\n            state.bookmarks = action.payload.bookmarks;\n            state.totalRecords = action.payload.totalRecords;\n            state.totalPages = action.payload.totalPages;\n            state.limit = action.payload.limit;\n            state.query = action.payload.query;\n            state.currentPage = action.payload.currentPage;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getLoggedInCustBookmarksByCollectionId.rejected, (state, action) => {\n            state.status = 'failed';\n            state.bookmarks = null;\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.query = null;\n            state.errorMessage = action.error.message || \"Something went wrong\";\n        });\n    }\n})\n\n\nexport const selectGetLoggedInCustBookmarksByCollectionId = (state: AppState) => state.getLoggedInCustBookmarksByCollectionId;\n\nexport default getLoggedInCustBookmarksByCollectionIdSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/bookmark/getPublicBookmarksByCollectionId.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Bookmark } from \"../types/Bookmark\";\n\n\ninterface GetPublicBookmarksByCollectionIdState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    bookmarks: null | Bookmark[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    query: string | null;\n    errorMessage: null | string;\n}\n\ninterface GetPublicBookmarksByCollectionIdData {\n    bookmarks: null | Bookmark[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    query: string | null;\n}\n\ntype GetPublicBookmarksByCollectionIdResPayload = Omit<GetPublicBookmarksByCollectionIdData, \"query\">;\n\nexport interface GetPublicBookmarksByCollectionIdInputOptions {\n    collectionId: string;\n    limit?: number;\n    query?: string;\n    page?: number;\n}\n\nexport const getPublicBookmarksByCollectionId = createAsyncThunk<GetPublicBookmarksByCollectionIdData, GetPublicBookmarksByCollectionIdInputOptions>('/bookmarks/public/collection/search', async (options: GetPublicBookmarksByCollectionIdInputOptions) => {\n    try{\n        const resp = await api.get<GetPublicBookmarksByCollectionIdResPayload>(`/bookmark/public/${options.collectionId}/search`, {params: options});\n        return {\n            ...resp.data,\n            query: options.query || null\n        }\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetPublicBookmarksByCollectionIdState = {\n    status: 'idle',\n    bookmarks: null,\n    totalPages: null,\n    totalRecords: null,\n    currentPage: null,\n    limit: null,\n    query: null,\n    errorMessage: null\n}\n\nconst getPublicBookmarksByCollectionIdSlice = createSlice({\n    name: 'getBookmarksByCollectionId',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getPublicBookmarksByCollectionId.pending, (state) => {\n            state.status = 'pending';\n            state.bookmarks = null;\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.query = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getPublicBookmarksByCollectionId.fulfilled, (state, action) => {\n            state.status = 'succeeded';\n            state.bookmarks = action.payload.bookmarks;\n            state.totalRecords = action.payload.totalRecords;\n            state.totalPages = action.payload.totalPages;\n            state.limit = action.payload.limit;\n            state.query = action.payload.query;\n            state.currentPage = action.payload.currentPage;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getPublicBookmarksByCollectionId.rejected, (state, action) => {\n            state.status = 'failed';\n            state.bookmarks = null;\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.query = null;\n            state.errorMessage = action.error.message || \"Something went wrong\";\n        });\n    }\n})\n\n\nexport const selectGetPublicBookmarksByCollectionId = (state: AppState) => state.getPublicBookmarksByCollectionId;\n\nexport default getPublicBookmarksByCollectionIdSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/getAllPublicCollections.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { HYDRATE } from \"next-redux-wrapper\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Collection } from \"../types/Collection\";\n\n\ninterface GetAllPublicCollectionsState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collections: null | Collection[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    errorMessage: null | string;\n}\n\ninterface GetAllPublicCollectionsData {\n    collections: Collection[];\n    totalPages: number;\n    totalRecords: number;\n    currentPage: number;\n    limit: number\n}\n\ntype GetAllPublicCollectionsResPayload  = GetAllPublicCollectionsData;\n\nexport const getAllPublicCollections = createAsyncThunk<GetAllPublicCollectionsData>('/collection/public/all', async () => {\n    try{\n        const resp = await api.get<GetAllPublicCollectionsResPayload>('/collection/');\n        return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetAllPublicCollectionsState = {\n    status: 'idle',\n    collections: null,\n    totalPages: null,\n    totalRecords: null,\n    currentPage: null,\n    limit: null,\n    errorMessage: null\n}\n\nconst getAllPublicCollectionsSlice = createSlice({\n    name: 'getAllPublicCollections',\n    initialState,\n    reducers: {\n        setGetAllPublicCollections: (state, action) => {\n            state.status = 'succeeded';\n            state.collections = action.payload.collections;\n            state.totalPages = action.payload.totalPages;\n            state.totalRecords = action.payload.totalRecords;\n            state.currentPage = action.payload.currentPage;\n            state.limit = action.payload.currentPage;\n            state.errorMessage = null;\n        }\n    },\n    extraReducers: {\n\n        [HYDRATE]: (state, action) => {\n            if(action.payload.status !== 'idle') {\n                state.status = 'succeeded';\n                state.collections = action.payload.getAllPublicCollections.collections;\n                state.totalPages = action.payload.getAllPublicCollections.totalPages;\n                state.totalRecords = action.payload.getAllPublicCollections.totalRecords;\n                state.currentPage = action.payload.getAllPublicCollections.currentPage;\n                state.limit = action.payload.getAllPublicCollections.limit; \n                return state;\n            }\n        },\n\n        [getAllPublicCollections.pending as unknown as string]: (state) => {\n            state.status = 'pending';\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.collections = null;\n            state.errorMessage = null;\n            return state;\n        },\n\n        [getAllPublicCollections.fulfilled as unknown as string]: (state, action) => {\n            state.status = 'succeeded';\n            state.collections = action.payload.collections;\n            state.totalPages = action.payload.totalPages;\n            state.totalRecords = action.payload.totalRecords;\n            state.currentPage = action.payload.currentPage;\n            state.limit = action.payload.limit;\n            state.errorMessage = null;\n            return state;\n        },\n\n        [getAllPublicCollections.rejected as unknown as string]:  (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || \"Something went wrong\";\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.collections = null;\n            return state;\n        }\n    }\n})\n\n\nexport const selectGetAllPublicCollections = (state: AppState) => state.getAllPublicCollections;\n\nexport const { setGetAllPublicCollections } = getAllPublicCollectionsSlice.actions;\n\nexport default getAllPublicCollectionsSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/getCollectionById.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Collection } from \"../types/Collection\";\n\ninterface GetCollectionByIdState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collection: null | Collection;\n    errorMessage: null |string;\n}\n\nconst initialState: GetCollectionByIdState = {\n    status: 'idle',\n    collection: null,\n    errorMessage: null\n}\n\nexport const getCollectionById = createAsyncThunk<Collection, string>('/collection/public/collectionId', async (collectionId: string) => {\n    try{\n    const resp = await api.get<Collection>(`/collection/public/${collectionId}`);\n    return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nexport const getCollectionByIdSlice = createSlice({\n    name: 'getCollectionByid',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getCollectionById.pending, (state) => {\n            state.status = 'pending';\n            state.collection = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getCollectionById.fulfilled, (state, action) => {\n            state.collection = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n        });\n        \n        builder.addCase(getCollectionById.rejected, (state, action) => {\n            state.status = \"failed\",\n            state.errorMessage = action.error.message || \"Something went wrong\",\n            state.collection = null;\n        })\n    }\n});\n\n\nexport const selectGetCollectionById = (state: AppState) => state.getCollectionById;\n\nexport default getCollectionByIdSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/getCustomerSubscriptions.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Bookmark } from \"../types/Bookmark\";\n\n\ninterface GetCustomerSubscriptionsState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    bookmarks: null | Bookmark[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    query: string | null;\n    errorMessage: null | string;\n}\n\ninterface GetCustomerSubscriptionsData {\n    bookmarks: null | Bookmark[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    query: string | null;\n}\n\ntype GetCustomerSubscriptionsResPayload = Omit<GetCustomerSubscriptionsData, \"query\">;\n\nexport interface GetCustomerSubscriptionsInputOptions {\n    limit?: number;\n    query?: string;\n    page?: number;\n}\n\nexport const getCustomerSubscriptions = createAsyncThunk<GetCustomerSubscriptionsData, GetCustomerSubscriptionsInputOptions>('/subscription', async (options: GetCustomerSubscriptionsInputOptions) => {\n    try{\n        const resp = await api.get<GetCustomerSubscriptionsResPayload>(`/subscription`, {params: options});\n        return {\n            ...resp.data,\n            query: options.query || null\n        }\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetCustomerSubscriptionsState = {\n    status: 'idle',\n    bookmarks: null,\n    totalPages: null,\n    totalRecords: null,\n    currentPage: null,\n    limit: null,\n    query: null,\n    errorMessage: null\n}\n\nconst getCustomerSubscriptionsSlice = createSlice({\n    name: 'getBookmarksByCollectionId',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getCustomerSubscriptions.pending, (state) => {\n            state.status = 'pending';\n            state.bookmarks = null;\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.query = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getCustomerSubscriptions.fulfilled, (state, action) => {\n            state.status = 'succeeded';\n            state.bookmarks = action.payload.bookmarks;\n            state.totalRecords = action.payload.totalRecords;\n            state.totalPages = action.payload.totalPages;\n            state.limit = action.payload.limit;\n            state.query = action.payload.query;\n            state.currentPage = action.payload.currentPage;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getCustomerSubscriptions.rejected, (state, action) => {\n            state.status = 'failed';\n            state.bookmarks = null;\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.query = null;\n            state.errorMessage = action.error.message || \"Something went wrong\";\n        });\n    }\n})\n\n\nexport const selectGetCustomerSubscriptions = (state: AppState) => state.getCustomerSubscriptions;\n\nexport default getCustomerSubscriptionsSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/getFeaturedCollections.ts",
    "content": "import { createAsyncThunk, createSlice, PayloadAction } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { HYDRATE } from \"next-redux-wrapper\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Collection } from \"../types/Collection\";\n\n\ninterface GetFeaturedCollectionsState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collections: null | Collection[];\n    totalPages: number | null;\n    totalRecords: number | null;\n    currentPage: number | null;\n    limit: number | null;\n    errorMessage: null | string;\n}\n\ninterface GetFeaturedCollectionsData {\n    collections: Collection[];\n    totalPages: number;\n    totalRecords: number;\n    currentPage: number;\n    limit: number\n}\n\ntype GetFeaturedCollectionsResPayload  = GetFeaturedCollectionsData;\n\nexport const getFeaturedCollections = createAsyncThunk<GetFeaturedCollectionsData>('/collection/public/featured', async () => {\n    try{\n        const resp = await api.get<GetFeaturedCollectionsResPayload>('/collection/my-collections');\n        return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetFeaturedCollectionsState = {\n    status: 'idle',\n    collections: null,\n    totalPages: null,\n    totalRecords: null,\n    currentPage: null,\n    limit: null,\n    errorMessage: null\n}\n\nconst getFeaturedCollectionsSlice = createSlice({\n    name: 'getFeaturedCollections',\n    initialState,\n    reducers: {\n        setGetFeaturedCollections: (state, action) => {\n            state.status = 'succeeded';\n            state.collections = action.payload.collections;\n            state.totalPages = action.payload.totalPages;\n            state.totalRecords = action.payload.totalRecords;\n            state.currentPage = action.payload.currentPage;\n            state.limit = action.payload.currentPage;\n            state.errorMessage = null;\n        }\n    },\n    extraReducers: {\n\n        [HYDRATE]: (state, action) => {\n            if(action.payload.status !== 'idle') {\n                state.status = 'succeeded';\n                state.collections = action.payload.getFeaturedCollections.collections;\n                state.totalPages = action.payload.getFeaturedCollections.totalPages;\n                state.totalRecords = action.payload.getFeaturedCollections.totalRecords;\n                state.currentPage = action.payload.getFeaturedCollections.currentPage;\n                state.limit = action.payload.getFeaturedCollections.limit; \n                return state;\n            }\n        },\n\n        [getFeaturedCollections.pending as unknown as string]: (state) => {\n            state.status = 'pending';\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.collections = null;\n            state.errorMessage = null;\n            return state;\n        },\n\n        [getFeaturedCollections.fulfilled as unknown as string]: (state, action) => {\n            state.status = 'succeeded';\n            state.collections = action.payload.collections;\n            state.totalPages = action.payload.totalPages;\n            state.totalRecords = action.payload.totalRecords;\n            state.currentPage = action.payload.currentPage;\n            state.limit = action.payload.limit;\n            state.errorMessage = null;\n            return state;\n        },\n\n        [getFeaturedCollections.rejected as unknown as string]:  (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || \"Something went wrong\";\n            state.totalPages = null;\n            state.totalRecords = null;\n            state.currentPage = null;\n            state.limit = null;\n            state.collections = null;\n            return state;\n        }\n    }\n})\n\n\nexport const selectGetFeaturedCollections = (state: AppState) => state.getFeaturedCollections;\n\nexport const { setGetFeaturedCollections } = getFeaturedCollectionsSlice.actions;\n\nexport default getFeaturedCollectionsSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/getLoggedInCustCollections.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Collection } from \"../types/Collection\";\n\n\ninterface GetLoggedInCustCollectionsState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collecitons: null | Collection[];\n    errorMessage: null | string;\n}\n\nexport const getLoggedInCustCollections = createAsyncThunk<Collection[]>('/collection/me', async () => {\n    try{\n        const resp = await api.get<Collection[]>('/collection/my-collections');\n        return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetLoggedInCustCollectionsState = {\n    status: 'idle',\n    collecitons: null,\n    errorMessage: null\n}\n\nconst getLoggedInCustCollectionsSlice = createSlice({\n    name: 'getLoggedInCustCollections',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getLoggedInCustCollections.pending, (state) => {\n            state.status = 'pending';\n            state.collecitons = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getLoggedInCustCollections.fulfilled, (state, action) => {\n            state.status = 'succeeded';\n            state.collecitons = action.payload;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getLoggedInCustCollections.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || \"Something went wrong\";\n            state.collecitons = null;\n        });\n    }\n})\n\n\nexport const selectGetLoggedInCustCollections = (state: AppState) => state.getLoggedInCustCollections;\n\nexport default getLoggedInCustCollectionsSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/getSubscribedCollections.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Collection } from \"../types/Collection\";\n\n\ninterface GetSubscribedCollectionsState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collecitons: null | Collection[];\n    errorMessage: null | string;\n}\n\nexport const getSubscribedCollections = createAsyncThunk<Collection[]>('/subscription/collections', async () => {\n    try{\n        const resp = await api.get<Collection[]>('/subscription/collections');\n        return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nconst initialState: GetSubscribedCollectionsState = {\n    status: 'idle',\n    collecitons: null,\n    errorMessage: null\n}\n\nconst getSubscribedCollectionsSlice = createSlice({\n    name: 'getLoggedInCustCollections',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getSubscribedCollections.pending, (state) => {\n            state.status = 'pending';\n            state.collecitons = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getSubscribedCollections.fulfilled, (state, action) => {\n            state.status = 'succeeded';\n            state.collecitons = action.payload;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getSubscribedCollections.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || \"Something went wrong\";\n            state.collecitons = null;\n        });\n    }\n})\n\n\nexport const selectGetSubscribedCollections = (state: AppState) => state.getSubscribedCollections;\n\nexport default getSubscribedCollectionsSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/isCollectionSubscribed.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\n\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { AsyncThunkSubmissionError } from \"../errors/AsyncThunkSubmissionError\";\nimport { CollectionSubscription } from \"../types/CollectionSubscription\";\nimport { ValidationErrors } from \"../types/validationErrors\";\nimport { createSubmissionErrorFromErrObj } from \"../utils/createError\";\n\n\ninterface IsCollectionSubscribedResPayload {\n    isSubscribed: false\n}\n\n\ninterface IsCollectionSubscribedState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    isSubscribed: null | boolean;\n    errorMessage: null |string;\n}\n\nconst initialState: IsCollectionSubscribedState = {\n    status: 'idle',\n    isSubscribed: null,\n    errorMessage: null,\n}\n\nexport const isCollectionSubscribed = createAsyncThunk<boolean, string>('/subscribe/collection-id/is-subscribed', async (collectionId) => {\n    try {\n        const res = await api.post<IsCollectionSubscribedResPayload>(`/subscription/${collectionId}/is-subscribed`);\n        return res.data.isSubscribed;\n    } catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n});\n\nexport const isCollectionSubscribedSlice = createSlice({\n    name: 'subscribeCollectionById',\n    initialState,\n    reducers: {},\n    extraReducers: async (builder) => {\n        builder.addCase(isCollectionSubscribed.pending, (state, action) => {\n            state.isSubscribed = null;\n            state.errorMessage = null;\n            state.status = \"pending\";\n        })\n\n        builder.addCase(isCollectionSubscribed.fulfilled, (state, action) => {\n            state.isSubscribed = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n        })\n\n        builder.addCase(isCollectionSubscribed.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || null;\n            state.isSubscribed = null;\n        })\n    }\n})\n\n\nexport const selectIsCollectionSubscribed = (state: AppState) => state.isCollectionSubscribed;\n\nexport default isCollectionSubscribedSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/subscribeCollectionById.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\n\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { AsyncThunkSubmissionError } from \"../errors/AsyncThunkSubmissionError\";\nimport { CollectionSubscription } from \"../types/CollectionSubscription\";\nimport { ValidationErrors } from \"../types/validationErrors\";\nimport { createSubmissionErrorFromErrObj } from \"../utils/createError\";\n\n\n\n\ninterface SubscribeCollectionByIdReqPayload {\n    collectionId: string;\n};\n\ntype SubscribeCollectionByIdResPayload = CollectionSubscription;\n\ntype SubscribeCollectionByIdValidationErrors = ValidationErrors<SubscribeCollectionByIdReqPayload>;\n\ninterface SubscribeCollectionByIdState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collectionSubscription: null | CollectionSubscription;\n    errorMessage: null |string;\n    errors: SubscribeCollectionByIdValidationErrors | null;\n}\n\nconst initialState: SubscribeCollectionByIdState = {\n    status: 'idle',\n    collectionSubscription: null,\n    errorMessage: null,\n    errors: null\n}\n\nexport const subscribeCollectionById = createAsyncThunk<CollectionSubscription, string, { rejectValue: AsyncThunkSubmissionError<SubscribeCollectionByIdValidationErrors | null>}>('/subscribe/collection-id/add', async (collectionId, thunkApi) => {\n    try {\n        const res = await api.post<SubscribeCollectionByIdResPayload>(`/subscription/${collectionId}/add`);\n        return res.data;\n    } catch(e) {\n        let err: AsyncThunkSubmissionError<SubscribeCollectionByIdValidationErrors | null>= new AsyncThunkSubmissionError(\"Something went wrong\", null);\n        if(e instanceof Error) {\n            err = createSubmissionErrorFromErrObj<SubscribeCollectionByIdValidationErrors>(e); \n        }\n        return thunkApi.rejectWithValue(err);\n    }\n});\n\nexport const subscribeCollectionByIdSlice = createSlice({\n    name: 'subscribeCollectionById',\n    initialState,\n    reducers: {},\n    extraReducers: async (builder) => {\n        builder.addCase(subscribeCollectionById.pending, (state, action) => {\n            state.collectionSubscription = null;\n            state.errorMessage = null;\n            state.errors = null;\n            state.status = \"pending\";\n        })\n\n        builder.addCase(subscribeCollectionById.fulfilled, (state, action) => {\n            state.collectionSubscription = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n            state.errors = null;\n        })\n\n        builder.addCase(subscribeCollectionById.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || null;\n            state.collectionSubscription = null;\n            if(action.payload) {\n                state.errorMessage = action.payload.message;\n                state.errors = action.payload.validationErrors;\n            }\n        })\n    }\n})\n\n\nexport const selectSubscribeCollectionById = (state: AppState) => state.subscribeCollectionById;\n\nexport default subscribeCollectionByIdSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/collection/unSubscribeCollectionById.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\n\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { CollectionSubscription } from \"../types/CollectionSubscription\";\n\n\n\n\n\ntype UnSubscribeCollectionByIdResPayload = CollectionSubscription;\n\n\ninterface UnSubscribeCollectionByIdState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    collectionSubscription: null | CollectionSubscription;\n    errorMessage: null |string;\n}\n\nconst initialState: UnSubscribeCollectionByIdState = {\n    status: 'idle',\n    collectionSubscription: null,\n    errorMessage: null,\n}\n\nexport const unSubscribeCollectionById = createAsyncThunk<CollectionSubscription, string>('/subscribe/collection-id/remove', async (collectionId, thunkApi) => {\n    try {\n        const res = await api.post<UnSubscribeCollectionByIdResPayload>(`/subscription/${collectionId}/remove`);\n        return res.data;\n    } catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message); \n    }\n});\n\nexport const unSubscribeCollectionByIdSlice = createSlice({\n    name: 'unSubscribeCollectionById',\n    initialState,\n    reducers: {},\n    extraReducers: async (builder) => {\n        builder.addCase(unSubscribeCollectionById.pending, (state, action) => {\n            state.collectionSubscription = null;\n            state.errorMessage = null;\n            state.status = \"pending\";\n        })\n\n        builder.addCase(unSubscribeCollectionById.fulfilled, (state, action) => {\n            state.collectionSubscription = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n        })\n\n        builder.addCase(unSubscribeCollectionById.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || null;\n            state.collectionSubscription = null;\n        })\n    }\n})\n\n\nexport const selectUnSubscribeCollectionById = (state: AppState) => state.unSubscribeCollectionById;\n\nexport default unSubscribeCollectionByIdSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/customer/activateCustomer.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\n\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { AsyncThunkSubmissionError } from \"../errors/AsyncThunkSubmissionError\";\nimport { Customer } from \"../types/Customer\";\nimport { ValidationErrors } from \"../types/validationErrors\";\nimport { createSubmissionErrorFromErrObj } from \"../utils/createError\";\n\n\n\nexport interface ActivateCustomerData {\n    firstName: string;\n    lastName: string;\n    email: string;\n    desc: string;\n    lightningAddress: string;\n}\n\ntype ActivateCustomerReqPayload = ActivateCustomerData;\n\ntype ActivateCustomerResPayload = Customer;\n\ntype ActivateCustomerValidationErrors = ValidationErrors<ActivateCustomerData>;\n\ninterface ActivateCustomerState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    customer: null | Customer;\n    errorMessage: null |string;\n    errors: ActivateCustomerValidationErrors | null;\n}\n\nconst initialState: ActivateCustomerState = {\n    status: 'idle',\n    customer: null,\n    errorMessage: null,\n    errors: null\n}\n\nexport const activateCustomer = createAsyncThunk<Customer, ActivateCustomerData, { rejectValue: AsyncThunkSubmissionError<ActivateCustomerValidationErrors | null>}>('/customer/activate', async (data, thunkApi) => {\n    try {\n        const res = await api.post<ActivateCustomerResPayload>('/customer/activate', data);\n        return res.data;\n    } catch(e) {\n        let err: AsyncThunkSubmissionError<ActivateCustomerValidationErrors | null>= new AsyncThunkSubmissionError(\"Something went wrong\", null);\n        if(e instanceof Error) {\n            err = createSubmissionErrorFromErrObj<ActivateCustomerValidationErrors>(e); \n        }\n        return thunkApi.rejectWithValue(err);\n    }\n});\n\nexport const activateCustomerSlice = createSlice({\n    name: 'activateCustomer',\n    initialState,\n    reducers: {},\n    extraReducers: async (builder) => {\n        builder.addCase(activateCustomer.pending, (state, action) => {\n            state.customer = null;\n            state.errorMessage = null;\n            state.errors = null;\n            state.status = \"pending\";\n        })\n\n        builder.addCase(activateCustomer.fulfilled, (state, action) => {\n            state.customer = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n            state.errors = null;\n        })\n\n        builder.addCase(activateCustomer.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || null;\n            state.customer = null;\n            if(action.payload) {\n                state.errorMessage = action.payload.message;\n                state.errors = action.payload.validationErrors;\n            }\n        })\n    }\n})\n\n\nexport const selectActivateCustomer = (state: AppState) => state.activateCustomer;\n\nexport default activateCustomerSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/customer/getCurrentLoggedInCustomer.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Customer } from \"../types/Customer\";\n\ninterface GetCurrentLoggedInCustomerState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    customer: null | Customer;\n    errorMessage: null |string;\n}\n\nconst initialState: GetCurrentLoggedInCustomerState = {\n    status: 'idle',\n    customer: null,\n    errorMessage: null\n}\n\nexport const getCurrentLoggedInCustomer = createAsyncThunk<Customer>('/customer/getCurrentLoggedInCustomer', async () => {\n    try{\n    const resp = await api.get<Customer>('/customer/me');\n    return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nexport const getCurrentLoggedInCustomerSlice = createSlice({\n    name: 'getCurrentLoggedInCustomer',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getCurrentLoggedInCustomer.pending, (state) => {\n            state.status = 'pending';\n            state.customer = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getCurrentLoggedInCustomer.fulfilled, (state, action) => {\n            state.customer = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n        });\n        \n        builder.addCase(getCurrentLoggedInCustomer.rejected, (state, action) => {\n            state.status = \"failed\",\n            state.errorMessage = action.error.message || \"Something went wrong\",\n            state.customer = null;\n        })\n    }\n});\n\n\nexport const selectGetCurrentLoggedInCustomer = (state: AppState) => state.getCurrentLoggedInCustomer;\n\nexport default getCurrentLoggedInCustomerSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/customer/getCustomerById.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AxiosError } from \"axios\";\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { Customer } from \"../types/Customer\";\n\ninterface GetCustomerByIdState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    customer: null | Customer;\n    errorMessage: null |string;\n}\n\nconst initialState: GetCustomerByIdState = {\n    status: 'idle',\n    customer: null,\n    errorMessage: null\n}\n\nexport const getCustomerById = createAsyncThunk<Customer, string>('/customer/public/customerId', async (customerId: string) => {\n    try{\n    const resp = await api.get<Customer>(`/customer/public/${customerId}`);\n    return resp.data;\n    }catch(e) {\n        let message = \"Something went wrong\";\n        if(e instanceof AxiosError) {\n            message = e.response?.data.message || message;\n        }\n        throw new Error(message);\n    }\n})\n\nexport const getCustomerByIdSlice = createSlice({\n    name: 'getCustomerById',\n    initialState,\n    reducers: {},\n    extraReducers: (builder) => {\n        builder.addCase(getCustomerById.pending, (state) => {\n            state.status = 'pending';\n            state.customer = null;\n            state.errorMessage = null;\n        });\n\n        builder.addCase(getCustomerById.fulfilled, (state, action) => {\n            state.customer = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n        });\n        \n        builder.addCase(getCustomerById.rejected, (state, action) => {\n            state.status = \"failed\",\n            state.errorMessage = action.error.message || \"Something went wrong\",\n            state.customer = null;\n        })\n    }\n});\n\n\nexport const selectGetCustomerById = (state: AppState) => state.getCustomerById;\n\nexport default getCustomerByIdSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/customer/updateCustomer.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\n\nimport { AppState } from \"../..\";\nimport api from \"../../../utils/api\";\nimport { AsyncThunkSubmissionError } from \"../errors/AsyncThunkSubmissionError\";\nimport { Customer } from \"../types/Customer\";\nimport { ValidationErrors } from \"../types/validationErrors\";\nimport { createSubmissionErrorFromErrObj } from \"../utils/createError\";\n\n\n\nexport interface UpdateCustomerData {\n    firstName: string;\n    lastName: string;\n    email: string;\n    desc: string;\n    lightningAddress: string;\n}\n\ntype UpdateCustomerReqPayload = UpdateCustomerData;\n\ntype UpdateCustomerResPayload = Customer;\n\ntype UpdateCustomerValidationErrors = ValidationErrors<UpdateCustomerData>;\n\ninterface UpdateCustomerState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    customer: null | Customer;\n    errorMessage: null |string;\n    errors: UpdateCustomerValidationErrors | null;\n}\n\nconst initialState: UpdateCustomerState = {\n    status: 'idle',\n    customer: null,\n    errorMessage: null,\n    errors: null\n}\n\nexport const updateCustomer = createAsyncThunk<Customer, UpdateCustomerData, { rejectValue: AsyncThunkSubmissionError<UpdateCustomerValidationErrors | null>}>('/customer/activate', async (data, thunkApi) => {\n    try {\n        const res = await api.patch<UpdateCustomerResPayload>('/customer', data);\n        return res.data;\n    } catch(e) {\n        let err: AsyncThunkSubmissionError<UpdateCustomerValidationErrors | null>= new AsyncThunkSubmissionError(\"Something went wrong\", null);\n        if(e instanceof Error) {\n            err = createSubmissionErrorFromErrObj<UpdateCustomerValidationErrors>(e); \n        }\n        return thunkApi.rejectWithValue(err);\n    }\n});\n\nexport const updateCustomerSlice = createSlice({\n    name: 'updateCustomer',\n    initialState,\n    reducers: {},\n    extraReducers: async (builder) => {\n        builder.addCase(updateCustomer.pending, (state, action) => {\n            state.customer = null;\n            state.errorMessage = null;\n            state.errors = null;\n            state.status = \"pending\";\n        })\n\n        builder.addCase(updateCustomer.fulfilled, (state, action) => {\n            state.customer = action.payload;\n            state.status = \"succeeded\";\n            state.errorMessage = null;\n            state.errors = null;\n        })\n\n        builder.addCase(updateCustomer.rejected, (state, action) => {\n            state.status = 'failed';\n            state.errorMessage = action.error.message || null;\n            state.customer = null;\n            if(action.payload) {\n                state.errorMessage = action.payload.message;\n                state.errors = action.payload.validationErrors;\n            }\n        })\n    }\n})\n\n\nexport const selectUpdateCustomer = (state: AppState) => state.updateCustomer;\n\nexport default updateCustomerSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/errors/AsyncThunkSubmissionError.ts",
    "content": "export class AsyncThunkSubmissionError<T = null> extends Error {\n    public validationErrors: T | null;\n\n    constructor(message: string, validationErrors: T | null) {\n        super(message)\n        this.validationErrors = validationErrors;\n    }\n}"
  },
  {
    "path": "aquila/view/store/slices/generateName.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\nimport { AppState } from \"..\";\nimport api from \"../../utils/api\";\n\nexport const fetchNames = createAsyncThunk('customer/generateName', async () => {\n    const response = await api.get('/customer/generate-name');\n    return response.data;\n})\n\ninterface GeneratedNameState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    firstName: string | null;\n    lastName: string | null;\n}\n\nconst initialState: GeneratedNameState = {\n    status: 'idle',\n    firstName: null,\n    lastName: null\n}\n\nexport const generateNameSlice = createSlice({\n    name: 'generatedName',\n    initialState,\n    reducers: {\n        removeGeneratedNames: (state) => {\n            state.status = 'idle';\n            state.firstName = null;\n            state.lastName = null;\n        }\n    },\n    extraReducers: (builder) => {\n        builder.addCase(fetchNames.fulfilled, (state, action) => {\n            state.status = 'succeeded';\n            state.firstName = action.payload.firstName;\n            state.lastName = action.payload.lastName;\n        })\n    }\n});\n\nexport const { removeGeneratedNames } = generateNameSlice.actions;\n\nexport const selectGeneratedName = (state: AppState) => state.generatedName;\n\nexport default generateNameSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/signup.ts",
    "content": "import { createAsyncThunk, createSlice } from \"@reduxjs/toolkit\";\n\nimport { AppState } from \"..\";\nimport api from \"../../utils/api\";\nimport { AsyncThunkSubmissionError } from \"./errors/AsyncThunkSubmissionError\";\nimport { Customer } from \"./types/Customer\";\nimport { ValidationErrors } from \"./types/validationErrors\";\nimport { createSubmissionErrorFromErrObj } from \"./utils/createError\";\n\ninterface Collection {\n    id: string;\n    name: string;\n    desc: string;\n    customerId: string;\n    aquilaDbName: string;\n    isSharable: true;\n    indexedDocsCount: number;\n    createdAt: string;\n    updatedat: string;\n}\n\ninterface SignUpData {\n    firstName: string;\n    lastName: string;\n}\n\ntype SignUpRequestPayload = SignUpData;\n\ninterface SignUpResponsePayload {\n    customer: Customer;\n    collection: Collection ;\n}\n\ntype SignUpValidationErrors = ValidationErrors<SignUpRequestPayload>\n\ninterface SignUpState {\n    status: 'idle' | 'pending' | 'succeeded' | 'failed';\n    customer: Customer | null\n    errors: SignUpValidationErrors | null;\n    errorMessage: string | null;\n}\n\nconst initialState: SignUpState = {\n    status: 'idle',\n    customer: null,\n    errors: null,\n    errorMessage: null\n}\n\nexport const signUp = createAsyncThunk<Customer, SignUpData, { rejectValue: AsyncThunkSubmissionError<SignUpValidationErrors | null>}>(\"/customer/sign-up\", async (data, thunkApi) => {\n    try {\n        const res = await api.post<SignUpResponsePayload>('/customer', data);\n        return res.data.customer;\n    }catch(e) {\n        let err: AsyncThunkSubmissionError<SignUpValidationErrors | null>= new AsyncThunkSubmissionError(\"Something went wrong\", null);\n        if(e instanceof Error) {\n            err = createSubmissionErrorFromErrObj<SignUpValidationErrors>(e); \n        }\n        return thunkApi.rejectWithValue(err);\n    }\n})\n\nexport const signUpSlice = createSlice({\n    name: 'signUp',\n    initialState,\n    reducers: {\n        removeSignUpData: (state) => {\n            state.status = 'idle';\n            state.customer = null;\n            state.errors = null;\n            state.errorMessage = null;\n        }\n    },\n    extraReducers: async (builder) => {\n        builder.addCase(signUp.fulfilled, (state, action) => {\n            if(action.payload) {\n                state.customer = action.payload;\n                state.errors = null;\n                state.status = 'succeeded';\n            }\n        });\n\n        builder.addCase(signUp.pending, (state) => {\n            state.customer = null;\n            state.errorMessage = null;\n            state.status = \"pending\";\n            state.errors = null;\n        })\n\n        builder.addCase(signUp.rejected, (state, action) => {\n            state.status = 'failed';\n            state.customer = null;\n            state.errorMessage = action.error.message || null;\n            if(action.payload) {\n                state.errorMessage = action.payload.message;\n                state.errors = action.payload.validationErrors;\n            }\n        });\n    }\n});\n\n\nexport const selectSignUp = (state: AppState) => state.signUp;\n\nexport const { removeSignUpData } = signUpSlice.actions;\n\nexport default signUpSlice.reducer;"
  },
  {
    "path": "aquila/view/store/slices/types/Bookmark.ts",
    "content": "import { Settings } from \"http2\";\n\nexport enum BookmarkStatus {\n    NOT_PROCESSED = 'NOT_PROCESSED',\n    PROCESSING = 'PROCESSING',\n    PROCESSED = 'PROCESSED'\n}\n\nexport interface Bookmark {\n    id: string;\n    collectionId: string;\n    url: string;\n    html: string;\n    title: string;\n    author: string;\n    coverImg: string;\n    summary: string;\n    description?: string;\n    links: string;\n    isHidden: boolean;\n    status: BookmarkStatus\n    createdAt: string;\n}"
  },
  {
    "path": "aquila/view/store/slices/types/Collection.ts",
    "content": "import { Customer } from \"./Customer\";\n\nexport interface Collection {\n    id: string;\n    name: string;\n    desc: string;\n    customerId: string;\n    customer?:  Customer;\n}"
  },
  {
    "path": "aquila/view/store/slices/types/CollectionSubscription.ts",
    "content": "export interface CollectionSubscription {\n    id: string;\n    collectionId: string;\n    subscriberId: string;\n    subscribedAt: string;\n    createdAt: string;\n    updatedAt: string;\n}"
  },
  {
    "path": "aquila/view/store/slices/types/Customer.ts",
    "content": "export interface Customer {\n    id: string;\n    firstName: string;\n    lastName: string;\n    email: string;\n    avatar: string;\n    secretKey: string;\n    desc: string;\n    lightningAddress: string;\n    isActive: boolean;\n    createdAt: string;\n    updatedAt: string;\n}"
  },
  {
    "path": "aquila/view/store/slices/types/validationErrors.ts",
    "content": "interface ValidationErrorData {\n    value: string;\n    msg: string;\n    param: string;\n    location: string;\n}\n\nexport type ResponsePayloadValidationErrors<T> = Partial<Record<keyof T, ValidationErrorData>>\n\nexport type ValidationErrors<T> = Partial<Record<keyof T, string>>"
  },
  {
    "path": "aquila/view/store/slices/utils/createError.ts",
    "content": "import { AxiosError } from \"axios\";\nimport { AsyncThunkSubmissionError } from \"../errors/AsyncThunkSubmissionError\";\n\n\nconst isArrayFieldError = (item: any) => {\n    const match = item.param.match(/\\[(\\d+)\\]/);\n    if (match && match.length === 2) {\n      return true;\n    }\n    return false;\n  };\n  \n  const isObjectType = (item: any) => {\n    const split = item.param.split('.');\n    if (split.length === 2) {\n      return true;\n    }\n    return false;\n  };\n  \n  const parseArrayFieldError = (item: any) => {\n    const pattern = /\\[(\\d+)\\]/;\n    const match = item.param.match(pattern);\n    const index = parseInt(match[1], 10);\n    const param = item.param.replace(pattern, '');\n    const [key, prop] = param.split('.');\n    return { index, key, prop };\n  };\n  \n  const collectValidationErrors = (errors: any) => {\n    const formErrors: any = {};\n    errors.forEach((item: any) => {\n      if (isArrayFieldError(item)) {\n        const { key, index, prop } = parseArrayFieldError(item);\n        if (!formErrors[key]) {\n          formErrors[key] = [];\n          formErrors[key][index] = {};\n          formErrors[key][index][prop] = item.msg;\n        } else {\n          if (!formErrors[key][index]) {\n            formErrors[key][index] = {};\n          }\n          formErrors[key][index][prop] = item.msg;\n        }\n      } else if (isObjectType(item)) {\n        const [key, prop] = item.param.split('.');\n        if (!formErrors[key]) {\n          formErrors[key] = {};\n          formErrors[key][prop] = item.msg;\n        } else {\n          if (!formErrors[key][prop]) {\n            formErrors[key][prop] = item.msg;\n          }\n        }\n      } else if (!formErrors[item]) {\n        formErrors[item.param] = item.msg;\n      }\n    });\n    return formErrors;\n  };\n  \ninterface SubmissionErrorResponse<T> {\n    message: string;\n    errors: Array<T>;\n}\n\nexport const createSubmissionErrorFromErrObj = <T extends {}> (error: AxiosError<SubmissionErrorResponse<T>> | Error) => {\n    let message = \"Something went wrong\";\n    let validationErrors: T | null = null;\n    if(error instanceof AxiosError) {\n        message = error.response?.data.message || message;\n        if(error.response?.status === 400 && error.response.data.errors) {\n            validationErrors = collectValidationErrors(error.response.data.errors);\n        }\n    }\n    const errObj = new AsyncThunkSubmissionError<T>(message, validationErrors);\n    return errObj;\n}"
  },
  {
    "path": "aquila/view/styles/globals.scss",
    "content": "// @import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');\n@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');\n/* http://meyerweb.com/eric/tools/css/reset/ \n   v2.0 | 20110126\n   License: none (public domain)\n*/\n\nhtml, body, div, span, applet, object, iframe,\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\na, abbr, acronym, address, big, cite, code,\ndel, dfn, em, img, ins, kbd, q, s, samp,\nsmall, strike, strong, sub, sup, tt, var,\nb, u, i, center,\ndl, dt, dd, ol, ul, li,\nfieldset, form, label, legend,\ntable, caption, tbody, tfoot, thead, tr, th, td,\narticle, aside, canvas, details, embed, \nfigure, figcaption, footer, header, hgroup, \nmenu, nav, output, ruby, section, summary,\ntime, mark, audio, video {\n\tmargin: 0;\n\tpadding: 0;\n\tborder: 0;\n\tfont-size: 100%;\n\tvertical-align: baseline;\n}\n/* HTML5 display-role reset for older browsers */\narticle, aside, details, figcaption, figure, \nfooter, header, hgroup, menu, nav, section {\n\tdisplay: block;\n}\nbody {\n\tline-height: 1;\n}\nol, ul {\n\tlist-style: none;\n}\nblockquote, q {\n\tquotes: none;\n}\nblockquote:before, blockquote:after,\nq:before, q:after {\n\tcontent: '';\n\tcontent: none;\n}\ntable {\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n}\n\n* {\n\t// font-family: 'Roboto', sans-serif;\n\tfont-family: 'IBM Plex Sans', sans-serif;\n}\nhtml, body {\n\theight: 100%;\t\n\tmin-height: 100%;\n}\n#__next {\n\theight: 100%;\t\n\tmin-height: 100%;\n}"
  },
  {
    "path": "aquila/view/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\",\n    \"incremental\": true\n  },\n  \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "aquila/view/utils/api.ts",
    "content": "import axios from \"axios\";\nimport { getSession, signOut } from \"next-auth/react\";\nimport { store } from \"../store\";\n\n\nconst api = axios.create({\n    baseURL: process.env.NEXT_PUBLIC_AQUILA_API_URL,\n});\n\napi.interceptors.request.use(async (config) => {\n    const authState = store.getState().auth;\n    let accessToken = authState.token;\n    // console.log(authState);\n    if(!accessToken && authState.status === \"idle\" && typeof window !== \"undefined\") {\n        const session = await getSession();\n        // console.log(session, \"Output\");\n        if(session) {\n            accessToken = session?.user.token || null;\n        }\n    }\n    if(config.headers && accessToken) {\n        config.headers.Authorization = `Bearer ${accessToken}`;\n    }\n    return config;\n})\n\napi.interceptors.response.use((request) => request, (err) => {\n    if(!err.response || err.response.data.code === 401) {\n        signOut();\n    }\n})\n\nexport default api;"
  }
]