├── .gitattributes ├── .gitignore ├── .jsbeautifyrc ├── .travis.yml ├── LICENSE ├── README.md └── frontend ├── __mocks__ ├── rawMock.js └── styleMock.js ├── asciify.js ├── assets ├── README.md ├── neon-moon │ ├── 00.png.gpg │ ├── 01-cups.png.gpg │ ├── 01-pents.png.gpg │ ├── 01-swords.png.gpg │ ├── 01-wands.png.gpg │ ├── 01.png.gpg │ ├── 02-cups.png.gpg │ ├── 02-pents.png.gpg │ ├── 02-swords.png.gpg │ ├── 02-wands.png.gpg │ ├── 02.png.gpg │ ├── 03-cups.png.gpg │ ├── 03-pents.png.gpg │ ├── 03-swords.png.gpg │ ├── 03-wands.png.gpg │ ├── 03.png.gpg │ ├── 04-cups.png.gpg │ ├── 04-pents.png.gpg │ ├── 04-swords.png.gpg │ ├── 04-wands.png.gpg │ ├── 04.png.gpg │ ├── 05-cups.png.gpg │ ├── 05-pents.png.gpg │ ├── 05-swords.png.gpg │ ├── 05-wands.png.gpg │ ├── 05.png.gpg │ ├── 06-cups.png.gpg │ ├── 06-pents.png.gpg │ ├── 06-swords.png.gpg │ ├── 06-wands.png.gpg │ ├── 06.png.gpg │ ├── 07-cups.png.gpg │ ├── 07-pents.png.gpg │ ├── 07-swords.png.gpg │ ├── 07-wands.png.gpg │ ├── 07.png.gpg │ ├── 08-cups.png.gpg │ ├── 08-pents.png.gpg │ ├── 08-swords.png.gpg │ ├── 08-wands.png.gpg │ ├── 08.png.gpg │ ├── 09-cups.png.gpg │ ├── 09-pents.png.gpg │ ├── 09-swords.png.gpg │ ├── 09-wands.png.gpg │ ├── 09.png.gpg │ ├── 10-cups.png.gpg │ ├── 10-pents.png.gpg │ ├── 10-swords.png.gpg │ ├── 10-wands.png.gpg │ ├── 10.png.gpg │ ├── 11-cups.png.gpg │ ├── 11-pents.png.gpg │ ├── 11-swords.png.gpg │ ├── 11-wands.png.gpg │ ├── 11.png.gpg │ ├── 12-cups.png.gpg │ ├── 12-pents.png.gpg │ ├── 12-swords.png.gpg │ ├── 12-wands.png.gpg │ ├── 12.png.gpg │ ├── 13-cups.png.gpg │ ├── 13-pents.png.gpg │ ├── 13-swords.png.gpg │ ├── 13-wands.png.gpg │ ├── 13.png.gpg │ ├── 14-cups.png.gpg │ ├── 14-pents.png.gpg │ ├── 14-swords.png.gpg │ ├── 14-wands.png.gpg │ ├── 14.png.gpg │ ├── 15.png.gpg │ ├── 16.png.gpg │ ├── 17.png.gpg │ ├── 18.png.gpg │ ├── 19.png.gpg │ ├── 20.png.gpg │ ├── 21.png.gpg │ ├── LICENSE │ └── back.png.gpg ├── rider-waite-smith │ ├── 00.jpg │ ├── 01-cups.jpg │ ├── 01-pents.jpg │ ├── 01-swords.jpg │ ├── 01-wands.jpg │ ├── 01.jpg │ ├── 02-cups.jpg │ ├── 02-pents.jpg │ ├── 02-swords.jpg │ ├── 02-wands.jpg │ ├── 02.jpg │ ├── 03-cups.jpg │ ├── 03-pents.jpg │ ├── 03-swords.jpg │ ├── 03-wands.jpg │ ├── 03.jpg │ ├── 04-cups.jpg │ ├── 04-pents.jpg │ ├── 04-swords.jpg │ ├── 04-wands.jpg │ ├── 04.jpg │ ├── 05-cups.jpg │ ├── 05-pents.jpg │ ├── 05-swords.jpg │ ├── 05-wands.jpg │ ├── 05.jpg │ ├── 06-cups.jpg │ ├── 06-pents.jpg │ ├── 06-swords.jpg │ ├── 06-wands.jpg │ ├── 06.jpg │ ├── 07-cups.jpg │ ├── 07-pents.jpg │ ├── 07-swords.jpg │ ├── 07-wands.jpg │ ├── 07.jpg │ ├── 08-cups.jpg │ ├── 08-pents.jpg │ ├── 08-swords.jpg │ ├── 08-wands.jpg │ ├── 08.jpg │ ├── 09-cups.jpg │ ├── 09-pents.jpg │ ├── 09-swords.jpg │ ├── 09-wands.jpg │ ├── 09.jpg │ ├── 10-cups.jpg │ ├── 10-pents.jpg │ ├── 10-swords.jpg │ ├── 10-wands.jpg │ ├── 10.jpg │ ├── 11-cups.jpg │ ├── 11-pents.jpg │ ├── 11-swords.jpg │ ├── 11-wands.jpg │ ├── 11.jpg │ ├── 12-cups.jpg │ ├── 12-pents.jpg │ ├── 12-swords.jpg │ ├── 12-wands.jpg │ ├── 12.jpg │ ├── 13-cups.jpg │ ├── 13-pents.jpg │ ├── 13-swords.jpg │ ├── 13-wands.jpg │ ├── 13.jpg │ ├── 14-cups.jpg │ ├── 14-pents.jpg │ ├── 14-swords.jpg │ ├── 14-wands.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── LICENSE │ └── back.jpg ├── scrape_rws.py ├── silicon-dawn │ ├── 0(-1).jpg │ ├── 0(0).jpg │ ├── 0(2).jpg │ ├── 0(5).jpg │ ├── 00-VOID.jpg │ ├── 00.jpg │ ├── 01-cups.jpg │ ├── 01-pents.jpg │ ├── 01-swords.jpg │ ├── 01-wands.jpg │ ├── 01.jpg │ ├── 02-cups.jpg │ ├── 02-pents.jpg │ ├── 02-swords.jpg │ ├── 02-wands.jpg │ ├── 02.jpg │ ├── 03-cups.jpg │ ├── 03-pents.jpg │ ├── 03-swords.jpg │ ├── 03-wands.jpg │ ├── 03.jpg │ ├── 04-cups.jpg │ ├── 04-pents.jpg │ ├── 04-swords.jpg │ ├── 04-wands.jpg │ ├── 04.jpg │ ├── 05-cups.jpg │ ├── 05-pents.jpg │ ├── 05-swords.jpg │ ├── 05-wands.jpg │ ├── 05.jpg │ ├── 06-cups.jpg │ ├── 06-pents.jpg │ ├── 06-swords.jpg │ ├── 06-wands.jpg │ ├── 06.jpg │ ├── 07-cups.jpg │ ├── 07-pents.jpg │ ├── 07-swords.jpg │ ├── 07-wands.jpg │ ├── 07.jpg │ ├── 08-cups.jpg │ ├── 08-pents.jpg │ ├── 08-swords.jpg │ ├── 08-wands.jpg │ ├── 08.jpg │ ├── 09-cups.jpg │ ├── 09-pents.jpg │ ├── 09-swords.jpg │ ├── 09-wands.jpg │ ├── 09.jpg │ ├── 10-cups.jpg │ ├── 10-pents.jpg │ ├── 10-swords.jpg │ ├── 10-wands.jpg │ ├── 10.jpg │ ├── 11-VOID.jpg │ ├── 11-cups.jpg │ ├── 11-pents.jpg │ ├── 11-swords.jpg │ ├── 11-wands.jpg │ ├── 11.jpg │ ├── 12-VOID.jpg │ ├── 12-cups.jpg │ ├── 12-pents.jpg │ ├── 12-swords.jpg │ ├── 12-wands.jpg │ ├── 12.jpg │ ├── 13-VOID.jpg │ ├── 13-cups.jpg │ ├── 13-pents.jpg │ ├── 13-swords.jpg │ ├── 13-wands.jpg │ ├── 13.jpg │ ├── 13x.jpg │ ├── 14-VOID.jpg │ ├── 14-cups.jpg │ ├── 14-pents.jpg │ ├── 14-swords.jpg │ ├── 14-wands.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 8½.jpg │ ├── 99-cups.jpg │ ├── 99-pents.jpg │ ├── 99-swords.jpg │ ├── 99-wands.jpg │ ├── LICENSE │ ├── N4.jpg │ ├── VIII.jpg │ ├── X.jpg │ ├── back.jpg │ ├── black.jpg │ ├── interpretations.json │ └── white.jpg └── tarot_interpretations.json ├── jest.config.js ├── package-lock.json ├── package.json ├── src ├── cards │ ├── __mocks__ │ │ └── artFinderContext.tsx │ ├── artFinder.tsx │ ├── artFinderContext.tsx │ ├── cardFormatter.spec.tsx │ ├── cardFormatter.tsx │ ├── cards.spec.tsx │ ├── cards.tsx │ ├── interpret.spec.tsx │ ├── interpret.tsx │ ├── lfsr.spec.tsx │ ├── lfsr.tsx │ ├── shuffle.spec.tsx │ └── shuffle.tsx ├── components │ ├── About.md │ ├── App.spec.tsx │ ├── App.tsx │ ├── BackupRestore.tsx │ ├── CardArtViewer.tsx │ ├── Credits.md │ ├── Deck.tsx │ ├── DeckPreloader.tsx │ ├── DrawResult.tsx │ ├── InterpretationView.spec.tsx │ ├── InterpretationView.tsx │ ├── Navbar.tsx │ ├── NewDeckDialog.spec.tsx │ ├── NewDeckDialog.tsx │ ├── Prompter.spec.tsx │ └── Prompter.tsx ├── crc-32.d.ts ├── index.tsx ├── romanize.d.ts ├── setupTests.tsx └── styles │ ├── app.scss │ ├── backup-restore.scss │ ├── card_art_viewer.scss │ ├── dialog_form.scss │ ├── draw_result.scss │ ├── modal.scss │ ├── navbar.scss │ └── prompter.scss ├── tsconfig.json ├── tslint.json └── webpack.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | frontend/assets/rider-waite-smith/*.jpg filter=lfs diff=lfs merge=lfs -text 2 | *.jpg filter=lfs diff=lfs merge=lfs -text 3 | *.png.gpg filter=lfs diff=lfs merge=lfs -text 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /frontend/assets/silicon-dawn-ascii 2 | /frontend/assets/rider-waite-smith-ascii 3 | /frontend/assets/neon-moon-ascii 4 | /frontend/assets/neon-moon/*.png 5 | /frontend/coverage 6 | /frontend/dist 7 | /frontend/node_modules 8 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_size": 2 3 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: "node_js" 2 | cache: 3 | directories: 4 | - ".git/lfs" 5 | node_js: 6 | - "node" 7 | git: 8 | lfs_skip_smudge: true 9 | 10 | before_install: 11 | - cd frontend 12 | 13 | install: 14 | - git lfs pull 15 | - npm ci 16 | 17 | script: 18 | - npm install -g codecov 19 | - npm test 20 | 21 | after_success: 22 | - codecov 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Ash 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tarot of the Lost Purpose 2 | 3 | **NOT MAINTAINED** 4 | 5 | This was an experiment back in 2019 to learn React. Unfortunately, the nature 6 | of modern webdev means severay of the 'best practices' here are no longer 7 | valid. One day I'd like to rewrite this in the 'modern' recommended style, 8 | possibly with Preact or even without any framework at all. But until then, 9 | consider this code bit-rotten. 10 | 11 | If you want to try the Tarot of the Lost Purpose out for yourself, see [the 12 | official instance](https://synthetic.zone/lost-purpose). 13 | 14 | Tarot of the Lost Purpose (or just Lost Purpose) is a 15 | [skeuomorphic](https://en.wikipedia.org/wiki/Skeuomorph) tarot deck web 16 | application: it simulates tarot decks in significantly more detail than is 17 | necessary, and makes several design decisions with the explicit purpose of 18 | *feeling* like a tarot deck. 19 | 20 | * It uses a [linear-feedback shift 21 | register](https://en.wikipedia.org/wiki/Linear-feedback_shift_register) for 22 | random number generation, seeded using a user-provided string with 23 | [CRC32](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) repeatedly 24 | applied. It does this in order to simulate the fact that humans are quite bad 25 | at 'randomly' shuffling. 26 | * Instead of implementing a perfect [Fisher-Yates 27 | shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle), it 28 | implements a 'chunked riffle shuffle' where the deck is randomly cut and 29 | randomly-sized chunks from each half are interleaved. 30 | 31 | For a more rambly about page, read [the about page](frontend/src/components/About.md). 32 | 33 | ## Silicon Dawn 34 | 35 | Lost Purpose also supports the [Tarot of the Silicon 36 | Dawn](http://egypt.urnash.com/tarot/), which augments the traditional tarot deck 37 | with: 38 | * Five extra major arcana 39 | * The (VOID) suit, with five ranks (including a 0). 40 | * The 99s of all four traditional suits 41 | * Two extra cards that defy categorization. 42 | 43 | The deck is worth a shot if you're queer/transhuman/generally Weird, but sadly 44 | out of print (as of August 2018) and unreasonably expensive to buy second-hand. 45 | Egypt Urnash has kindly given me permission to use the art assets and her 46 | interpretations. 47 | 48 | ## Licensing 49 | 50 | All of my own work (everything outside of `frontend/assets`) is licensed under 51 | the MIT license found in `LICENSE`. The assets are licensed using the 52 | per-directory `LICENSE` files. 53 | -------------------------------------------------------------------------------- /frontend/__mocks__/rawMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'some mocked raw text'; 2 | -------------------------------------------------------------------------------- /frontend/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /frontend/asciify.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | const assert = require('assert'); 6 | const child_process = require('child_process'); 7 | const fs = require('fs'); 8 | const path = require('path'); 9 | 10 | const cli = process.argv[2]; 11 | 12 | // Lists the images stored in the given directory. The returned paths have `dir` 13 | // prepended to them. 14 | function listImages(dir) { 15 | return fs.readdirSync(dir) 16 | .filter(file => file.match(/\.(jpg|png|gif)$/i)) 17 | .map(file => path.join(dir, file)); 18 | } 19 | 20 | // ASCIIfies the assets stored in the given directory. 21 | function asciify(dir) { 22 | const sourceDir = `assets/${dir}`; 23 | const targetDir = `assets/${dir}-ascii`; 24 | if (!fs.existsSync(targetDir)) { 25 | fs.mkdirSync(targetDir); 26 | } 27 | for (const source of listImages(sourceDir)) { 28 | const target = path.join(targetDir, path.parse(source).name + '.jpg'); 29 | console.log(`asciifying ${source} => ${target}`); 30 | 31 | child_process.spawnSync(cli, [ 32 | "--font", "/System/Library/Fonts/Menlo.ttc", 33 | "--ascii-width", "70", 34 | "--font-height", "10", 35 | source, target 36 | ]); 37 | } 38 | } 39 | assert(cli); 40 | 41 | asciify('silicon-dawn'); 42 | asciify('rider-waite-smith'); 43 | asciify('neon-moon'); 44 | -------------------------------------------------------------------------------- /frontend/assets/README.md: -------------------------------------------------------------------------------- 1 | This folder stores art and data assets. In general, the stuff here wasn't 2 | written by me (meaning Ash, the author of Lost Purpose). 3 | 4 | ## Tarot card meanings 5 | 6 | `tarot_interpretations.json` stores a list of interpretations of Tarot. The 7 | underlying writing is by [Mark 8 | McElroy](http://www.madebymark.com/2014/07/06/my-latest-book-belongs-to-you/), 9 | with the translation to JSON done by [Darius 10 | Kazemi](https://github.com/dariusk/corpora). Both the original and JSON forms 11 | are public domain. 12 | 13 | To replicate, run 14 | 15 | ```sh 16 | curl "https://raw.githubusercontent.com/dariusk/corpora/23ae2da2c70db54420bc86994e6702a2d6a60c1a/data/divination/tarot_interpretations.json" | \ 17 | sed 's/coins/pentacles/g' | \ 18 | jq -c . > \ 19 | tarot_interpretations.json 20 | ``` 21 | 22 | ## Art assets 23 | 24 | The card art assets are stored using the following pattern: 25 | 26 | - `NN.jpg` for major arcana (e.g., `01.jpg` for the Magician, `13.png` for Death) 27 | - `rank-suit.jpg` for minor arcana (e.g., `08-pentacles.png`, `queen-wands.png`). 28 | 29 | ### ASCII generation 30 | 31 | To generate ASCII art assets, build the `cli` binary from 32 | http://github.com/deifactor/ascender, then run 33 | 34 | npm asciify -- /path/to/cli/binary 35 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/00.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0cc54da9f406e0019a269f5f053bd3060cb841f4e17cef256c39f740bcc21da1 3 | size 431132 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/01-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4094e629e70b9ce1aa2baf4a085af3cd40a005925ca8fb9dcecacad9f4e237fd 3 | size 367290 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/01-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3fe0d27c8f4f3406ae5fdccc3f11b2e04ec3d59502ff68717a2c72b0e087503a 3 | size 354787 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/01-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0295547e35ddd5f5be9dc6a45524a21f747e52fd60b0eec5fe41acc808bca22a 3 | size 366486 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/01-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:abb6da89558774925c215653500020fd54bc70c41f6b74fb5c76d6fbe0994007 3 | size 318977 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/01.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e8966bd453548ccd67bc3c33dc530f5c18d06a3ff9c289c2be420e495d8f2bca 3 | size 340024 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/02-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d6937346c3832ea8e6fa6ec941dea1459de340654f5dc340c536e2685a1f9338 3 | size 461283 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/02-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:382699d7510f7e4bf53329c0801823d1863eb4f8c7f87e4236d76e8a25df09a6 3 | size 399105 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/02-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b3d6d9f0a68e00c3d6f19b6a96da3f6973ddcb8fefabff7b1e299eda7ad0f45d 3 | size 424415 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/02-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9751cf8038f1c406e8563e3186681e3ef9da07f8be4efa2b3c45731d6862850c 3 | size 393580 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/02.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4f5cccd8d83655dc0b10742e9c065618ac93a4d5477fa3b266eede2833a4dfee 3 | size 474881 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/03-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2daef75cdfefc6f04a5fb10448bbe8070d8e600c2b8b03f52b7b1c6e36c6cd1d 3 | size 453711 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/03-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5892f8b41848d7f202e7c3940b04dcd3b175b8e06c4985a2b9e8359f66d6ef6b 3 | size 454975 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/03-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6fc94ffa2c8f65663b0047ff81168e95583a8a09fdafbf6f6bdb7eebd429e9ce 3 | size 344663 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/03-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eb024430d023e7a6b305078c77601dcba6d19ec67b15157bef491d5d1a7266eb 3 | size 300967 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/03.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d8939561cedec78052250e3f8636ce79a86d0c80bb0a9525eecbf354408683b0 3 | size 368467 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/04-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:92d3858edf6b17c9a078432df9217e4d57ca3c3856c7bec25b27322dcec3df07 3 | size 452718 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/04-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:de955f036cd0e9fcce11cf847e360a153ce79a8255e2c8d2bd3e12231c9f1911 3 | size 442388 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/04-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9ab60f474c5095ed50b0e65e6e809061ab0c0afd980241a1554d33a73b24e250 3 | size 426854 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/04-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4a1d370466b368288100d27b907a59fbde8da9a860779da77c11af8e74af63fb 3 | size 506241 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/04.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:44fafbc779bde1ba3a137080c375b2f558327a16bee0f66f4791e764e822befa 3 | size 526588 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/05-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cb91b3ae5b891cb68bb8e596c14983de7463e66cdae04084ddc21d66e3ab2d9d 3 | size 483172 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/05-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bb3e53ddb033948de007bdd2193d196875e8e2c866e784ebc97c961c6f6ac938 3 | size 336164 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/05-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8314b9a6e699088190f2f4786ebc009cf85a4b6c4a80025fce988e25a5cceebf 3 | size 453017 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/05-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eafb68daa742e0bb0f477ed9db471a1e8eeeea6c10362baad1d82b127e9749f9 3 | size 450053 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/05.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ded2ea5095ad32f070a8bd2d02b235cfe81d4071cefd141acfd64f12fbb0155c 3 | size 360487 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/06-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6dd114790f2e3a4216709ddd1990f6be3d4ce09e7ba317ecf78b774c2896f4c3 3 | size 368349 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/06-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0dd9b10f731b72a4b2b550f08dde68229ff03feb985fcb69d9c4f7c3145bb8df 3 | size 435916 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/06-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0e3f2aa565451e2a9dead0bb935ff05742e573698cd550d8cb6d6e61529bad9d 3 | size 453567 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/06-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7354822aded28dd51d14259246c5deb1ebf4c42fb4010bb416ce3fc5be0c110e 3 | size 429935 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/06.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:465ccdfb700b6ee7881bb1570739e40e533bb048d43dfa93f4ee4108fced4a38 3 | size 501404 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/07-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a3de27bdbf75a17f78c7874f866c4c7fb9eb77a64bc8f30ee1cbc6c8f0b7d45b 3 | size 520990 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/07-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8039ebc2fc0e996e3e4013473d44abcdfcf583d871c48c8ccd9721e63643947a 3 | size 364194 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/07-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:034fbb42762f948ebedec96993f1511e292d305d78a78faba287268c230b745e 3 | size 533462 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/07-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1318c28cc4dbcc09f3cb17f72f128f494a222ea366d68b8d0b7a91eadf8ac988 3 | size 486221 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/07.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a5985251f52de2baf556d5c66dd6c2c7cd331c357d1b3026183601e0f77e317c 3 | size 443189 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/08-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f59d3e4da9253a7f652135e43fcdeb67e8c383e5649916279b51de2deb50d354 3 | size 276515 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/08-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:788e64a73c834568688747d774a3efaae07c78e36cf4ab3f80923a309670f44e 3 | size 391918 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/08-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bb9d652fad0785c8f3e337163dc339995cfe254d1edfac50f462b9b493f832d5 3 | size 592727 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/08-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bc1b48d32dbd419b320f2ac1938d6ebf1176a86c299f904d106a0c365236dbbd 3 | size 475436 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/08.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:996aa93e320c897716676746b1ad6a25981ce16de11bfcf7291e749a3165cac8 3 | size 448084 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/09-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5470a254d2bdaacd3f02acd538a2fe57ec019379b6231d0ac1e80381efb4fd26 3 | size 425942 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/09-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:661a3fcb5deed3b36002e4ea72eb2b4e98e7ba41cc15fe727b0a88c4d3115b85 3 | size 479996 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/09-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:49b84135dd6638a701d5122d74dfb16710b24a4e054d6b5a0e9211cc0f4ccc1c 3 | size 591398 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/09-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:03a872716f8c8ba0b9c1e102bec827b71750dab3d33c64483ea354c3276b73c8 3 | size 376497 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/09.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9a7d6ca0da5916538e585b2940caf5bf8ea9e925f4b326b3a9bf41fa5bf8741b 3 | size 377505 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/10-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f5049fe058837046114f5de92571321c2c67afed62de5af37546e296c9c6e7e9 3 | size 595998 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/10-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:12c44251df0071cd65056a35a8131e982eaa3e248bb39f8107d3f20bbe9d6a30 3 | size 436966 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/10-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0877e54ec6d679135055e3a7b9e534290c01fb0e343d59e25fa5bd4d024ee80c 3 | size 371241 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/10-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4e973c4c1cfac70bdca1a554739850cdb3c3b22b1e46a63133ba519c402c0ef9 3 | size 494793 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/10.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a4a99873fe902ccae218b875d0d00e9ca930a1d5f650842afb79f32a7aa8e38a 3 | size 551666 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/11-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b9b98badffc78a5a26b8183205277151772fbf9bf66be4f0d2725f339866d219 3 | size 560040 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/11-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d7d997d7694745052392708680907966daf2100d0a8e661ab5f8ef1506ddd630 3 | size 470307 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/11-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:040f9bd3f35240001ade8238d72f0eabd99b1bb0e46f7fa7ac002fd3ae3142cc 3 | size 388063 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/11-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2769f42ac689393c6a7adbe0bfed93bf5d7740ab63232dc92d6b86766bc1b764 3 | size 331043 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/11.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8cce6f00934bd1e5dda79ad33aaa848d74f815f39ce25d4ed83357fc4b5fa4df 3 | size 515239 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/12-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0dbcc19ccda301046591efe851551460ab4dfa3f2ea25f2b808e7eac6af982cd 3 | size 422673 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/12-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f8b1a1fc0e8340d6acdee6d988990048bdbd4d8a15ee808949c38209245b5b56 3 | size 522579 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/12-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ac779dc1219bc1c49c88c80664efdd530192c68b783db5d1e814f4c1597045b9 3 | size 484719 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/12-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ff13b1bb9b62e07eec2c6c34156e8d679617983e76a50d55a9433b9bac5fa28d 3 | size 467672 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/12.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:675de122d6e672cfa9dac9a0c2da094d193d57f3e11a15208b4c0865ad618403 3 | size 422828 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/13-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:307979df17fff39d42e5095797c492ca9f1f5b82a0e90b8d3d0d7d350953951c 3 | size 545305 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/13-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3116e5e6a5b5f9aad6435da43ab40dad212f68b0aafd6bbb78ff033a63e0ceb4 3 | size 569014 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/13-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3c45dcb2cb0bc13cc299c6457af8816641f886543421762d16d34d81cc7533e2 3 | size 531064 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/13-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5cab70801dccfe5b964696b56de9726f530e8a72baf7e1300b4d91eeec99eff1 3 | size 510548 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/13.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e33c7fae653a327e7aa3d6bccbf037a970b3cf17322b47462b13e361a6f2ea04 3 | size 500247 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/14-cups.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:97b0471c8cdc6c59895e6bb33bcee7c439bd25053b2e062c3a8a0f67cf0e510e 3 | size 409222 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/14-pents.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a9b2f24d97da5545a3d74aca2a6063df4d45c37142f4ccdb5d44dd7fab838dc1 3 | size 391445 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/14-swords.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1322654e7505ea92c7d83a5343eca68d0852a95a948c8c5ba6403fcf89c74881 3 | size 434807 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/14-wands.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:36fe8e68ebae6c63738347a22a2af40a4b69f0ad7c251fc2a089842a98fe5cee 3 | size 488748 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/14.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d4c4f34b4cbc28b25d7298a62fc8baf28f8e376c718fe6d834f8f8f4f5e5ac53 3 | size 456259 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/15.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ac60dc0c06a3e5dac1d270499590f5c52777657950655476ef03a6db94c31be5 3 | size 604878 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/16.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3998e23f726e5c54542aeb8513f95ef204261f640c1173b934ddf23c7a370258 3 | size 427738 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/17.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5528561f7fa72470e098236fed64b5e44fc697720f5892f092c9b89eeeaa1c0a 3 | size 416210 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/18.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6cb6a564af37792f5e36a5c395feb28ae0de4aa786122f13591624e54232e7fa 3 | size 429240 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/19.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:45cfc0dee1f10a11040f3d4d62c5f540fe37d107273b8577e405aca3fdda42f4 3 | size 460581 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/20.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1db8546b69873a692c98dc8df7cf16d82806dd245d505dd1956af0c727fab16b 3 | size 417833 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/21.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:29bb0f6e838e9991599c1175e50ae332e3e5f32f8ff57fd655a7cc9c0999b28d 3 | size 560039 4 | -------------------------------------------------------------------------------- /frontend/assets/neon-moon/LICENSE: -------------------------------------------------------------------------------- 1 | All Neon Moon Tarot art is copyright Pixel Occult, and used here in ASCIIfied 2 | form only with explicit permission (which is why the files are committed 3 | *encrypted*). 4 | 5 | If you want the passphrase, ask me. -------------------------------------------------------------------------------- /frontend/assets/neon-moon/back.png.gpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:661720375617d05cc86c754dc09a22fea98895cc2840ea0c79683e28a13d79d2 3 | size 73110 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/00.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6938bc4bda805e1446d906cb979aebe0576f9062191d8bb61c66bd0b1c9c197e 3 | size 1048478 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/01-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e01f2fb0c020842ca6de1a83389854b7ebf0db67e7c79917ae7ab925c54627af 3 | size 815856 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/01-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6297bb68be416bc9fdd747f1c70825292f2c837ae5428e35bff8d89544d56ada 3 | size 766341 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/01-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:04f6cc16bc9f9e09d11d425792f70107effc30f892876f5337c0ec74d3b532b5 3 | size 743462 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/01-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a43df3731e1b921809b4bd2b739a98b5b55fc26b7ce5a55a91918ff985526a42 3 | size 745014 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/01.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e3ae7f9d58cfaeee185df1a66f386dd401cbca2a2956bd714a5b300e255d8f79 3 | size 699662 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/02-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4915140879b177c8ef1bed579f4921dbaa55742b8416b06e4c182daf53d3be8d 3 | size 1013161 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/02-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b06fb4847530a735ced9dfe36dde382b1c8c8e18f44ae10dfaa965e8c4092e5f 3 | size 812398 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/02-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:56dcf25e37ef2012a60c5e2e1e4f852c67a0492a492674aee4f8c9cb69c4ce2a 3 | size 712252 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/02-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:13e54848859c4db289e8422088380cb9be2707d8d6ba1f286e65253c5e99f48d 3 | size 749285 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/02.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a8cf1c83bf74ccebf28be45d36564145dda4856c7b1bbcfeddf76f05b60a6f0a 3 | size 789649 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/03-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9d8dec699a6b12bbd1d341eb50ab14bcd17b77f2ae2dcb0717080a5c1140e1da 3 | size 1021499 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/03-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eaa57d2060bd81a7382e963b0d38899a52dcee4492a69dcfc217a7febdbc84d2 3 | size 789948 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/03-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9e33ff93444639eb0a7b3dea0c61a8c29159279b1075eb04d1a2cb76f5b49b82 3 | size 632576 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/03-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:14ac893d0b9bb21f5d0372f6f51fc8533757d2fe1b7d395545aa704221360523 3 | size 839652 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/03.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:10a3957870ab08abd04b6e31544e9a057a35a01b7c662205246f03c356c8541c 3 | size 850419 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/04-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4aa66bd02819bcbed9fb37b92080884d1702dc00341337464ea55fbc77b92404 3 | size 700398 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/04-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ac4b170e433562c771bfc1b581aed82f37bfab0fa68990f8cabb5c96b2ea5070 3 | size 716133 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/04-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:533a21b1bbfa9b7a49bf70fd1c085131185ebc7c9bdbd33b3e69f9693e9bb168 3 | size 755638 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/04-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:868b520ff6c434eb296c7ff7102d3fafb9bf0ffbc0beb6ad96de2c5ef739114a 3 | size 695704 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/04.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b900d86d0cb80bd6d050a986b5cae99dd44a99ae9c2630c03a0283ebbc71a553 3 | size 840162 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/05-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:47ad29cef456c1285b405d4fddb7ead9c914316b318faab68ca3b0a08204fa41 3 | size 598982 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/05-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:60586eee2e1c08cec2689c6c8679b94a99949acad8426b7cc61078a799118480 3 | size 800278 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/05-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d382a3179b087a686dbbaf67af5d69613be6d8210a641350a4bf9fb2a1373665 3 | size 781859 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/05-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:458e33f708b9cff2e78a49fa8f2cac482f57d432c0cea0e198f554451d8fb7cb 3 | size 742571 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/05.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bd1dcc3c3673850b487e157c9a6a387ee2ca61dff73d7100363f53869926cf20 3 | size 799622 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/06-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fbb0562e113f1526ea82f4870b87cdd1db754572b7f1b97ffdc263ce424cf33a 3 | size 879852 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/06-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:50e0bbe029231d05c707a7dcb54d7bd677414f99af9d796c7ac6eb653cab3144 3 | size 772142 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/06-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c325a6f4f772bbd29e8b7776628b5e6a90ec11ad1ae9235d6b27cfb4e6409f63 3 | size 834411 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/06-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:63f8a1e17282870af9dfe468c53419af1abcf2011f19db80b8cb10194679a2e9 3 | size 774498 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/06.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3a0a97cd2f7ba432775b8a879ebdc7bb920a5bed1569c7ce1715f6449ed289cd 3 | size 889270 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/07-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b1f6e4c233c31f7e7138d066d445a1564f73d3ccd26f19c168a3d1e6d1a8a023 3 | size 713312 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/07-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:819272a0953675e23cdd5382ea8909d2031682c9ec987290920b8536ee082d8f 3 | size 835290 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/07-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:047bc71fc3f0868e36f145dab5697b367a6985638754ace5df8262975be6b5af 3 | size 688335 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/07-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:36bf6cf0193ad7cd491ff1b2fbb0aaca94cf5b4aeade771f05ee5d447c5f8fa6 3 | size 657367 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/07.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:01a867e034229add6177d6bd721f3abfa93f1f6b11e577319abd9f17eea78905 3 | size 759104 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/08-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:180ecff2b41577d8ae984a77bef7892906342d3c336b460dd4941888bc4c8d23 3 | size 730562 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/08-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7bdeaf1996277e93e7c2bba1536cc81cd267593a3b6664053c0c46ce7e61e528 3 | size 785996 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/08-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4b620d2d632f2e6f1b98270cab0b1e157a3bffe9f28542601bc9413c136d764e 3 | size 792644 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/08-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1e5fbc7f2437469bf14d4302341d7b8b461daa2bdc9c3e916464dbc7f630f2ab 3 | size 656469 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/08.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9251b2052486aadfe449929ff509db4736a564e52c9e03a86be2d477a9114589 3 | size 699299 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/09-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6cdaebd75b17bb822d81998a6ed2a5e7668578cfd66c31a81ed56394fa5bb56e 3 | size 725320 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/09-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:11edc6b5b1af38408be5ec82dfcb5f71728403c58aefeee318656eda545d6ef7 3 | size 748464 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/09-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5bb4b13dc78ea3d0334fee437d117def83b2bee1c670d3d4fa470f5a8f6aa61f 3 | size 690826 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/09-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2fcfa2cbec8de25af5d442ef272d91e0dc81449d83bf6d2ee16c395b1f84335c 3 | size 785183 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/09.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7532db564339747d22a1b2784806c4a7ebbaf7c01ff84d3a85574e56a2332a5a 3 | size 634212 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/10-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d9f29cd3bb5b333060c5ab0b8d838a122199c07b75e26470589e587effe2e897 3 | size 848933 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/10-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c15a8ed9d8791946b5150ce9498475e82748fe58aacfa12ace09c253b7b9fed4 3 | size 852247 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/10-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f4d246a1a89b27eda534af8c31f9bb9ed399b7ce589f5f8a02a8f5f2f7d47dee 3 | size 638689 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/10-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:24963ea2beaea673e3e24b096671e25d51d1ecbf40ea540c4e607361f4a191f3 3 | size 728790 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/10.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ad756193b91b2f71d421528057dc5166cfe8d63733c1acb4dcb614a691b63f30 3 | size 1025106 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/11-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:36eba9d5a6edcba9c9701f55860a338a63216bb40083ec28df710eeb3d7f55f1 3 | size 839083 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/11-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:be17874514fb5790b72b46b6454e21b8686d9646457bbde292ec6f3a7eaac015 3 | size 662859 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/11-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d5268a16ea5c1510e11772a5d3f90c208a76f55b68e72ba3d2147949d788629c 3 | size 764574 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/11-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:46b04b8130e461ca5ba292fb01db251d80041af4da3afe1614f3a80929cc6a4e 3 | size 849225 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/11.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5fccdc89a26bbd022c50468c51e1f9e3431f8a827c33229b5b6aedc0147fff71 3 | size 793927 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/12-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a10a5a1353d779b27756cdbdccd02939b97fcab96bfad04dc919114d10470ca1 3 | size 808120 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/12-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:97898d04164494f8cd9330260958495dd42f4909a2e90ad99b88667a62be2c26 3 | size 608743 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/12-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f258ee7c16938f2a5d77fb831a3232971d8aef9a5fcd4f73cb24fd0273663840 3 | size 741491 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/12-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:81565e44306ce9f5bc0a8afe4d0bad589d87f287c67338f7f19fa35a50314b82 3 | size 887185 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/12.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4c1a8720e2f004225a1a2271d5b2d2d98224236f1b9d93d11dce873c394861c9 3 | size 994315 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/13-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0b8ed3ed6de0ad1d1ec7dad060f5d479959517867cc951df22c6710f6fc13c8e 3 | size 772358 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/13-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4f19f6e30fda447eae1df39dbfc07730aab1c8cbf674aa93ebacad7a87a10b2c 3 | size 1063497 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/13-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:47027943347d2f5d3f75317ea15958b3830dc30e798f540bcd7b98a138c68816 3 | size 714389 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/13-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0075aa8e05a5e765fdfbfd9de51032671c73cd858857c0fa80b66dbb1af03404 3 | size 873409 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/13.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c4c057878087997e9425e76e71537321a1e370cac24cec0c8b012c37cd6d62bb 3 | size 823853 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/14-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e7e4fe6e440182e0506ff7c0fbfc9cadc9b96d46b2a172011d0da3010c5f0661 3 | size 799923 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/14-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b46757c70605864cb528f3f429fa551660a1c383272f9b9e01eee0add7d8b080 3 | size 721502 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/14-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7599db38a775f46912c8fb525f2d185c703830dd03412bffbeb7343216427b7a 3 | size 831779 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/14-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:60a3ad9b8da8e5ecabf31e34d30d62ec94876ebc01e3d3abab27b0e484db2404 3 | size 878203 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/14.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fb0d3192800506e063a93b8af052fb3f103d0fbd094247e3a08a8e582aa94983 3 | size 855564 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/15.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:70a0f84f3473a199c923f97e58dbe27ba9299e45193dbefbb4fa83f85f346069 3 | size 686374 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/16.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cc7e1b0b9277dba561f730f95c92eaab1f49cd505e3368b7a8a1e4ca61a835b3 3 | size 675903 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/17.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e29d19ed695383d214901a9b55f47b7d7c8e9202228c19b311c7c66f596bb609 3 | size 747799 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/18.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cf7cce532fe5a5a8d1650dd12854ba93db2d62b69058c5040c05706fbd2ed4c2 3 | size 758368 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/19.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0082ffc9a8749c5ad8833cef2e45cf00846f361e79aa87f511aac92b60a1aa61 3 | size 838004 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/20.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:65beb3da28f200b01de6b3cade0a10c54038178ac7034f73ed2e0e3ea7c2b38a 3 | size 830228 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/21.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:59c6beda0bd95283aefa2bc0cf119b958448152908e1b324ca994b6769c73049 3 | size 1036312 4 | -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/LICENSE: -------------------------------------------------------------------------------- 1 | This is the *original* Rider-Waite-Smith deck, published in 1910. Therefore, it 2 | is in the public domain in the United States. Other jurisdictions may vary. 3 | 4 | The images were scraped from http://muzendo.jp/blog/?p=19. -------------------------------------------------------------------------------- /frontend/assets/rider-waite-smith/back.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c18ff06006a86b2cec77c145f63fbc5d2daf8eec9f8e95865e1789de1a7d2e2b 3 | size 731024 4 | -------------------------------------------------------------------------------- /frontend/assets/scrape_rws.py: -------------------------------------------------------------------------------- 1 | # Scrapes all of the Tarot images to the directory given as its argument. 2 | import bs4 3 | import os 4 | import requests 5 | import sys 6 | 7 | URL = "http://muzendo.jp/blog/?p=19" 8 | SUITS = ["wands", "cups", "swords", "pents"] 9 | 10 | def get_image_urls(html): 11 | urls = {} 12 | images = [link.get('href') for link in html.find(class_="entry-content").find_all("a") 13 | if link.get('href').startswith('http://blogimg.goo.ne.jp')] 14 | if len(images) != 22 + 14 * 4 + 1: 15 | raise ValueError("Wrong number of images {}: {}".format(len(images), images)) 16 | # The second one is the card back. 17 | urls["00"] = images[0] 18 | urls["back"] = images[1] 19 | for i in range(1, 22): 20 | urls["{:02}".format(i)] = images[i + 1] 21 | for suit in SUITS: 22 | offset = len(urls) 23 | for i in range(1, 15): 24 | urls["{:02}-{}".format(i, suit)] = images[offset + i - 1] 25 | 26 | return urls 27 | 28 | 29 | if __name__ == "__main__": 30 | output_dir = sys.argv[1] 31 | html = bs4.BeautifulSoup(requests.get(URL).content, features="html.parser") 32 | for name, url in get_image_urls(html).items(): 33 | path = os.path.join(output_dir, "{}.jpg".format(name)) 34 | print("Saving {} to {}".format(url, path)) 35 | response = requests.get(url) 36 | if response.status_code == 200: 37 | with open(path, "wb") as f: 38 | f.write(response.content) 39 | else: 40 | print("Error {}".format(response.status_code)) 41 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/0(-1).jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:98e7c1053afcd1258e3a7756f076f92dc02bac5c50bf3fb2d99eb2795c482b4f 3 | size 295204 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/0(0).jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:87f63df826efc54664e0498089937a2bb03b69c9a69479b24d07bb83112d8ff6 3 | size 913604 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/0(2).jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:814f99600ee529f46a3893c8713c756dc18b6c291b6bb8ac96a22d7ef7bf42ed 3 | size 291213 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/0(5).jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e892be847b0b6ab3d29606bd09128c6b84481c70fbb1128ec38e10ebb5e6db20 3 | size 589077 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/00-VOID.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:62b0f439b9b2d19c5dedf46b7ff1fc76f198ea5f8ac55a699fc4653496e48e03 3 | size 48630 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/00.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5faac46ed0cfda29cf5b946e009160f2cbde3cec99ec7a65a5aaa2511495e99e 3 | size 380086 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/01-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fc50e5ac913ec0859b866a39973985df5aa87c104026eecb5f6bdd29b7e2df5a 3 | size 377897 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/01-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f6b87d63ce289cb3d1ab15fee82af29c2fe8ba92f2a69bb44946b1f3d4cab24d 3 | size 235783 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/01-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5e8a39dd1f542bd67f23f7c65b9fca330b898b336a449310489f8f566c382873 3 | size 333730 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/01-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b279a91a4f163a603f1efbe2d7238dee5d008430051ac80575533f745242f1b6 3 | size 296521 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/01.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1d20f8f6253111fd4159f8463dd8c20c768b1bc1db93c7e6df3151144b78eb3e 3 | size 292096 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/02-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1c38d9cc20d487408547098460ddfec5aaef91cd4c3390ffcf8bec4ebb447ce5 3 | size 485931 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/02-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ab3f4ab21d82fd27fda141751fe1dfe3045ac057e44e6061bff7e41d6fab8777 3 | size 1242729 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/02-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1b0fb6dd967caf3db79ff7084f2c7f58e3a843a4eacffd3862a4883aeb4b5b80 3 | size 248034 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/02-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2e62b66c72af970fb1068c5192073a22e4ece3aa6f52977fd55a9d0af33c8a13 3 | size 298565 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/02.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:91879439c05512f4bf1bd130133b8e34cf6cfba33bb00863e8bf9bbd7b23710a 3 | size 662248 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/03-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:970c7c79031fea85ad27d87f2876fd900199d0d2edc88bc52995e979686aa22a 3 | size 414587 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/03-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0aa3df55a15a7dbf27dd323f471ccda1689bb22ff2673bc9fe0a76770adabc12 3 | size 391033 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/03-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:169176a4b65e7a663f1edec050e77d0407aa7b83e888f3e0b4c8ef18224cc327 3 | size 375824 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/03-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:75448cb1ea3ff159ef44e7dad4f7409a8bf9b4d0af6287ffa217f4158a5e2ecf 3 | size 262631 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/03.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b72300cca55da776b7f14270ebd18e7f41efbfb0dfa4a36058351211a992dfc9 3 | size 284472 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/04-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:444dfe4c866c20450d4494ca44c71bd593cdf02b31883b5dcf3c5414d2179b62 3 | size 343705 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/04-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:221da160cc1ef7b59a7c4efebcc64a4cc9aa94e81850a357368d52b0c2c87a83 3 | size 277459 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/04-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f3926c43ccb04d308d930acdbcaaac549bc70dcc4ffea20d7ecd99dcf8f52860 3 | size 330063 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/04-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ec6fa233fc66fb17977939f9997077c53f6fc25dff6abcd58265189875c3d950 3 | size 310162 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/04.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dedb560627f63c1bfa661dc2884d4b815145d3275a41c1f3a0dd0f82c4f9deec 3 | size 313626 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/05-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2da9e168ee1a9937ae768585a2a8594483ad574d3342822213b045e4237960da 3 | size 203255 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/05-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:da546854ca86991cb4b006a38b4b5392462224ae8f7fed29101d3932d3535275 3 | size 279768 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/05-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9716d2992f6074167754e7a246fe0c8b6a3daabaedb02ac2c1454a6d5a264ff7 3 | size 227529 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/05-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a8dd67be47eb4ba0b308bc38943aed77d13bd49ae5eba56bccdb800144379932 3 | size 303934 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/05.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:594ff8f86473c73524047ce96f6886cd0fea08f599bd5039182ea6845ef57074 3 | size 594211 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/06-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:01ef2e2270b1aa14ef3bc192a00ff005d4bbbbcbc2d22052b4276a79c7758e01 3 | size 335834 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/06-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:805d9523c0c1444bb0eca199db08acb9a4d47d26c99a5e12c6cd79c04d6498aa 3 | size 579376 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/06-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1c6e6e48549a003995809550e9bc7c6a49b41e21d657746c075bd3ca379b97c8 3 | size 371422 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/06-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f6bfeb5a20c85b4fd411d9dd51800024488a2a0ef6b3b7031e60185595d3ebd0 3 | size 375107 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/06.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:979d6d8d879a1737c9469144f025b04899fa104075aa9b36b7ee267999f3d679 3 | size 295708 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/07-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1bb2a7d2f7d48e74e2c6917f9c223e03370e716224158fd5f4c321d4df21deb5 3 | size 468617 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/07-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2d3f8eec632f340dfa4dfd15545a080bafd70aa362942a2df9567eceb7e85ad0 3 | size 409400 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/07-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:696abff8fe398b32766df0e327f5358293d62a579a415aa359e8687a4de738d5 3 | size 407309 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/07-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:84eeb7bacbe0e48f19fe746a7eb64743e53f1f88ebfdc2768c02a126e9d9b615 3 | size 320631 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/07.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5a67e831397ec42c740d3adbb5aa840e2cb818a1bc897bc5fe9b482d5aa441bc 3 | size 287415 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/08-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:873f1357b236e987ed67210b25d193c2bf730c84bd2ad972972ac1f8e0b51074 3 | size 240566 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/08-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c194cc3dcca2fefcb5dce8584eb7ae1679778791a9611b8ca0228f43503835c0 3 | size 324724 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/08-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5af957707519ba57c46f37521f6dd1dec694c58eba386536e225b05e0e907cdf 3 | size 369459 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/08-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ec05988d1961c1475d949aaec70ae23b057c751d9df6a595e575b3995f56538c 3 | size 372965 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/08.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:941064b9ffbc973e760b04303b7cfe01866d50136162a83557017872dca7b9cf 3 | size 268808 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/09-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b340615de43df494d3c815b3ca911e9e9e4b0f1882734dfdddb761b3c56eb4e0 3 | size 374769 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/09-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:78977c08695dfc798767cd73d4eb02235e6ae8afe1c451ff4aa1f7806b149363 3 | size 375982 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/09-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d3bcf4f1c021e7f10d00415dc594325b92e1b988df97fef3e352fc5fb2afa5de 3 | size 276661 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/09-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4dfef205ee671dbd77294757afdfd7aee3c92eff5ed18e52c8b98066a2d22d19 3 | size 376752 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/09.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e006092c9fb7dcbc23921dc389bbeeb0e0ae1bcec1ccb0c900ed170b96eb3dca 3 | size 355312 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/10-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2008abce77352e6e15311983c7be5ca4c893a339016a2da5504181f5da5b2e10 3 | size 456799 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/10-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4606d15d833a8d520f5c42f514840c155dcbcb29cadc5b977ad34ee357fcff50 3 | size 549259 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/10-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:597fbe9b2300a47fe26c0d768c4ac1f34e3c43795f9e17d57df68d0b55252997 3 | size 323304 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/10-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0788ff814574e7999794d32f794eff833452506478a1f3ca6e6d2e5e52a1016b 3 | size 315565 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/10.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9b8ca8ddd654b719c52101fb29961b377db3a7c96b34c971ef3c7a68db2377df 3 | size 345848 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/11-VOID.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:537ec77375a8563b094b812f0d793fb48d3fe4f2204cbcf67ca930bdff086b08 3 | size 324354 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/11-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1f48a52c1ea3979f72e433bc52b53ccd43aeb2c948f45a57692e33cba5cc98b2 3 | size 210876 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/11-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4edc540eab9ec6bfec918425abcbec7a1d2eb79dc5da0015d3dabd6cf3f09888 3 | size 443977 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/11-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1a9e1830209b17c57bb38bf0d502ec6039702a426ee13138d680a3be5ecb79c6 3 | size 463428 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/11-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:44e8d56a5e7a45266f10dd118ae489857fa5408ecdcb2c5ac84c1fe7c216b600 3 | size 426223 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/11.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:72af84ec450e5dcb2b7e6b97fefa7bf684665563477f0cfdb69009c49a4b4322 3 | size 225904 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/12-VOID.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d8587001ac6aa1e98fc18ca7076850a006095da32e9be528b1f9e88c1eae1482 3 | size 601872 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/12-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8303359ea3b141f85b497b9d24db6d8a1b2022e9e70198dd1e7e1d4cedbdc2f4 3 | size 416769 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/12-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:97859677247743c965c47ea18859c80bc1b2afeaeeda5bf1afa82aff801a124f 3 | size 398227 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/12-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4395be1e8267f9cef50abb84e4b153bea9ad8b4ac97e2e6bd384ba71d7e12783 3 | size 349721 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/12-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:16e994ccfa5e42383c52e880edea86422d209b2903ad2e5a601b6b5dddd86e4a 3 | size 398524 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/12.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:28af3856fbfb476ba05b252aa3b511afadcc1f8c6853b4fd0ce6df30132aadb6 3 | size 264477 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13-VOID.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7f6563244e6c8764ff3978b9028464807c1772ea9d10fa5fe48b883167a2f29d 3 | size 175478 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a35d1777ccc6be79672ff97a35ea6ef0c64c56705104517676bac8e2b4fd830c 3 | size 243176 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:261b014ce3101f90519e0ba15e368daa77ed7a20c1d9946e99825798eb5ee725 3 | size 288887 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:994b2b33ad6e7db0e5874f180f68007be5ffa58b852852486d1919e3afa5c9cd 3 | size 464996 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:099eb289800531046bb521e3bf8f4294b484cd7e210193d05d11f9292f39fc0a 3 | size 305885 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:15dfb7db90b143d4670ec7f1b6284326192f5a2e2268ab89ec1b201f974429d8 3 | size 359668 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/13x.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d04c76b186865e230e9c76a703de203bd5c87145798ccbf80f2f616ea25cbf3c 3 | size 251212 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/14-VOID.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e6d6c08a554b3abdd17dd762e2e2a763d9f953608a9c1ddd6a90b71e5a97bafa 3 | size 424080 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/14-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:eec70be3777df224553d432d92975d45acc19fd9193f0b60895c73d5563d5d9e 3 | size 424469 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/14-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0ebee413a6a412e6be374b6958864cd894f150ccffcdcc183d6783d17b8d1d95 3 | size 313219 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/14-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:45e6854a25881784508f866a05cbe68330844066d736fa526ec587c975aa8317 3 | size 466595 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/14-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ee31ef7d01fdc332f0847fcc824e22029b2660567a1d2e030b8d17e31ef0a004 3 | size 428532 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/14.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aee2e5db42d8eebdf2ba398199fa84b28c114c8d64d80cefdb72a5b4d8f907e2 3 | size 287993 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/15.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:af1488d569f2ce4080751db1740a7a0bd83cdd48527fa464656c275fde899b7a 3 | size 578883 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/16.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fe1dd2a2da235d9cd1bea6fd7601affbb32a875206528cf3cd805a494cfad449 3 | size 392169 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/17.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d316aaf2c15fd74bd185a0737b03e244f160719ae9dce8813ddb53dd2677f211 3 | size 380927 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/18.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c6083f16bc8dc3b75fe3183d57ced02b7cdedc0b291041142cdf7ed64207be90 3 | size 198170 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/19.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b857ca9b4528bad2bf06b7a829c43a7eaa947cee36210b5165846f48c17b368d 3 | size 187721 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/20.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0d30b54e4f6ed6c87477a03eb4be34778d2c19155a9b8902043025d1cd7364ed 3 | size 277392 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/21.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1a46337298d44e9779c8d05eb2fd1542e7bf01285ad94085eb690f807ad0f402 3 | size 106884 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/8½.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:69aeda48f2c429b83bd3182866026b045cd23cbc6e560fd70bbc4c218c245d1a 3 | size 875122 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/99-cups.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:95910756fadab95503c364cc6c090e9b7f1ae084ebeddec8c617a9a4b07869bd 3 | size 454812 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/99-pents.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3ed18733a3acf1f2fc2ce44c1362f3086474cc08a057f9db003651e43264d1c0 3 | size 732132 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/99-swords.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d9ae67ef75655883d872f7d5a6f4a2e1f99bbdb52f800658838c9d132729dff8 3 | size 458941 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/99-wands.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7d7a4e45cabd2cd80d6834ef00062e8bcc36bbb09b6b531b4226fa5d6cac231f 3 | size 665485 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/LICENSE: -------------------------------------------------------------------------------- 1 | The images in this directory are copyright Egypt Urnash and used here with 2 | explicit permission. Please don't be a jerk with them. 3 | 4 | The Tarot of the Silicon Dawn is located at http://egypt.urnash.com/tarot/. -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/N4.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f4c28b1739eae90adc7c11bf7dc0fa9d9104cf88ff4d1fcf79d397b5cdfcb952 3 | size 528043 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/VIII.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a848d213664d2ee50d5b78dbfebdde14dcbac5ea3bfc102ebca197fa07f024c9 3 | size 408111 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/X.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d3a08e7a6aba21c18a4eca19c70ba7207a1f4c01be4b4fe96a94ede91d9484b0 3 | size 343538 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/back.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4026c7c8685d50b495dd5ba8f10c97b9d5350cc219d2a759d9a6a6c28b951bd4 3 | size 1022837 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/black.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4026c7c8685d50b495dd5ba8f10c97b9d5350cc219d2a759d9a6a6c28b951bd4 3 | size 1022837 4 | -------------------------------------------------------------------------------- /frontend/assets/silicon-dawn/white.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:62cf1b03a51517004593f5f367ee5c0da57cada5d27cb9e17a05bf2f2a05d43b 3 | size 30348 4 | -------------------------------------------------------------------------------- /frontend/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "transform": { 3 | "^.+\\.tsx?$": "ts-jest" 4 | }, 5 | "moduleNameMapper": { 6 | "\\.(css|scss|sass)$": "/__mocks__/styleMock.js", 7 | "\\.md$": "/__mocks__/rawMock.js" 8 | }, 9 | "setupTestFrameworkScriptFile": "src/setupTests.tsx", 10 | "collectCoverage": true, 11 | "collectCoverageFrom": [ 12 | "src/**/*.{ts,tsx}", 13 | ], 14 | "coveragePathIgnorePatterns": [ 15 | "/node_modules/", 16 | "\\.d.ts$", 17 | "src/index.tsx", 18 | "setupTests.tsx" 19 | ], 20 | "testURL": "http://localhost", 21 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$", 22 | "moduleFileExtensions": [ 23 | "ts", 24 | "tsx", 25 | "js", 26 | "jsx", 27 | "json", 28 | "node" 29 | ] 30 | }; 31 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lost-purpose-frontend", 3 | "version": "1.0.0", 4 | "description": "The frontend for the Tarot of the Lost Purpose.", 5 | "repository": "https://github.com/deifacted/lost-purpose", 6 | "scripts": { 7 | "test": "jest", 8 | "asciify": "./asciify.js" 9 | }, 10 | "author": "Astra", 11 | "license": "MIT", 12 | "dependencies": { 13 | "@types/classnames": "^2.2.6", 14 | "@types/delay": "^2.0.1", 15 | "@types/lodash": "^4.14.116", 16 | "@types/react": "^16.4.7", 17 | "@types/react-dom": "^16.0.6", 18 | "@types/react-modal": "^3.2.1", 19 | "@types/react-router-dom": "^4.3.1", 20 | "@types/uuid": "^3.4.3", 21 | "classnames": "^2.2.6", 22 | "crc-32": "^1.2.0", 23 | "css-loader": "^1.0.0", 24 | "delay": "^3.1.0", 25 | "immutability-helper": "^2.7.1", 26 | "lodash": "^4.17.21", 27 | "react": "^16.4.2", 28 | "react-dom": "^16.4.2", 29 | "react-markdown": "^3.6.0", 30 | "react-modal": "^3.5.1", 31 | "react-router-dom": "^4.3.1", 32 | "romanize": "^1.1.1", 33 | "style-loader": "^0.22.1", 34 | "typescript-formatter": "^7.2.2", 35 | "uuid": "^3.3.2" 36 | }, 37 | "devDependencies": { 38 | "@types/enzyme": "^3.1.14", 39 | "@types/enzyme-adapter-react-16": "^1.0.3", 40 | "@types/jest": "^23.3.1", 41 | "@types/webpack-env": "^1.13.6", 42 | "awesome-typescript-loader": "^5.2.0", 43 | "coveralls": "^3.0.2", 44 | "enzyme": "^3.6.0", 45 | "enzyme-adapter-react-16": "^1.5.0", 46 | "file-loader": "^1.1.11", 47 | "html-webpack-plugin": "^3.2.0", 48 | "jest": "^24.1.0", 49 | "node-sass": "^4.14.1", 50 | "raw-loader": "^0.5.1", 51 | "sass-loader": "^7.1.0", 52 | "source-map-loader": "^0.2.3", 53 | "ts-jest": "^23.1.2", 54 | "ts-node": "^7.0.0", 55 | "tslint": "^5.11.0", 56 | "tslint-react": "^3.6.0", 57 | "typescript": "^2.9.2", 58 | "webpack": "^4.43.0", 59 | "webpack-command": "^0.5.1", 60 | "webpack-serve": "^2.0.2" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /frontend/src/cards/__mocks__/artFinderContext.tsx: -------------------------------------------------------------------------------- 1 | import { Art, Card } from "../cards"; 2 | 3 | export function context(art: Art): (id: string) => string { 4 | return (id) => `/dummy/${Art[art]}/id.fake`; 5 | } 6 | -------------------------------------------------------------------------------- /frontend/src/cards/artFinder.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * A function for finding the path to the art asset for a given card. This is 3 | * separate from the card loic so that we don't have to mess around with 4 | * webpack's require.context when testing pure logic. 5 | */ 6 | import { context } from "./artFinderContext"; 7 | import { Art, Card, CardKind, Color, MajorArcana, Rank, Suit } from "./cards"; 8 | 9 | export function path(card: Card) { 10 | return context(card.art)(`./${fileName(card)}.jpg`); 11 | } 12 | 13 | export function thumbnail(card: Card) { 14 | return context(card.art)(`./thumbs/${fileName(card)}.jpg`); 15 | } 16 | 17 | export function back(card: Card) { 18 | switch (card.art) { 19 | case Art.SiliconDawn: return context(card.art)("./black.jpg"); 20 | case Art.RiderWaiteSmith: return context(card.art)("./back.jpg"); 21 | case Art.NeonMoon: return context(card.art)("./back.jpg"); 22 | } 23 | } 24 | 25 | /** 26 | * Finds the filename of the card in the repository/as the input to file-loader. 27 | */ 28 | function fileName(card: Card): string { 29 | switch (card.kind) { 30 | case CardKind.Major: 31 | switch (card.arcana) { 32 | case MajorArcana.Maya: return "8½"; 33 | case MajorArcana.Vulture: return "13x"; 34 | case MajorArcana.SheIsLegend: return "VIII"; 35 | case MajorArcana.History: return "X"; 36 | case MajorArcana.AlephFour: return "N4"; 37 | default: 38 | return twoDigitNumber(card.arcana); 39 | } 40 | case CardKind.Minor: 41 | return `${twoDigitNumber(card.rank)}-${suitComponent(card.suit)}`; 42 | case CardKind.Extra: 43 | switch (card.color) { 44 | case Color.White: return "white"; 45 | case Color.Black: return "black"; 46 | } 47 | } 48 | throw new Error(`Impossible card ${JSON.stringify(card)}`); 49 | } 50 | 51 | function twoDigitNumber(n: number) { 52 | return n < 10 ? "0" + n.toString() : n.toString(); 53 | } 54 | 55 | function suitComponent(suit: Suit) { 56 | switch (suit) { 57 | case Suit.Cups: return "cups"; 58 | case Suit.Pentacles: return "pents"; 59 | case Suit.Swords: return "swords"; 60 | case Suit.Wands: return "wands"; 61 | case Suit.Void: return "VOID"; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /frontend/src/cards/artFinderContext.tsx: -------------------------------------------------------------------------------- 1 | import { Art } from "./cards"; 2 | 3 | const riderWaiteSmithAscii = require.context("../../assets/rider-waite-smith-ascii", true, /\.jpg/); 4 | const siliconDawnAscii = require.context("../../assets/silicon-dawn-ascii", true, /\.jpg/); 5 | const neonMoonAscii = require.context("../../assets/neon-moon-ascii", true, /\.jpg/); 6 | 7 | export function context(art: Art): (id: string) => string { 8 | switch (art) { 9 | case Art.SiliconDawn: return siliconDawnAscii; 10 | case Art.RiderWaiteSmith: return riderWaiteSmithAscii; 11 | case Art.NeonMoon: return neonMoonAscii; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /frontend/src/cards/cardFormatter.spec.tsx: -------------------------------------------------------------------------------- 1 | import { CardFormatter, NumberFormat } from "./cardFormatter"; 2 | import { Art, CardKind, Color, MajorArcana, OrientedCard, Rank, Suit } from "./cards"; 3 | 4 | const art = Art.SiliconDawn; 5 | 6 | describe("numeric formatting", () => { 7 | const formatter = new CardFormatter({ 8 | romanNumeralMajorArcana: false, 9 | minorArcanaRankFormat: NumberFormat.Numerals, 10 | }); 11 | it("should format 5S correctly", () => { 12 | const card: OrientedCard = { 13 | kind: CardKind.Minor, 14 | rank: Rank.Five, 15 | suit: Suit.Swords, 16 | reversed: false, 17 | art, 18 | }; 19 | expect(formatter.format(card)).toBe("the 5 of Swords"); 20 | }); 21 | 22 | it("should format 99S correctly", () => { 23 | const card: OrientedCard = { 24 | kind: CardKind.Minor, 25 | rank: Rank.NinetyNine, 26 | suit: Suit.Swords, 27 | reversed: false, 28 | art, 29 | }; 30 | expect(formatter.format(card)).toBe("the 99 of Swords"); 31 | }); 32 | }); 33 | 34 | describe("roman numeral formatting", () => { 35 | const options = { 36 | romanNumeralMajorArcana: true, 37 | minorArcanaRankFormat: NumberFormat.Roman, 38 | }; 39 | const formatter = new CardFormatter({ 40 | romanNumeralMajorArcana: true, 41 | minorArcanaRankFormat: NumberFormat.Roman, 42 | }); 43 | it("should format the Fool correctly", () => { 44 | const fool: OrientedCard = { 45 | kind: CardKind.Major, 46 | arcana: MajorArcana.Fool, 47 | reversed: false, 48 | art, 49 | }; 50 | expect(formatter.format(fool)).toBe("0, the Fool"); 51 | }); 52 | 53 | it("should format the 99 correctly", () => { 54 | const card: OrientedCard = { 55 | kind: CardKind.Minor, 56 | rank: Rank.NinetyNine, 57 | suit: Suit.Swords, 58 | reversed: false, 59 | art, 60 | }; 61 | expect(formatter.format(card)).toBe("the XCIX of Swords"); 62 | }); 63 | 64 | it("should format the zero of (VOID) correctly", () => { 65 | expect(formatter.format({ 66 | kind: CardKind.Minor, 67 | rank: Rank.Zero, 68 | suit: Suit.Void, 69 | reversed: false, 70 | art, 71 | })).toBe("the 0 of (VOID)"); 72 | }); 73 | }); 74 | 75 | describe("major arcana name formatting", () => { 76 | const formatter = new CardFormatter(); 77 | it("should include 'the' when appropriate", () => { 78 | expect(formatter.format({ 79 | kind: CardKind.Major, 80 | arcana: MajorArcana.Magician, 81 | reversed: false, 82 | art, 83 | })) 84 | .toBe("the Magician"); 85 | }); 86 | it("should not include 'the' when not appropriate", () => { 87 | expect(formatter.format({ 88 | kind: CardKind.Major, 89 | arcana: MajorArcana.Death, 90 | reversed: false, 91 | art, 92 | })) 93 | .toBe("Death"); 94 | }); 95 | }); 96 | 97 | describe("reversed card handling", () => { 98 | const formatter = new CardFormatter(); 99 | it("should indicate when a card is reversed", () => { 100 | expect(formatter.format({ 101 | kind: CardKind.Major, 102 | arcana: MajorArcana.Tower, 103 | reversed: true, 104 | art, 105 | })) 106 | .toContain("reversed"); 107 | expect(formatter.format({ 108 | kind: CardKind.Minor, 109 | rank: Rank.Four, 110 | suit: Suit.Cups, 111 | reversed: true, 112 | art, 113 | })) 114 | .toContain("reversed"); 115 | }); 116 | it("should not indicate when the (VOID) is reversed", () => { 117 | expect(formatter.format({ 118 | kind: CardKind.Minor, 119 | rank: Rank.Queen, 120 | suit: Suit.Void, 121 | reversed: true, 122 | art, 123 | })).not.toContain("reversed"); 124 | }); 125 | it("should not indicate when an 'extra' card is reversed", () => { 126 | expect(formatter.format({ 127 | kind: CardKind.Extra, 128 | color: Color.White, 129 | reversed: true, 130 | art, 131 | })).not.toContain("reversed"); 132 | }); 133 | }); 134 | -------------------------------------------------------------------------------- /frontend/src/cards/cardFormatter.tsx: -------------------------------------------------------------------------------- 1 | import romanize = require("romanize"); 2 | import { Card, CardKind, Color, MajorArcana, OrientedCard, Rank, Suit } from "./cards"; 3 | 4 | export enum NumberFormat { 5 | Roman, 6 | Words, 7 | Numerals, 8 | } 9 | 10 | export type Options = { 11 | /** If true, major arcana are formatted like "XIII, Death". Defaults to false. */ 12 | romanNumeralMajorArcana: boolean; 13 | /** 14 | * Determines how to format the numbers for minor arcana: "VIII of Cups", "Eight of Cups", or "8 of Cups". 15 | * Defaults to words. 16 | */ 17 | minorArcanaRankFormat: NumberFormat; 18 | }; 19 | 20 | export class CardFormatter { 21 | 22 | private static majorName = new Map([ 23 | [MajorArcana.Fool, "the Fool"], 24 | [MajorArcana.Magician, "the Magician"], 25 | [MajorArcana.HighPriestess, "the High Priestess"], 26 | [MajorArcana.Empress, "the Empress"], 27 | [MajorArcana.Emperor, "the Emperor"], 28 | [MajorArcana.HighPriest, "the High Priest"], 29 | [MajorArcana.Lovers, "the Lovers"], 30 | [MajorArcana.Chariot, "the Chariot"], 31 | [MajorArcana.Strength, "Strength"], 32 | [MajorArcana.Hermit, "the Hermit"], 33 | [MajorArcana.Fortune, "Fortune"], 34 | [MajorArcana.Justice, "Justice"], 35 | [MajorArcana.HangedMan, "the Hanged Man"], 36 | [MajorArcana.Death, "Death"], 37 | [MajorArcana.Temperance, "Temperance"], 38 | [MajorArcana.Devil, "the Devil"], 39 | [MajorArcana.Tower, "the Tower"], 40 | [MajorArcana.Star, "the Star"], 41 | [MajorArcana.Moon, "the Moon"], 42 | [MajorArcana.Sun, "the Sun"], 43 | [MajorArcana.Judgement, "Judgement"], 44 | [MajorArcana.World, "the World"], 45 | [MajorArcana.Maya, "Maya"], 46 | [MajorArcana.Vulture, "the Vulture"], 47 | [MajorArcana.SheIsLegend, "She-is-Legend"], 48 | [MajorArcana.History, "History"], 49 | [MajorArcana.AlephFour, "\u2135\u2084"], 50 | ]); 51 | 52 | private static numberWords = new Map([ 53 | [Rank.Zero, "Zero"], 54 | [Rank.One, "Ace"], 55 | [Rank.Two, "Two"], 56 | [Rank.Three, "Three"], 57 | [Rank.Four, "Four"], 58 | [Rank.Five, "Five"], 59 | [Rank.Six, "Six"], 60 | [Rank.Seven, "Seven"], 61 | [Rank.Eight, "Eight"], 62 | [Rank.Nine, "Nine"], 63 | [Rank.Ten, "Ten"], 64 | [Rank.Progeny, "Progeny"], 65 | [Rank.Cavalier, "Cavalier"], 66 | [Rank.Queen, "Queen"], 67 | [Rank.King, "King"], 68 | [Rank.NinetyNine, "Ninety-Nine"], 69 | ]); 70 | 71 | private static formatSuit: Map = new Map([ 72 | [Suit.Wands, "Wands"], 73 | [Suit.Cups, "Cups"], 74 | [Suit.Swords, "Swords"], 75 | [Suit.Pentacles, "Pentacles"], 76 | [Suit.Void, "(VOID)"], 77 | ]); 78 | 79 | private static formatExtra = new Map([ 80 | [Color.White, "A blank card"], 81 | [Color.Black, "The card with two backs"], 82 | ]); 83 | public options: Options; 84 | 85 | constructor(options: Partial = {}) { 86 | this.options = { 87 | romanNumeralMajorArcana: false, 88 | minorArcanaRankFormat: NumberFormat.Words, 89 | }; 90 | this.options = Object.assign(this.options, options); 91 | } 92 | 93 | public format(card: OrientedCard): string { 94 | const unoriented = this.formatUnoriented(card); 95 | const kind = card.kind; 96 | // The (VOID) cards and the 'extras' cannot be reversed. 97 | const shouldIndicateReversal = 98 | card.kind === CardKind.Major || (card.kind === CardKind.Minor && card.suit !== Suit.Void); 99 | if (card.reversed && shouldIndicateReversal) { 100 | return `${unoriented}, reversed`; 101 | } else { 102 | return unoriented; 103 | } 104 | } 105 | 106 | private formatUnoriented(card: Card): string { 107 | switch (card.kind) { 108 | case CardKind.Major: 109 | return this.formatMajor(card.arcana); 110 | case CardKind.Minor: 111 | return `the ${this.formatRank(card.rank)} of ${CardFormatter.formatSuit.get(card.suit)}`; 112 | case CardKind.Extra: 113 | return CardFormatter.formatExtra.get(card.color)!; 114 | } 115 | } 116 | 117 | private formatMajor(arcana: MajorArcana): string { 118 | const name = CardFormatter.majorName.get(arcana)!; 119 | if (this.options.romanNumeralMajorArcana && MajorArcana.isStandard(arcana)) { 120 | return `${zeroAwareRomanize(arcana)}, ${name}`; 121 | } else { 122 | return name; 123 | } 124 | } 125 | 126 | private formatRank(rank: Rank): string { 127 | switch (this.options.minorArcanaRankFormat) { 128 | case NumberFormat.Roman: return zeroAwareRomanize(rank); 129 | case NumberFormat.Numerals: return String(rank); 130 | case NumberFormat.Words: { 131 | return CardFormatter.numberWords.get(rank)!; 132 | } 133 | } 134 | } 135 | } 136 | 137 | function zeroAwareRomanize(n: number): string { 138 | return n === 0 ? "0" : romanize(n); 139 | } 140 | -------------------------------------------------------------------------------- /frontend/src/cards/cards.spec.tsx: -------------------------------------------------------------------------------- 1 | import { Art, MajorArcana, Rank, siliconDawn, standard, Suit } from "./cards"; 2 | 3 | describe("Rider-Waite-Smith", () => { 4 | it("should have all cards using Rider-Waite-Smith art", () => { 5 | expect(standard().every((card) => card.art === Art.RiderWaiteSmith)); 6 | }); 7 | 8 | it("should have the right number of cards", () => { 9 | expect(standard().length).toBe(22 + 4 * 14); 10 | }); 11 | }); 12 | 13 | describe("decks", () => { 14 | it("should start face-up", () => { 15 | expect(standard().filter((card) => card.reversed === false).length).toBe(78); 16 | expect(siliconDawn().filter((card) => card.reversed === false).length).toBe(94); 17 | }); 18 | 19 | // 22 major arcana, 14 ranks in 4 suits each. 20 | const standardCount = 22 + 14 * 4; 21 | const ninetyNineCount = 4; 22 | const voidCount = 5; 23 | const extraCount = 7; 24 | describe("silicon dawn", () => { 25 | 26 | it("should default all options to true", () => { 27 | const noOptions = siliconDawn(); 28 | const emptyOptions = siliconDawn({ voidSuit: true, ninetyNines: true, extraArcana: true }); 29 | expect(noOptions).toEqual(emptyOptions); 30 | }); 31 | 32 | it("should have the right number of cards with all default options", () => { 33 | expect(siliconDawn().length).toBe(standardCount + ninetyNineCount + voidCount + extraCount); 34 | }); 35 | 36 | it("should have the right number of cards with no extras", () => { 37 | const options = { voidSuit: false, ninetyNines: false, extraArcana: false }; 38 | expect(siliconDawn(options).length).toBe(standardCount); 39 | }); 40 | 41 | it("should have the right number of cards with the void suit", () => { 42 | const options = { voidSuit: true, ninetyNines: false, extraArcana: false }; 43 | expect(siliconDawn(options).length).toBe(standardCount + voidCount); 44 | }); 45 | 46 | it("should have the right number of cards with the 99s", () => { 47 | const options = { voidSuit: false, ninetyNines: true, extraArcana: false }; 48 | expect(siliconDawn(options).length).toBe(standardCount + ninetyNineCount); 49 | }); 50 | 51 | it("should have the right number of cards with the extra arcana", () => { 52 | const options = { voidSuit: false, ninetyNines: false, extraArcana: true }; 53 | expect(siliconDawn(options).length).toBe(standardCount + extraCount); 54 | }); 55 | 56 | it("should have all cards using Silicon Dawn art", () => { 57 | expect(siliconDawn().every((card) => card.art === Art.SiliconDawn)); 58 | }); 59 | }); 60 | }); 61 | 62 | describe("the major arcana", () => { 63 | it("should have the right count of standard arcana", () => { 64 | expect(MajorArcana.standard().length).toBe(22); 65 | }); 66 | 67 | it("should have the right count of Silicon Dawn arcana", () => { 68 | expect(MajorArcana.siliconDawn().length).toBe(5); 69 | }); 70 | }); 71 | 72 | describe("the ranks", () => { 73 | it("should have the right count of standard ranks", () => { 74 | expect(Rank.standard().length).toBe(14); 75 | }); 76 | }); 77 | 78 | describe("the suits", () => { 79 | it("should have the right count of standard suits", () => { 80 | expect(Suit.standard().length).toBe(4); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /frontend/src/cards/cards.tsx: -------------------------------------------------------------------------------- 1 | export interface Deck { 2 | cards: OrientedCard[]; 3 | name: string; 4 | /** UUIDv4 format ID. */ 5 | id: string; 6 | } 7 | 8 | export function standard(art: Art = Art.RiderWaiteSmith): OrientedCard[] { 9 | const cards: OrientedCard[] = []; 10 | for (const major of MajorArcana.standard()) { 11 | cards.push({ kind: CardKind.Major, arcana: major, reversed: false, art }); 12 | } 13 | for (const rank of Rank.standard()) { 14 | for (const suit of Suit.standard()) { 15 | cards.push({ kind: CardKind.Minor, rank, suit, reversed: false, art }); 16 | } 17 | } 18 | return cards; 19 | } 20 | 21 | /** 22 | * Creates a new Tarot of the Silicon Dawn deck. 23 | * @param voidSuit Whether to include the VOID suit. 24 | * @param ninetyNines Whether to include the 99 rank of each suit. 25 | * @param extraArcana A list of the nonstandard major arcana to use. Defaults to all of them. 26 | */ 27 | export function siliconDawn( 28 | options = { voidSuit: true, ninetyNines: true, extraArcana: true }) 29 | : OrientedCard[] { 30 | let cards = standard(); 31 | const art = Art.SiliconDawn; 32 | cards.forEach((card) => card.art = art); 33 | if (options.voidSuit) { 34 | const voidRanks = [Rank.Zero, Rank.Progeny, Rank.Cavalier, Rank.Queen, Rank.King]; 35 | const voids = voidRanks.map((rank): OrientedCard => ({ 36 | kind: CardKind.Minor, 37 | rank, 38 | suit: Suit.Void, 39 | reversed: false, 40 | art, 41 | })); 42 | cards = cards.concat(voids); 43 | } 44 | if (options.ninetyNines) { 45 | const ninetyNines = Suit.standard().map((suit): OrientedCard => ({ 46 | kind: CardKind.Minor, 47 | rank: Rank.NinetyNine, 48 | suit, 49 | reversed: false, 50 | art, 51 | })); 52 | cards = cards.concat(ninetyNines); 53 | } 54 | if (options.extraArcana) { 55 | const extraCards = MajorArcana.siliconDawn().map((arcana): OrientedCard => ({ 56 | kind: CardKind.Major, 57 | arcana, 58 | reversed: false, 59 | art, 60 | })); 61 | cards = cards.concat(extraCards); 62 | cards = cards.concat([ 63 | { kind: CardKind.Extra, color: Color.Black, reversed: false, art }, 64 | { kind: CardKind.Extra, color: Color.White, reversed: false, art }, 65 | ]); 66 | } 67 | return cards; 68 | } 69 | 70 | export enum CardKind { 71 | Major, 72 | Minor, 73 | Extra, 74 | } 75 | 76 | export interface MajorCard { 77 | kind: CardKind.Major; 78 | arcana: MajorArcana; 79 | } 80 | 81 | export interface MinorCard { 82 | kind: CardKind.Minor; 83 | rank: Rank; 84 | suit: Suit; 85 | } 86 | 87 | /** 88 | * Silicon Dawn also includes one card that has a black face and one with a 89 | * white face. 90 | */ 91 | export interface ExtraCard { 92 | kind: CardKind.Extra; 93 | color: Color; 94 | } 95 | 96 | export enum Art { 97 | SiliconDawn, 98 | RiderWaiteSmith, 99 | NeonMoon, 100 | } 101 | 102 | export type Card = (MajorCard | MinorCard | ExtraCard) & { art: Art }; 103 | export type OrientedCard = Card & { reversed: boolean }; 104 | 105 | export function isStandardMajorArcana(majorArcana: MajorArcana) { 106 | return majorArcana <= MajorArcana.World; 107 | } 108 | 109 | // The Arcana are the means by which all is revealed. 110 | export enum MajorArcana { 111 | Fool = 0, 112 | Magician, 113 | HighPriestess, 114 | Empress, 115 | Emperor, 116 | HighPriest, 117 | Lovers, 118 | Chariot, 119 | Strength, 120 | Hermit, 121 | Fortune, 122 | Justice, 123 | HangedMan, 124 | Death, 125 | Temperance, 126 | Devil, 127 | Tower, 128 | Star, 129 | Moon, 130 | Sun, 131 | Judgement, 132 | World, 133 | // Silicon dawn only. 134 | Maya, 135 | Vulture, 136 | SheIsLegend, 137 | History, 138 | AlephFour, 139 | } 140 | 141 | // tslint:disable-next-line:no-namespace 142 | export namespace MajorArcana { 143 | export function standard() { 144 | return [ 145 | MajorArcana.Fool, 146 | MajorArcana.Magician, 147 | MajorArcana.HighPriestess, 148 | MajorArcana.Empress, 149 | MajorArcana.Emperor, 150 | MajorArcana.HighPriest, 151 | MajorArcana.Lovers, 152 | MajorArcana.Chariot, 153 | MajorArcana.Strength, 154 | MajorArcana.Hermit, 155 | MajorArcana.Fortune, 156 | MajorArcana.Justice, 157 | MajorArcana.HangedMan, 158 | MajorArcana.Death, 159 | MajorArcana.Temperance, 160 | MajorArcana.Devil, 161 | MajorArcana.Tower, 162 | MajorArcana.Star, 163 | MajorArcana.Moon, 164 | MajorArcana.Sun, 165 | MajorArcana.Judgement, 166 | MajorArcana.World, 167 | ]; 168 | } 169 | 170 | export function siliconDawn() { 171 | return [ 172 | MajorArcana.Maya, 173 | MajorArcana.Vulture, 174 | MajorArcana.SheIsLegend, 175 | MajorArcana.History, 176 | MajorArcana.AlephFour, 177 | ]; 178 | } 179 | 180 | export function isStandard(arcana: MajorArcana): boolean { 181 | return arcana <= MajorArcana.World; 182 | } 183 | } 184 | 185 | export enum Rank { 186 | // Silicon dawn only. 187 | Zero = 0, 188 | One, 189 | Two, 190 | Three, 191 | Four, 192 | Five, 193 | Six, 194 | Seven, 195 | Eight, 196 | Nine, 197 | Ten, 198 | Progeny, 199 | Cavalier, 200 | Queen, 201 | King, 202 | // Silicon dawn only. 203 | NinetyNine = 99, 204 | } 205 | 206 | // tslint:disable-next-line:no-namespace 207 | export namespace Rank { 208 | export function standard() { 209 | return [ 210 | Rank.One, 211 | Rank.Two, 212 | Rank.Three, 213 | Rank.Four, 214 | Rank.Five, 215 | Rank.Six, 216 | Rank.Seven, 217 | Rank.Eight, 218 | Rank.Nine, 219 | Rank.Ten, 220 | Rank.Progeny, 221 | Rank.Cavalier, 222 | Rank.Queen, 223 | Rank.King, 224 | ]; 225 | } 226 | } 227 | 228 | export enum Suit { 229 | Wands, 230 | Cups, 231 | Swords, 232 | Pentacles, 233 | // Silicon Dawn only. Has a 0, Progeny, Cavalier, Queen, and King, but nothing else. 234 | Void, 235 | } 236 | 237 | // tslint:disable-next-line:no-namespace 238 | export namespace Suit { 239 | export function standard() { 240 | return [ 241 | Suit.Wands, 242 | Suit.Cups, 243 | Suit.Swords, 244 | Suit.Pentacles, 245 | ]; 246 | } 247 | } 248 | 249 | export enum Color { 250 | White, 251 | Black, 252 | } 253 | -------------------------------------------------------------------------------- /frontend/src/cards/interpret.spec.tsx: -------------------------------------------------------------------------------- 1 | import { Art, Card, CardKind, Color, MajorArcana, Rank, siliconDawn, standard, Suit } from "./cards"; 2 | import * as interpret from "./interpret"; 3 | 4 | describe("RWS tarot meaning data", () => { 5 | const table = standard().map((card) => [card]); 6 | describe.each(table)("%j", (card) => { 7 | const interpretation = interpret.rws(card); 8 | it("should have an interpretation", () => { 9 | expect(interpretation).toBeTruthy(); 10 | expect(interpretation!.fortuneTelling).not.toHaveLength(0); 11 | expect(interpretation!.keywords).not.toHaveLength(0); 12 | expect(interpretation!.meanings.upright).not.toHaveLength(0); 13 | expect(interpretation!.meanings.reversed).not.toHaveLength(0); 14 | }); 15 | }); 16 | 17 | const alephFour: Card = { 18 | kind: CardKind.Major, 19 | arcana: MajorArcana.AlephFour, 20 | art: Art.SiliconDawn, 21 | }; 22 | const ninetyNineSwords: Card = { 23 | kind: CardKind.Minor, 24 | rank: Rank.NinetyNine, 25 | suit: Suit.Swords, 26 | art: Art.SiliconDawn, 27 | }; 28 | const queenOfVoid: Card = { 29 | kind: CardKind.Minor, 30 | rank: Rank.Queen, 31 | suit: Suit.Void, 32 | art: Art.SiliconDawn, 33 | }; 34 | const extra: Card = { 35 | kind: CardKind.Extra, 36 | color: Color.Black, 37 | art: Art.SiliconDawn, 38 | }; 39 | describe.each([alephFour, ninetyNineSwords, queenOfVoid, extra])("%j", (card) => { 40 | it("should not have an interpretation", () => { 41 | expect(interpret.rws(card)).toBeFalsy(); 42 | }); 43 | }); 44 | }); 45 | 46 | describe("Silicon Dawn tarot meaning data", () => { 47 | const table = siliconDawn(); 48 | describe.each(siliconDawn())("%j", (card) => { 49 | it("should have an interpretation", () => { 50 | const interpretation = interpret.siliconDawn(card); 51 | expect(interpretation).toBeTruthy(); 52 | expect(interpretation!.title).toBeTruthy(); 53 | expect(interpretation!.meaning).not.toHaveLength(0); 54 | }); 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /frontend/src/cards/interpret.tsx: -------------------------------------------------------------------------------- 1 | import siliconDawnJson from "../../assets/silicon-dawn/interpretations.json"; 2 | import rawJson from "../../assets/tarot_interpretations.json"; 3 | import { Art, Card, CardKind, Color, MajorArcana, Rank, Suit } from "./cards"; 4 | 5 | export interface RWSInterpretation { 6 | fortuneTelling: string[]; 7 | keywords: string[]; 8 | meanings: { 9 | upright: string[], 10 | reversed: string[], 11 | }; 12 | } 13 | 14 | export interface SiliconDawnInterpretation { 15 | title: string; 16 | // Each element of this list should be its own paragraph. 17 | meaning: string[]; 18 | } 19 | 20 | /** 21 | * An interpretation for the tarot card with the given rank and suit. Calling 22 | * this with Silicon Dawn cards produces undefined behavior, as those cards use 23 | * significantly different symbolism. 24 | */ 25 | export function rws(card: Card): RWSInterpretation | undefined { 26 | if (card.art === Art.SiliconDawn) { 27 | return undefined; 28 | } 29 | switch (card.kind) { 30 | case CardKind.Major: 31 | return majorInterpretations.get(card.arcana); 32 | case CardKind.Minor: { 33 | const suits = minorInterpretations.get(card.rank); 34 | return suits ? suits.get(card.suit) : undefined; 35 | } 36 | default: 37 | return undefined; 38 | } 39 | } 40 | 41 | export function siliconDawn(card: Card): SiliconDawnInterpretation | undefined { 42 | if (card.art !== Art.SiliconDawn) { 43 | return undefined; 44 | } 45 | switch (card.kind) { 46 | case CardKind.Major: 47 | return siliconDawnJson.majors[card.arcana]; 48 | case CardKind.Minor: 49 | const rank = card.rank === 99 ? 15 : card.rank; 50 | const minor = siliconDawnJson.minors[rank][card.suit]; 51 | if (minor === null) { 52 | // Should never happen. The only nulls are for rank 0, 'normal' suits. 53 | throw new Error(`Unexpected null with card ${card}`); 54 | } 55 | return minor; 56 | case CardKind.Extra: 57 | switch (card.color) { 58 | case Color.Black: 59 | return siliconDawnJson.extras.black; 60 | case Color.White: 61 | return siliconDawnJson.extras.white; 62 | } 63 | } 64 | } 65 | 66 | const majorInterpretations: Map = new Map(); 67 | const minorInterpretations: Map> = new Map(); 68 | for (const raw of rawJson.tarot_interpretations) { 69 | const cleaned = { 70 | fortuneTelling: raw.fortune_telling, 71 | keywords: raw.keywords, 72 | meanings: { 73 | upright: raw.meanings.light, 74 | reversed: raw.meanings.shadow, 75 | }, 76 | }; 77 | if (raw.suit === "major") { 78 | majorInterpretations.set(raw.rank as MajorArcana, cleaned); 79 | } else { 80 | const rank = parseRawRank(raw.rank); 81 | const suit = parseRawSuit(raw.suit); 82 | if (!minorInterpretations.has(rank)) { 83 | minorInterpretations.set(rank, new Map()); 84 | } 85 | minorInterpretations.get(rank)!.set(suit, { 86 | fortuneTelling: raw.fortune_telling, 87 | keywords: raw.keywords, 88 | meanings: { 89 | upright: raw.meanings.light, 90 | reversed: raw.meanings.shadow, 91 | }, 92 | }); 93 | } 94 | } 95 | 96 | // Below is code for converting the JSON into something Typescript can handle. 97 | 98 | function parseRawRank(rawRank: string | number): Rank { 99 | switch (rawRank) { 100 | case "page": return Rank.Progeny; 101 | case "knight": return Rank.Cavalier; 102 | case "queen": return Rank.Queen; 103 | case "king": return Rank.King; 104 | default: 105 | return rawRank as Rank; 106 | } 107 | } 108 | 109 | function parseRawSuit(rawSuit: string): Suit { 110 | switch (rawSuit) { 111 | case "cups": return Suit.Cups; 112 | case "swords": return Suit.Swords; 113 | case "wands": return Suit.Wands; 114 | case "pentacles": return Suit.Pentacles; 115 | default: 116 | throw new Error("Unknown raw suit `${rawSuit}`"); 117 | } 118 | } 119 | 120 | // The interpretation interface in the raw data. 121 | interface RawInterpretation { 122 | fortune_telling: string[]; 123 | keywords: string[]; 124 | meanings: { 125 | light: string[], 126 | shadow: string[], 127 | }; 128 | rank: number; 129 | suit: string; 130 | } 131 | -------------------------------------------------------------------------------- /frontend/src/cards/lfsr.spec.tsx: -------------------------------------------------------------------------------- 1 | import { LFSR } from "./lfsr"; 2 | 3 | describe("nonsensical inputs", () => { 4 | it("should fail if the feed is unsafe", () => { 5 | expect(() => new LFSR(Number.MAX_SAFE_INTEGER + 1, 1)).toThrow(); 6 | }); 7 | it("should fail if the state is unsafe", () => { 8 | expect(() => new LFSR(Number.MAX_SAFE_INTEGER + 1, 0x9)).toThrow(); 9 | }); 10 | }); 11 | 12 | it("should always output 0s if the state is 0", () => { 13 | const lfsr = new LFSR(0); 14 | expect(lfsr.random()).toBe(0); 15 | expect(lfsr.random()).toBe(0); 16 | }); 17 | 18 | it("should output something nonzero if the state is not 0", () => { 19 | const lfsr = new LFSR(12345); 20 | expect(lfsr.random()).not.toBe(0); 21 | }); 22 | 23 | it("should be deterministic", () => { 24 | const lfsr1 = new LFSR(12345); 25 | const lfsr2 = new LFSR(12345); 26 | expect(lfsr1.random()).toBe(lfsr2.random()); 27 | }); 28 | 29 | it("should not always output the same value", () => { 30 | const lfsr = new LFSR(54321); 31 | expect(lfsr.random()).not.toBe(lfsr.random()); 32 | }); 33 | 34 | it("should have the proper period for small states", () => { 35 | // 0xC should give something with period 15. 36 | const lfsr = new LFSR(3, 0xC); 37 | const values = []; 38 | for (let i = 0; i < 15; i++) { 39 | values.push(lfsr.nextBit()); 40 | } 41 | const repeatedValues = []; 42 | for (let i = 0; i < 15; i++) { 43 | repeatedValues.push(lfsr.nextBit()); 44 | } 45 | expect(repeatedValues).toEqual(values); 46 | }); 47 | -------------------------------------------------------------------------------- /frontend/src/cards/lfsr.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * An implementation of a linear-feedback shift register. **Do not use this 3 | * for actual cryptography!** It's *intentionally* not high-quality and LFSRs 4 | * have personal significance to the author (they were one of the first random) 5 | * (number generators she remembers reading about). 6 | */ 7 | 8 | /* tslint:disable:no-bitwise */ 9 | 10 | export class LFSR { 11 | public feed: number; 12 | public state: number; 13 | 14 | // feed and state must be <= MAX_SAFE_INTEGER. The feed values should be taken 15 | // from http://users.ece.cmu.edu/~koopman/lfsr/index.html. 16 | constructor(state: number, feed?: number) { 17 | if (!feed) { 18 | feed = 0x8000000000004; 19 | } 20 | if (feed > Number.MAX_SAFE_INTEGER || state > Number.MAX_SAFE_INTEGER) { 21 | throw new Error("Feed and state must be <= MAX_SAFE_INTEGER"); 22 | } 23 | this.feed = feed; 24 | this.state = state; 25 | } 26 | 27 | // In general you shouldn't need this, but it being public makes testing vastly easier. 28 | public nextBit(): number { 29 | const bit = this.state & 1; 30 | this.state >>= 1; 31 | if (bit) { 32 | this.state ^= this.feed; 33 | } 34 | return bit; 35 | } 36 | 37 | // Generates uniformly-distributed random number in the range [0, 1) similar to Math.random(). 38 | public random(): number { 39 | let out = 0; 40 | for (let i = 1; i < 53; i++) { 41 | out += this.nextBit() * Math.pow(2, -i); 42 | } 43 | return out; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /frontend/src/cards/shuffle.spec.tsx: -------------------------------------------------------------------------------- 1 | import * as _ from "lodash"; 2 | import { shuffle } from "./shuffle"; 3 | 4 | function faceUpDeck(values: number[]): Array<{ value: number, reversed: boolean }> { 5 | return values.map((value) => ({ value, reversed: false })); 6 | } 7 | 8 | describe("shuffling", () => { 9 | it("should should leave an empty deck empty", () => { 10 | expect(shuffle([])).toHaveLength(0); 11 | }); 12 | 13 | describe("reordering", () => { 14 | it("should swap the cards in a two-card deck", () => { 15 | expect(shuffle(faceUpDeck([0, 1])).map((x) => x.value)) 16 | .toEqual([1, 0]); 17 | }); 18 | 19 | it("should leave the elements in a hundred-card deck the same", () => { 20 | const shuffled = shuffle(faceUpDeck(_.range(100))); 21 | expect(shuffled).toHaveLength(100); 22 | expect(shuffled.map((x) => x.value)) 23 | .toEqual(expect.arrayContaining(_.range(100))); 24 | }); 25 | }); 26 | 27 | describe("reversing", () => { 28 | it("should reverse one half of a two-card deck", () => { 29 | expect(shuffle(faceUpDeck([0, 1])).map((x) => x.reversed)) 30 | .toEqual([true, false]); 31 | }); 32 | 33 | it("should reverse roughly half of a thousand-card deck", () => { 34 | const shuffled = shuffle(faceUpDeck(_.range(1000))); 35 | const reversedCount = shuffled.filter((x) => x.reversed).length; 36 | expect(reversedCount).toBeLessThan(800); 37 | expect(reversedCount).toBeGreaterThan(200); 38 | }); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /frontend/src/cards/shuffle.tsx: -------------------------------------------------------------------------------- 1 | interface Oriented { 2 | reversed: boolean; 3 | } 4 | 5 | /** 6 | * Shuffles the given array similarly to how a physical deck is shuffled: by 7 | * splitting it in two, turning the bottom half upside-down, and then 8 | * interleaving the cards in chunks starting from the bottom half. 9 | */ 10 | export function shuffle(cards: T[], rng: { random(): number } = Math): T[] { 11 | if (cards.length === 1) { 12 | return cards; 13 | } 14 | 15 | // We'll cut the pile so that the left/top half has cut_point cards in it. 16 | const midpoint = Math.floor(cards.length / 2); 17 | const offset = Math.floor(cards.length / 5); 18 | const cutPoint = generateInteger( 19 | Math.max(midpoint - offset, 1), 20 | Math.min(midpoint + offset + 1, cards.length), 21 | rng, 22 | ); 23 | for (const card of cards.slice(cutPoint)) { 24 | card.reversed = !card.reversed; 25 | } 26 | const chunker = () => generateInteger(1, 4, rng); 27 | const leftChunks = chunk(cards.slice(0, cutPoint), chunker); 28 | const rightChunks = chunk(cards.slice(cutPoint), chunker); 29 | 30 | let shuffled: T[] = []; 31 | for (let i = 0; i < Math.max(leftChunks.length, rightChunks.length); i++) { 32 | if (i < rightChunks.length) { 33 | shuffled = shuffled.concat(rightChunks[i]); 34 | } 35 | if (i < leftChunks.length) { 36 | shuffled = shuffled.concat(leftChunks[i]); 37 | } 38 | } 39 | return shuffled; 40 | } 41 | 42 | /** 43 | * Generates an integer in the range [low, high). 44 | */ 45 | function generateInteger(low: number, high: number, rng: { random(): number }): number { 46 | return Math.floor(low + rng.random() * (high - low)); 47 | } 48 | 49 | /** 50 | * Splits the given array into chunks using the given function to determine the 51 | * size. The chunker must always return a number >= 1. 52 | */ 53 | function chunk(array: T[], chunker: () => number): T[][] { 54 | const chunks = []; 55 | let offset = 0; 56 | while (offset < array.length) { 57 | const chunkSize = chunker(); 58 | if (chunkSize < 1) { 59 | throw new Error(`Chunker gave invalid size ${chunkSize}`); 60 | } 61 | const end = offset + chunkSize; 62 | chunks.push(array.slice(offset, end)); 63 | offset = end; 64 | } 65 | return chunks; 66 | } 67 | -------------------------------------------------------------------------------- /frontend/src/components/About.md: -------------------------------------------------------------------------------- 1 | ## origin story 2 | 3 | the tarot of the lost purpose began on june 8, 2018, with me thinking: 4 | 5 | > you know, i like tarot cards, but shuffling is annoying. computers can 6 | > shuffle, but the problem is that they shuffle things *too well*. they're way 7 | > better at it than humans. but what if i made a program that shuffled badly? 8 | 9 | but also 10 | 11 | > man, i really want an excuse to fuck around with rust and react. 12 | 13 | sadly, the rust backend atrophied when i decided to do everything on the 14 | frontend, but i wound up using it for the asciifier, so hey. 15 | 16 | ## why do i have to make a deck? 17 | 18 | because Lost Purpose actually does store the state of your deck, including 19 | whether each card is reversed or not, and actually uses a vague simulation of 20 | how humans shuffle, where the RNG is a function of the query you type in. 21 | 22 | of course, it would also be possible to just use a real RNG and pick a card at 23 | random, but that isn't really fun, is it? 24 | 25 | ## is anything transmitted to the server? 26 | 27 | everything is done clientside, including the shuffling and the deck storage. i 28 | can't see your queries, the names of your decks, the state of your decks, 29 | anything. 30 | 31 | in the future i may implement some kind of data sync so you can share the state 32 | of your decks between computers, but that will be opt-in, and the queries will 33 | never leave your computer. 34 | 35 | ## what's in a name? 36 | 37 | originally it was called 'skarot', for 38 | '[skeumorphic](https://en.wikipedia.org/wiki/Skeuomorph) tarot', but i later 39 | decided i didn't like that name. then 40 | [@millenomi](https://twitter.com/@millenomi), who's the reason i'm interested in 41 | tarot in the first place¹ suggested 'lost purpose', both because: 42 | 43 | - a skeumorphism is something that's lost its purpose 44 | - tarot is something you turn to when you've lost your purpose 45 | 46 | ## do you actually believe in the occult? 47 | 48 | me, personally? nah. the shuffling algorithm is *entirely* deterministic (modulo 49 | a huge lag spike decreasing the number of crc32 stretches). but what i do 50 | believe is that the cards you draw can serve as an impulse to view your 51 | situation in a certain way, or act as symmetry-breaking for indecision. and i 52 | think they're just pretty to look at. 53 | 54 | after writing the above, i asked a fresh, shuffled silicon dawn deck whether the 55 | occult is real, and it gave me History reversed. history upright "...may be a 56 | reminder that the whole deck can just be an elaborate way of talking to 57 | yourself...", so i guess reversed means 'yes, i am real, and i will doom you for 58 | doubting me'? i'm not making this up because you wouldn't believe me if i did. 59 | 60 | ## contact 61 | 62 | if you want to get in contact with me, here are your options from best to worst: 63 | 64 | - [send me a message on Mastodon](https://cybre.space/@hierarchon) 65 | - [send me a message on Twitter](https://twitter.com/hierarchon) (public DMs are on) 66 | - [e-mail me](mailto:relativistic.policeman+tarot@gmail.com) 67 | 68 | --- 69 | 70 | ¹ and who is also very cute 71 | -------------------------------------------------------------------------------- /frontend/src/components/App.spec.tsx: -------------------------------------------------------------------------------- 1 | import { mount, shallow } from "enzyme"; 2 | import * as React from "react"; 3 | import { HashRouter } from "react-router-dom"; 4 | import App from "./App"; 5 | 6 | jest.mock("../cards/artFinderContext"); 7 | 8 | describe("smoke tests", () => { 9 | it("renders shallowly", () => { 10 | shallow(); 11 | }); 12 | 13 | it("renders deeply", () => { 14 | mount(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/src/components/App.tsx: -------------------------------------------------------------------------------- 1 | import history from "history"; 2 | import update from "immutability-helper"; 3 | import * as React from "react"; 4 | import ReactMarkdown from "react-markdown"; 5 | import ReactModal = require("react-modal"); 6 | import { withRouter } from "react-router"; 7 | import { Route } from "react-router-dom"; 8 | import * as ArtFinder from "../cards/artFinder"; 9 | import * as Cards from "../cards/cards"; 10 | import { LFSR } from "../cards/lfsr"; 11 | import { shuffle } from "../cards/shuffle"; 12 | import { BackupRestore } from "./BackupRestore"; 13 | import Deck from "./Deck"; 14 | import { DeckPreloader } from "./DeckPreloader"; 15 | import { DrawResult } from "./DrawResult"; 16 | import { Navbar } from "./Navbar"; 17 | import { NewDeckDialog } from "./NewDeckDialog"; 18 | 19 | import "../styles/app.scss"; 20 | const aboutMarkdown = require("./About.md"); 21 | const creditsMarkdown = require("./Credits.md"); 22 | 23 | type Props = { 24 | history: history.History; 25 | location: any; 26 | match: any; 27 | }; 28 | 29 | type State = { 30 | // This is null if and only if there are no decks. 31 | currentCard: Cards.OrientedCard | null; 32 | decks: ReadonlyArray; 33 | showNewDeckDialog: boolean; 34 | }; 35 | 36 | const decksStorageKey = "decks"; 37 | 38 | export const Home: React.SFC<{}> = (props) => { 39 | return ( 40 |
41 |

