Puzzle Massive Overview

Massively Multiplayer Online Jigsaw Puzzles web application.

Currently in active development. A static version has been published at https://puzzle.massive.xyz/ and is playable. Note that the static version is single player and persists puzzle piece positions on the browser side only. Snapshots of puzzle piece positions can be made and downloaded which allows some collaboration between players for a puzzle.

Goals


Development and Source Code

Puzzle Massive is a hobby project that Jake Hickenlooper is doing in his spare time. This is version 3, which is a rewrite of Version 2. Version 1 and Version 2 of Puzzle Massive were done as open source projects with a AGPLv3 license. These have now been archived and no further development or maintenance will be done on them.

Project source code for version 3 is hosted on sourcehut: puzzle-massive. However, access to the project source code is not publicly available. Humans can ask Jake for a downloadable archive file of the source code. Please include your reason why you'd like to access it. Not all requests will be fulfilled. I may be open to interested individuals that want to collaborate with me on this project.

Links to stay up to date:

Overview

The technology stack is:

Files and Directories

A tree of the files are shown below to help get a sense of the current Puzzle Massive code base. I'm not ready to allow anyone access to this for a number of reasons. I also don't approve of web scrapers that are frequently used to train LLMs without the consent of the authors. For those curious about my choices of software or how I implemented something; please use the below file names as a guide when asking to see something.

Note that files that were generated from the cookiecutters project may be excluded from the list.