the Tarot of the Lost Purpose

42 |

an excessively-realistic tarot simulator

43 |
44 | ); 45 | }; 46 | 47 | class App extends React.Component { 48 | constructor(props: Props) { 49 | super(props); 50 | const savedDecks = localStorage.getItem(decksStorageKey); 51 | const decks = savedDecks ? JSON.parse(savedDecks) : []; 52 | this.state = { 53 | decks, 54 | currentCard: null, 55 | showNewDeckDialog: false, 56 | }; 57 | 58 | this.handleShowNewDeckDialog = this.handleShowNewDeckDialog.bind(this); 59 | this.handleCloseNewDeck = this.handleCloseNewDeck.bind(this); 60 | this.handleNewDeck = this.handleNewDeck.bind(this); 61 | this.handleSelectDeck = this.handleSelectDeck.bind(this); 62 | this.handleDeleteDeck = this.handleDeleteDeck.bind(this); 63 | this.handleDraw = this.handleDraw.bind(this); 64 | this.handleShuffle = this.handleShuffle.bind(this); 65 | this.handleRestore = this.handleRestore.bind(this); 66 | this.saveState = this.saveState.bind(this); 67 | 68 | // Needed since componentWillUnmount isn't called if the user is reloading the page. 69 | window.addEventListener("beforeunload", this.saveState); 70 | } 71 | 72 | public componentWillUnmount() { 73 | this.saveState(); 74 | window.removeEventListener("beforeunload", this.saveState); 75 | } 76 | 77 | public render() { 78 | const deckRoutes = this.state.decks.map((deck) => { 79 | const renderDeck = () => ( 80 | 81 | 87 | 88 |
89 | 90 |
91 |
92 | ); 93 | return ( 94 | 99 | ); 100 | }); 101 | return ( 102 |
103 | 108 | {deckRoutes} 109 | 110 | } 113 | /> 114 | ( 117 | 121 | )} 122 | /> 123 | } 126 | /> 127 | 128 | 135 | 136 | 137 |
138 | ); 139 | } 140 | 141 | private handleShowNewDeckDialog() { 142 | this.setState({ showNewDeckDialog: true }); 143 | } 144 | 145 | private handleCloseNewDeck() { 146 | this.setState({ showNewDeckDialog: false }); 147 | } 148 | 149 | private handleNewDeck(deck: Cards.Deck) { 150 | console.debug(`Creating new deck named ${deck.name}`); 151 | this.setState((state) => ({ 152 | decks: [...state.decks, deck], 153 | showNewDeckDialog: false, 154 | })); 155 | this.props.history.push(`/deck/${deck.id.substr(0, 8)}`); 156 | } 157 | 158 | private handleSelectDeck() { 159 | this.setState({ currentCard: null }); 160 | } 161 | 162 | private handleDeleteDeck(deck: Cards.Deck) { 163 | const index = this.state.decks.indexOf(deck); 164 | if (index === null) { 165 | console.error("Attempted to delete a deck at index null?"); 166 | return; 167 | } 168 | if (!confirm(`Are you sure you want to delete the deck "${deck.name}"? This cannot be undone.`)) { 169 | return; 170 | } 171 | 172 | console.debug(`Deleting deck ${index}`); 173 | this.setState((state) => 174 | update(state, { 175 | decks: { $splice: [[index, 1]] }, 176 | currentDeckIndex: { $set: null }, 177 | }), 178 | ); 179 | } 180 | 181 | private handleRestore(value: string) { 182 | let decks: Cards.Deck[] | undefined; 183 | try { 184 | decks = JSON.parse(value); 185 | } catch (err) { 186 | console.log(err); 187 | alert("Could not restore backup."); 188 | return; 189 | } 190 | this.setState((state) => 191 | update(state, { 192 | decks: { $set: decks! }, 193 | })); 194 | alert("Restore successful."); 195 | } 196 | 197 | private saveState() { 198 | console.log("Saving state to localStorage"); 199 | window.localStorage.setItem(decksStorageKey, JSON.stringify(this.state.decks)); 200 | } 201 | 202 | private handleDraw(deck: Cards.Deck) { 203 | this.setState((state) => { 204 | const index = this.state.decks.indexOf(deck)!; 205 | const topCard = deck.cards[0]; 206 | console.info("Drew", topCard); 207 | const currentCard = topCard; 208 | const numCards = deck.cards.length; 209 | let newDecks = update(state.decks, 210 | { [index]: { cards: { $splice: [[0, 1]] } } }); 211 | newDecks = update(newDecks, 212 | { [index]: { cards: { $push: [topCard] } } }); 213 | return { decks: newDecks, currentCard }; 214 | }); 215 | } 216 | 217 | private handleShuffle(deck: Cards.Deck, fingerprint: number) { 218 | const lfsr = new LFSR(fingerprint); 219 | console.debug("Shuffling deck"); 220 | this.setState((state) => { 221 | const index = this.state.decks.indexOf(deck)!; 222 | const repeatedShuffle = (cards: Cards.OrientedCard[]) => { 223 | // Ten times is enough to get some actual mixing. 224 | for (let i = 0; i < 10; i++) { 225 | cards = shuffle(cards, lfsr); 226 | } 227 | return cards; 228 | }; 229 | 230 | return update(state, 231 | { decks: { [index]: { cards: repeatedShuffle } } }); 232 | }); 233 | } 234 | } 235 | 236 | export default withRouter(App); 237 | -------------------------------------------------------------------------------- /frontend/src/components/BackupRestore.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import "../styles/backup-restore.scss"; 4 | 5 | type Props = { 6 | value: string; 7 | onRestore: (value: string) => void; 8 | }; 9 | 10 | type State = { 11 | restoreValue: string; 12 | }; 13 | 14 | export class BackupRestore extends React.Component { 15 | constructor(props: Props) { 16 | super(props); 17 | this.state = { restoreValue: "" }; 18 | this.handleChange = this.handleChange.bind(this); 19 | } 20 | 21 | public render() { 22 | return ( 23 |
24 |
25 |

Backup

26 |

27 | To backup the state of your decks, copy the below text and store it somewhere safe. 28 | This includes everything about your decks, including their names, the order of the cards, 29 | and so on. 30 |

31 |