119 directories, 643 files
.
├── LICENSE
├── pm-files.txt
├── README.md
├── README.md-1.svg
├── vendor-manifest.toml
│    { Used by vendor-grab tool to download dependencies
├── docs
│   └── development.md
├── piecemaker
│    ⎧ cookiecutters chillbox-site
│    ⎨ Mostly wrapping the piecemaker CLI tool as an API that puzzle-massive can call
│    ⎩ internally.
│   ├── LICENSE
│   ├── local.site.toml
│   ├── Makefile
│   ├── README.md
│   ├── VERSION
│   ├── apiv0
│   │    { cookiecutters python-service
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── src
│   │       └── piecemaker_apiv0
│   │           ├── app.py
│   │           ├── env.py
│   │           ├── __init__.py
│   │           └── sql
│   │               ├── schema.sql
│   │               └── select_schema_version.sql
│   ├── nginx
│   │   ├── Containerfile
│   │   ├── nginx.conf
│   │   ├── piecemaker.ssl_cert.include
│   │   ├── root
│   │   │   ├── error.html
│   │   │   ├── favicon.ico
│   │   │   ├── forbidden.html
│   │   │   ├── humans.txt
│   │   │   ├── maintenance.html
│   │   │   ├── notfound.html
│   │   │   ├── not-supported.html
│   │   │   └── robots.txt
│   │   └── templates
│   │       └── piecemaker.nginx.conf.template
│   └── runner
│        { cookiecutters python-worker
│       ├── Containerfile
│       ├── LICENSE
│       ├── Makefile
│       ├── pyproject.toml
│       ├── README.md
│       ├── requirements.txt
│       └── src
│           └── piecemaker_runner
│               ├── env.py
│               ├── __init__.py
│               ├── main.py
│               ├── script.py
│               └── wrapper.py
├── puzzlefreeze
│    ⎧ cookiecutters chillbox-site
│    ⎨ A static copy of the puzzle-massive site while it is under active development.
│    ⎩ No running services, just NGINX serving static files.
│   ├── LICENSE
│   ├── local.site.toml
│   ├── Makefile
│   ├── pz-view.importmap.json -> ../puzzle-massive/polar-bear/documents/pz-view.importmap.json
│   ├── README.md
│   ├── user-settings-localstorage.js -> ../puzzle-massive/polar-bear/documents/user-settings-localstorage.js
│   ├── VERSION
│   ├── freeze
│   │    { A custom script to build the static site files by using wget.
│   │   ├── Containerfile
│   │   ├── httpd.conf
│   │   ├── Makefile
│   │   ├── README.md
│   │   └── src
│   │       └── page_urls.txt
│   └── nginx
│       ├── Containerfile
│       ├── nginx.conf
│       ├── puzzlefreeze.ssl_cert.include
│       ├── root
│       │   ├── error.html
│       │   ├── favicon.ico
│       │   ├── forbidden.html
│       │   ├── humans.txt
│       │   ├── maintenance.html
│       │   ├── notfound.html
│       │   ├── partial-dingbat.html
│       │   ├── puzzlers.html
│       │   ├── robot-archive.html
│       │   ├── robots.txt
│       │   └── seal.html
│       └── templates
│           └── puzzlefreeze.nginx.conf.template
├── puzzle-massive
│    ⎧ cookiecutters chillbox-site
│    ⎩ The dynamic site.
│   ├── add-crontab-entries.sh
│   ├── Containerfile
│   ├── LICENSE
│   ├── local.site.toml
│   ├── Makefile
│   ├── nginx-log-prepare-up
│   ├── nginx-log-run
│   ├── nginx-run
│   ├── README.md
│   ├── redict-run.template.sh
│   ├── s6-overlay-exp.mk
│   ├── s6-rc-setup-service.sh
│   ├── scrub-solid-color-image.sh
│   ├── starting-data.toml
│   ├── store-packages-notes.md
│   ├── todo.txt
│   ├── VERSION
│   ├── account
│   │    { cookiecutters python-service
│   │   ├── Containerfile
│   │   ├── Makefile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── src
│   │       └── puzzle_massive_account
│   │           ├── app.py
│   │           ├── authz.py
│   │           ├── brown_paper_packages_tied_up_with_strings.py
│   │           │    { Some of my favorite things.
│   │           ├── env.py
│   │           ├── errors.py
│   │           ├── __init__.py
│   │           ├── logging.py
│   │           ├── package_jobs.py
│   │           ├── partials.py
│   │           ├── public_claim_codes.py
│   │           ├── puzzle.py
│   │           ├── token_permissions.py
│   │           ├── user.py
│   │           ├── sql
│   │           │   ├── action.py
│   │           │   ├── check.py
│   │           │   ├── __init__.py
│   │           │   ├── insert_brown_paper_packages_tied_up_with_strings_for_owner.sql
│   │           │   ├── insert_brown_paper_packages_tied_up_with_strings_for_user_and_owner.sql
│   │           │   ├── insert_brown_paper_packages_tied_up_with_strings_for_user.sql
│   │           │   ├── insert_brown_paper_packages_tied_up_with_strings.sql
│   │           │   ├── insert_claim_codes.sql
│   │           │   ├── insert_link_claim_codes_tokens.sql
│   │           │   ├── insert_link_user_claim_codes.sql
│   │           │   ├── insert_tokens.sql
│   │           │   ├── insert_tokens_with_owner_and_permission.sql
│   │           │   ├── insert_tokens_with_owner.sql
│   │           │   ├── schema.sql
│   │           │   ├── select_active_claim_codes_for_user.sql
│   │           │   ├── select_all_from_token_types.sql
│   │           │   ├── select_all_user_ids_with_limit.sql
│   │           │   ├── select_brown_paper_packages_tied_up_with_strings.sql
│   │           │   ├── select_claim_code_for_user.sql
│   │           │   ├── select_claim_codes_for_user.sql
│   │           │   ├── select_claim_code.sql
│   │           │   ├── select_count_tokens_for_user_that_are_available_and_not_expired.sql
│   │           │   ├── select_count_tokens_that_are_available_and_not_expired.sql
│   │           │   ├── select_packages_for_user.sql
│   │           │   ├── select_schema_version.sql
│   │           │   ├── select_tokens_active_permissions_for_bearer.sql
│   │           │   ├── select_tokens_active_permissions_for_owner.sql
│   │           │   ├── select_tokens_for_claim_code.sql
│   │           │   ├── select_tokens_that_user_is_bearer_of.sql
│   │           │   ├── select_tokens_with_status_and_type_for_user.sql
│   │           │   ├── select_tokens_with_status_and_type_for_user_that_are_not_claimed.sql
│   │           │   ├── select_tokens_with_status_and_type.sql
│   │           │   ├── select_tokens_with_status_and_type_that_are_not_claimed.sql
│   │           │   ├── select_user_settings_privacy.sql
│   │           │   ├── select_user.sql
│   │           │   ├── update_access_token_set_bearer_to_user.sql
│   │           │   ├── update_brown_paper_package_redeemed.sql
│   │           │   ├── update_brown_paper_packages_status.sql
│   │           │   ├── update_brown_paper_packages_status_when_redeemable_limit.sql
│   │           │   ├── update_claim_codes_status.sql
│   │           │   ├── update_guest_tokens_set_permission_and_bearer.sql
│   │           │   ├── update_invite_token_set_bearer_to_user.sql
│   │           │   ├── update_tokens_from_claim_code_set_bearer_to_user.sql
│   │           │   ├── update_user_guest_token_count_and_interval.sql
│   │           │   ├── upsert_package_jobs.sql
│   │           │   ├── upsert_token_permissions.sql
│   │           │   ├── upsert_user_id.sql
│   │           │   ├── upsert_user_settings_privacy.sql
│   │           │   └── upsert_users.sql
│   │           └── templates
│   │               ├── 403-error.html.jinja2
│   │               ├── app-dependency-error.html.jinja2
│   │               ├── base.html.jinja2
│   │               ├── brown-paper-packages-tied-up-with-strings-claim.html
│   │               ├── brown-paper-packages-tied-up-with-strings-landing.html
│   │               ├── brown-paper-packages-tied-up-with-strings-listing.html.jinja2
│   │               ├── brown-paper-packages-tied-up-with-strings-package-contents-partial.html.jinja2
│   │               ├── public-claim-code.html.jinja2
│   │               ├── public-claim-code-post-message.html.jinja2
│   │               ├── settings-privacy.html.jinja2
│   │               ├── user-claim-code-error.html.jinja2
│   │               ├── user-claim-code.html.jinja2
│   │               ├── user-claim-codes.html.jinja2
│   │               ├── user-header-partial.html.jinja2
│   │               ├── user-invite-package-response.html.jinja2
│   │               ├── user-invites.html.jinja2
│   │               ├── user-landing.html.jinja2
│   │               └── user-settings-localstorage.js
│   ├── cedar-block
│   │    { cookiecutters python-service
│   │   ├── Containerfile
│   │   ├── Makefile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── src
│   │       └── puzzle_massive_cedar_block
│   │           ├── app.py
│   │           ├── cedar_policy.py
│   │           ├── env.py
│   │           ├── __init__.py
│   │           └── logging.py
│   ├── cedar-tree
│   │    { cookiecutters immutable-make
│   │   ├── _01-process-src-files.mk
│   │   ├── Containerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   └── src
│   │       ├── account.entities.cedar.toml
│   │       ├── account.policies.cedar
│   │       ├── account_test.py
│   │       ├── admin.policies.cedar
│   │       ├── admin_test.py
│   │       ├── convert-cedar-toml-to-json.py
│   │       ├── entities_and_policies_test.py
│   │       ├── format-cedar-policy.py
│   │       ├── __init__.py
│   │       ├── puzzle.entities.cedar.toml
│   │       ├── puzzle-porte.policies.cedar
│   │       ├── puzzles.entities.cedar.toml
│   │       ├── puzzles.policies.cedar
│   │       ├── puzzles_test.py
│   │       ├── puzzle_test.py
│   │       ├── studio.entities.cedar.toml
│   │       ├── studio.policies.cedar
│   │       ├── studio_test.py
│   │       └── utils.py
│   ├── doer
│   │    { cookiecutters python-worker
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── src
│   │       └── puzzle_massive_doer
│   │           ├── env.py
│   │           ├── __init__.py
│   │           ├── logging.py
│   │           ├── main.py
│   │           ├── script.py
│   │           └── jobs
│   │               ├── http_request.py
│   │               └── __init__.py
│   ├── media
│   │    ⎧ cookiecutters immutable-make
│   │    ⎨ The graphics are not included in the git history and so they also don't show
│   │    ⎪ in the tree output here. All image files are included by running the
│   │    ⎩ vendor-grab command.
│   │   ├── _01-process-src-files.mk
│   │   ├── _02-convert-scanned-typed-doc.mk
│   │   ├── _03-snowstorm-media.mk
│   │   ├── _04-handwritten-media.mk
│   │   ├── Containerfile
│   │   ├── Makefile
│   │   ├── README.md
│   │   └── src
│   │       ├── file1.txt
│   │       └── file2.txt
│   ├── mini-map
│   │    { cookiecutters client-side-public
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── vendor-manifest.toml
│   │   │    { Used by vendor-grab tool to download dependencies
│   │   ├── src
│   │   │   ├── index.html
│   │   │   ├── index.js
│   │   │   ├── mini-map.css
│   │   │   └── mini-map.js
│   │   └── vendor
│   │       └── normalize.css
│   │           └── LICENSE.md
│   ├── nginx
│   │   ├── Containerfile
│   │   ├── nginx.conf
│   │   ├── puzzle-massive.ssl_cert.include
│   │   ├── root
│   │   │   ├── error.html
│   │   │   ├── favicon.ico
│   │   │   ├── forbidden.html
│   │   │   ├── humans.txt
│   │   │   ├── maintenance.html
│   │   │   ├── notfound.html
│   │   │   ├── puzzlers.html
│   │   │   ├── robot-archive.html
│   │   │   ├── robots.txt
│   │   │   └── legal
│   │   │       ├── privacy-policy.html
│   │   │       └── terms-of-service.html
│   │   └── templates
│   │       └── puzzle-massive.nginx.conf.template
│   ├── polar-bear
│   │    { cookiecutters chill-service
│   │   ├── chill-data-puzzle-authors.yaml
│   │   ├── chill-data-weekly.yaml
│   │   ├── chill-data.yaml
│   │   ├── chill-dump.sql
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── requirements.in
│   │   ├── requirements.txt
│   │   ├── site.cfg
│   │   ├── documents
│   │   │   ├── archive.md
│   │   │   ├── cookie-consent.md
│   │   │   ├── cookie-customize.md
│   │   │   ├── pz-view.importmap.json
│   │   │   └── user-settings-localstorage.js
│   │   ├── queries
│   │   │   ├── select-article.sql
│   │   │   ├── select-datetime-now-for-rss-date.sql
│   │   │   ├── select-error.sql
│   │   │   ├── select-images-for-moderation.sql
│   │   │   ├── select-latest-weekly-post-pub-date.sql
│   │   │   ├── select-latest-weekly-post.sql
│   │   │   ├── select-moderation-image-detail.sql
│   │   │   ├── select-puzzles-for-player.sql
│   │   │   ├── select-puzzle_share_maneuvers_add_players_as_guests_response.sql
│   │   │   ├── select-pz_info.sql
│   │   │   ├── select-pz_name.sql
│   │   │   ├── select-recent-weekly-posts.sql
│   │   │   ├── select-seal.sql
│   │   │   ├── select-studio-puzzle-admin-landing.sql
│   │   │   ├── select-studio-puzzle-landing.sql
│   │   │   ├── select-template-partial-name.sql
│   │   │   ├── select-template-snip-name.sql
│   │   │   ├── select-weekly-post-by-date.sql
│   │   │   ├── select-weekly-post-by-latest.sql
│   │   │   └── weekly.sql
│   │   └── templates
│   │       ├── aboutpage.html.jinja2
│   │       ├── archive.html.jinja2
│   │       ├── color-scheme-settings.html.jinja2
│   │       ├── cookie-consent-dialog.html.jinja2
│   │       ├── copyright.html.jinja2
│   │       ├── head_style.html.jinja2
│   │       ├── homepage.html
│   │       ├── htmx-head-script.html.jinja2
│   │       ├── importmap.html.jinja2
│   │       ├── intro-dialog.html.jinja2
│   │       ├── menu.html.jinja2
│   │       ├── moderation.html.jinja2
│   │       ├── moderation-images-detail.html.jinja2
│   │       ├── moderation-images-landing.html.jinja2
│   │       ├── page-footer.html.jinja2
│   │       ├── page-header.html.jinja2
│   │       ├── page.html.jinja2
│   │       ├── page-links.html.jinja2
│   │       ├── partial-dingbat.html.jinja2
│   │       ├── partial.html.jinja2
│   │       ├── piecemovementspage.html.jinja2
│   │       ├── puzzle-author.html.jinja2
│   │       ├── puzzle-info.html.jinja2
│   │       ├── puzzle-share.html.jinja2
│   │       ├── puzzle-share-maneuvers-add-players-as-guests-response.html.jinja2
│   │       ├── puzzles.html.jinja2
│   │       ├── puzzles-landing.html.jinja2
│   │       ├── puzzle-snapped.html.jinja2
│   │       ├── pz-error.html.jinja2
│   │       ├── pz-status.html.jinja2
│   │       ├── pz-view.html.jinja2
│   │       ├── rss.jinja2
│   │       ├── seal.html.jinja2
│   │       ├── site.html.jinja2
│   │       ├── snippet-content-space-close.html.jinja2
│   │       ├── sniptext-about.html.jinja2
│   │       ├── sniptext-loading.html.jinja2
│   │       ├── sniptext-login.html.jinja2
│   │       ├── sniptext-privacy-policy.html.jinja2
│   │       ├── sniptext-puzzle-massive.html.jinja2
│   │       ├── sniptext-terms-of-service.html.jinja2
│   │       ├── sniptext-weekly.html.jinja2
│   │       ├── snowstorm_js_script.html.jinja2
│   │       ├── studio-puzzle-admin-landing-view.html.jinja2
│   │       ├── studio-puzzle-landing-view.html.jinja2
│   │       ├── template-snip.html.jinja2
│   │       ├── typedpage.html.jinja2
│   │       ├── user_data_settings.html.jinja2
│   │       ├── user_settings_localstorage_js_script.html.jinja2
│   │       ├── web-component-puzzle-snapped-message-template.html.jinja2
│   │       ├── web-component-snap-template.html.jinja2
│   │       ├── weekly.html.jinja2
│   │       └── weekly-latest.html.jinja2
│   ├── porte
│   │    { cookiecutters python-service
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── src
│   │       └── puzzle_massive_porte
│   │           ├── account.py
│   │           ├── app_logging.py
│   │           ├── app.py
│   │           ├── archive.py
│   │           ├── authz.py
│   │           ├── env.py
│   │           ├── feed.py
│   │           ├── __init__.py
│   │           ├── moderation.py
│   │           ├── oauth2.py
│   │           ├── page.py
│   │           ├── partial.py
│   │           ├── puzzles.py
│   │           ├── seal.py
│   │           ├── snap.py
│   │           ├── snapshots.py
│   │           ├── studio.py
│   │           ├── tools.py
│   │           ├── users.py
│   │           ├── sql
│   │           │   ├── action.py
│   │           │   ├── check.py
│   │           │   ├── count_total_pz_names.sql
│   │           │   ├── __init__.py
│   │           │   ├── insert_name_to_pz_names.sql
│   │           │   ├── insert_name_to_pz_names_with_owner.sql
│   │           │   ├── insert_puzzle_snapshot.sql
│   │           │   ├── insert_pznames_puzzletypes_link.sql
│   │           │   ├── insert_snap_offset.sql
│   │           │   ├── schema.sql
│   │           │   ├── select_all_puzzle_snapshots_for_owner.sql
│   │           │   ├── select_puzzle_by_pzname.sql
│   │           │   ├── select_puzzle_offset_by_snap.sql
│   │           │   ├── select_puzzle_offset_list_by_pzname.sql
│   │           │   ├── select_puzzles_for_anyone.sql
│   │           │   ├── select_puzzles_for_guest.sql
│   │           │   ├── select_puzzles_for_members.sql
│   │           │   ├── select_puzzles_for_owner.sql
│   │           │   ├── select_puzzle_snap_by_pzname.sql
│   │           │   ├── select_puzzle_snap_key_by_pzname.sql
│   │           │   ├── select_puzzle_snapshots_for_name.sql
│   │           │   ├── select_puzzletypes_with_name.sql
│   │           │   ├── select_puzzle_with_puzzle_type_for_anyone.sql
│   │           │   ├── select_puzzle_with_pzname.sql
│   │           │   ├── select_schema_version.sql
│   │           │   ├── select_user_by_emailhash.sql
│   │           │   ├── select_user_by_name.sql
│   │           │   ├── select_user_by_user.sql
│   │           │   ├── upsert_puzzletypes_name.sql
│   │           │   ├── upsert_users.sql
│   │           │   └── upsert_users_with_name_and_email_hash.sql
│   │           └── templates
│   │               └── puzzle-not-ripe-yet.html.jinja2
│   │                    ⎧ It's not ripe yet... This template partial is shown when a puzzle is still
│   │                    ⎨ being created. HTMX is used to do some simple polling that updates the
│   │                    ⎩ content with the latest status.
│   ├── puzzle-canvas
│   │    { cookiecutters client-side-public
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── serve.py
│   │   ├── vendor-manifest.toml
│   │   │    { Used by vendor-grab tool to download dependencies
│   │   ├── src
│   │   │   ├── deno.json
│   │   │   ├── flat-view.js
│   │   │   ├── index.html
│   │   │   ├── index.js
│   │   │   ├── puzzle-canvas.css
│   │   │   ├── puzzle-canvas.js
│   │   │   ├── test.html
│   │   │   ├── TinyGesture.js
│   │   │   └── utils.js
│   │   └── vendor
│   │       ├── msgpack
│   │       │   ├── CachedKeyDecoder.mjs
│   │       │   ├── context.mjs
│   │       │   ├── decodeAsync.mjs
│   │       │   ├── DecodeError.mjs
│   │       │   ├── decode.mjs
│   │       │   ├── Decoder.mjs
│   │       │   ├── encode.mjs
│   │       │   ├── Encoder.mjs
│   │       │   ├── ExtData.mjs
│   │       │   ├── ExtensionCodec.mjs
│   │       │   ├── index.mjs
│   │       │   ├── LICENSE
│   │       │   ├── msgpack.js
│   │       │   ├── timestamp.mjs
│   │       │   └── utils
│   │       │       ├── int.mjs
│   │       │       ├── prettyByte.mjs
│   │       │       ├── stream.mjs
│   │       │       ├── typedArrays.mjs
│   │       │       └── utf8.mjs
│   │       └── tinygesture
│   │           ├── LICENSE
│   │           └── TinyGesture.js
│   ├── ressources-de-puzzle
│   │    { cookiecutters python-service
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── pyproject.toml
│   │   ├── README.md
│   │   ├── requirements.txt
│   │   └── src
│   │       └── puzzle_massive_ressources_de_puzzle
│   │           ├── app.py
│   │           ├── env.py
│   │           ├── imageanalysis.py
│   │           ├── image.py
│   │           ├── __init__.py
│   │           ├── loader.py
│   │           ├── logging.py
│   │           ├── pz_name.py
│   │           ├── sql
│   │           │   ├── check.py
│   │           │   ├── delete_puzzle_job_where_expired.sql
│   │           │   ├── __init__.py
│   │           │   ├── insert_attribution.sql
│   │           │   ├── insert_attribution_without_license.sql
│   │           │   ├── insert_image_analysis.sql
│   │           │   ├── insert_image.sql
│   │           │   ├── insert_license.sql
│   │           │   ├── insert_link_piecemaker_artifact_image.sql
│   │           │   ├── insert_piecemaker_artifact.sql
│   │           │   ├── insert_puzzle_job.sql
│   │           │   ├── insert_puzzle.sql
│   │           │   ├── schema.sql
│   │           │   ├── select_adjacent_by_pz_name.sql
│   │           │   ├── select_cache_key_by_name.sql
│   │           │   ├── select_image_by_id.sql
│   │           │   ├── select_image_cache_id_by_id.sql
│   │           │   ├── select_image_detail_by_id.sql
│   │           │   ├── select_image_ids_for_moderation.sql
│   │           │   ├── select_image_moderation_by_id.sql
│   │           │   ├── select_license_by_name.sql
│   │           │   ├── select_phash_for_all_image.sql
│   │           │   ├── select_public_puzzle_piece_props_by_uuid.sql
│   │           │   ├── select_puzzle_by_name.sql
│   │           │   ├── select_puzzle_data_by_name.sql
│   │           │   ├── select_puzzle_job_by_name.sql
│   │           │   ├── select_puzzle_job_where_expired.sql
│   │           │   ├── select_puzzle_piece_origins_by_pz_name.sql
│   │           │   ├── select_schema_version.sql
│   │           │   ├── select_submitters.sql
│   │           │   ├── update_puzzle_job_by_name.sql
│   │           │   ├── update_puzzle_job_status_by_name.sql
│   │           │   └── upsert_submitters.sql
│   │           └── templates
│   │               ├── mini-map.html.jinja2
│   │               ├── puzzle-canvas.html.jinja2
│   │               ├── puzzle-image-detail.html.jinja2
│   │               ├── puzzle-image-moderation.html.jinja2
│   │               ├── puzzle-preload.html.jinja2
│   │               ├── puzzle-variants.html.jinja2
│   │               └── snapshots.html.jinja2
│   ├── snap
│   │    { cookiecutters client-side-public
│   │   ├── Containerfile
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── vendor-manifest.toml
│   │   │    { Used by vendor-grab tool to download dependencies
│   │   ├── src
│   │   │   ├── database.js
│   │   │   ├── deno.json
│   │   │   ├── flatbush.js
│   │   │   ├── immer.js
│   │   │   ├── index.html
│   │   │   ├── index.js
│   │   │   ├── joined-piece-groups.js
│   │   │   ├── joined-piece-groups.test.js
│   │   │   ├── piece-proximity.js
│   │   │   ├── pieces.js
│   │   │   ├── service.js
│   │   │   ├── shared-utils.js
│   │   │   ├── snap.component.js
│   │   │   ├── snap.css
│   │   │   ├── snap.js
│   │   │   ├── snapshots.component.js
│   │   │   ├── snapshots.css
│   │   │   ├── utils.js
│   │   │   └── service-workers
│   │   │       ├── build-snap.js
│   │   │       ├── example-puzzle.js
│   │   │       ├── index.sw.js
│   │   │       ├── publish.intercept.js
│   │   │       ├── snapshots.intercept.js
│   │   │       └── snap.sw.js
│   │   └── vendor
│   │       ├── flatbush
│   │       │   ├── flatbush.js
│   │       │   └── LICENSE
│   │       ├── idb
│   │       │   ├── idb.js
│   │       │   └── LICENSE
│   │       ├── immer
│   │       │   ├── immer.js
│   │       │   └── LICENSE
│   │       ├── lit-html
│   │       │   ├── LICENSE
│   │       │   └── lit-html.min.js
│   │       └── msgpack
│   │           ├── CachedKeyDecoder.mjs
│   │           ├── context.mjs
│   │           ├── decodeAsync.mjs
│   │           ├── DecodeError.mjs
│   │           ├── decode.mjs
│   │           ├── Decoder.mjs
│   │           ├── encode.mjs
│   │           ├── Encoder.mjs
│   │           ├── ExtData.mjs
│   │           ├── ExtensionCodec.mjs
│   │           ├── index.mjs
│   │           ├── LICENSE
│   │           ├── msgpack.js
│   │           ├── timestamp.mjs
│   │           └── utils
│   │               ├── int.mjs
│   │               ├── prettyByte.mjs
│   │               ├── stream.mjs
│   │               ├── typedArrays.mjs
│   │               └── utf8.mjs
│   └── snowstorm
│        { cookiecutters client-side-public
│       ├── Containerfile
│       ├── LICENSE
│       ├── Makefile
│       ├── README.md
│       ├── vendor-manifest.toml
│       │    { Used by vendor-grab tool to download dependencies
│       ├── src
│       │   ├── 0-generic-reset.css
│       │   ├── 2-media.css
│       │   ├── 2-plain.css
│       │   ├── 2-pure.css
│       │   ├── 4-arctic.css
│       │   ├── 5-utils.css
│       │   ├── 6-settings.css
│       │   ├── account.html
│       │   ├── deno.json
│       │   ├── details-open.js
│       │   ├── draggable.js
│       │   ├── index.html
│       │   ├── index.js
│       │   ├── intro-dialog.html
│       │   ├── page.html
│       │   ├── page-legal.html
│       │   ├── polarcat.js
│       │   ├── puzzle.html
│       │   ├── puzzle-info-dialog.html
│       │   ├── puzzle-share-dialog.html
│       │   ├── qr-code.js
│       │   ├── README.md
│       │   ├── seal.html
│       │   ├── snowstorm.css
│       │   ├── snowstorm.js
│       │   ├── 1-elements
│       │   │   ├── elements.css
│       │   │   ├── pm-mini-map.css
│       │   │   └── qr-code.css
│       │   ├── 2-check-mark
│       │   │   └── check-mark.css
│       │   ├── 2-tabs
│       │   │   ├── tabs.css
│       │   │   └── tabs.js
│       │   ├── 3-account
│       │   │   ├── account.css
│       │   │   └── account.js
│       │   ├── 3-background
│       │   │   └── background.css
│       │   ├── 3-base
│       │   │   └── base.css
│       │   ├── 3-color-scheme-control
│       │   │   └── color-scheme-control.css
│       │   ├── 3-content-space
│       │   │   └── content-space.css
│       │   ├── 3-cookie-consent-customize-dialog
│       │   │   └── cookie-consent-customize-dialog.js
│       │   ├── 3-cookie-consent-dialog
│       │   │   ├── cookie-consent-dialog.css
│       │   │   └── cookie-consent-dialog.js
│       │   ├── 3-dialog
│       │   │   └── dialog.js
│       │   ├── 3-htmx
│       │   │   ├── htmx.js
│       │   │   └── response-handling.js
│       │   ├── 3-icon
│       │   │   └── icon.css
│       │   ├── 3-mark
│       │   │   └── mark.css
│       │   ├── 3-menu
│       │   │   ├── menu.css
│       │   │   └── menu.js
│       │   ├── 3-package-listing
│       │   │   └── package-listing.css
│       │   ├── 3-page
│       │   │   └── page.css
│       │   ├── 3-puzzle
│       │   │   ├── puzzle.css
│       │   │   └── puzzle.js
│       │   ├── 3-puzzle-image-detail
│       │   │   └── puzzle-image-detail.css
│       │   ├── 3-puzzle-info
│       │   │   └── puzzle-info.css
│       │   ├── 3-puzzle-massive-intro
│       │   │   ├── puzzle-massive-intro.css
│       │   │   └── puzzle-massive-intro.js
│       │   ├── 3-puzzles
│       │   │   └── puzzles.css
│       │   ├── 3-puzzle-snapped-message
│       │   │   ├── puzzle-snapped-message.component.js
│       │   │   ├── puzzle-snapped-message.css
│       │   │   └── puzzle-snapped-message.js
│       │   ├── 3-seal
│       │   │   └── seal.css
│       │   ├── 3-share
│       │   │   └── share.css
│       │   ├── 3-snapshots
│       │   │   ├── snapshots.css
│       │   │   └── snapshots.js
│       │   ├── 3-squid-beach
│       │   │   └── squid-beach.css
│       │   ├── 3-studio
│       │   │   └── studio.css
│       │   ├── 3-user-invites
│       │   │   └── user-invites.css
│       │   └── 3-user-landing
│       │       └── user-landing.css
│       └── vendor
│           ├── htmx
│           │   ├── htmx.min.js
│           │   └── LICENSE
│           ├── idiomorph
│           │   ├── idiomorph-ext.min.js
│           │   └── LICENSE
│           ├── lit-html
│           │   └── lit-html.min.js -> ../../../snap/vendor/lit-html/lit-html.min.js
│           ├── main.css
│           │   ├── _helpers.css
│           │   └── LICENSE.txt
│           ├── normalize.css
│           │   ├── LICENSE.md
│           │   └── normalize.css
│           ├── noto-emoji
│           │   ├── LICENSE
│           │   └── noto-emoji-emoji-700-normal.woff2
│           ├── old-timey-mono-font
│           │   ├── LICENSE.md
│           │   └── OldTimeyMono.ttf
│           ├── purecss
│           │   ├── LICENSE
│           │   └── tables.css
│           ├── qr-code
│           │   ├── LICENSE
│           │   └── qr-code.js
│           ├── qrjs
│           │   └── qr.js
│           └── suitcss-utils-text
│               ├── LICENSE.md
│               └── text.css
└── scripts
    ├── doit.sh
    ├── shareable-archive.sh
    ├── start.sh
    ├── stop.sh
    └── weekly.sh

119 directories, 643 files

Software and Services

Listing of various software and services that Puzzle Massive is currently using. This is to allow a glimpse of the internals of a web application like this and crediting other projects.

Jigsaw Puzzle Related

Backend (Server Side)

Frontend (Browser Side)

Infrastructure

Development

Services

History