kryten-webqueue 0.38.0__tar.gz → 0.38.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/CHANGELOG.md +22 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/PKG-INFO +1 -1
- kryten_webqueue-0.38.2/docs/SPEC-Visual-UX-Sprint-August-2026.md +714 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_catalog.py +36 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/mediacms.py +37 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_catalog.py +54 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/css/main.css +129 -19
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/js/main.js +28 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/auth/login.html +47 -5
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/base.html +2 -2
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/catalog/browse.html +1 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/catalog/item_detail.html +2 -1
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/queue/index.html +4 -4
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/race.html +25 -3
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/pyproject.toml +1 -1
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/scripts/patch_mediacms_bulk_facets.py +9 -9
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/scripts/patch_mediacms_tags.py +2 -4
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_classify.py +0 -1
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_title_normalization.py +0 -1
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/.github/workflows/gitleaks.yml +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/.gitignore +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/.gitleaks.toml +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/.pre-commit-config.yaml +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/AGENT-WORKFLOW-GUIDE.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/AGENTS.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/README.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/config.example.json +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/Kryten-Economy Service Quality Survey Report at v0.13.0.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/Kryten-Webqueue Service Quality Survey Report at v0.27.1.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/Log for incorrect promo insertion problem.txt +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/PLAN_PRESENCE_AND_PROMOS.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/SPEC_ADMIN_ITEM_EDITOR.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/SPEC_CATALOG_ENRICHMENT_PIPELINE.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/SPEC_EMOTE_REHOST.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/SPEC_JOBS_AND_BROWSE.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/docs/UX_POLISH_PLAN.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/app.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_connection.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_enrichment.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_feedback.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_people.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_playlists.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_queue.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/db/_watchlist.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/classify.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/normalise.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/pipeline.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/providers.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/report.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/art.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/categories.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/meta.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/sync.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/tags.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/enrichment/steps/title.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/catalog/sync.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/_common.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/enrichmeta.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/enrichtitles.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/enrichtv.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/fetchurls.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/motdposters.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/cmsutils/playedmovies.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/ytpipe/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/integrations/ytpipe/downloader.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/jobs/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/jobs/fetchurls_auth.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/jobs/job_scheduler.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/jobs/manager.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/jobs/rehost_emotes.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/jobs/tasks.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/logging_config.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/playlists/bulk_add.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/playlists/ordering.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/promos/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/promos/director.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/completion.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/ordering.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/presence.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/race_poller.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/queue/shadow.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_feedback.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_job_schedules.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_jobs.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_moderation.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_promos.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/feedback.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/queue.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/js/admin-playlists.js +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/js/admin-promos.js +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/js/admin-queue-mgmt.js +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/js/admin-schedules.js +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/static/js/admin.js +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/admin/playlists.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/admin/promos.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/admin/schedules.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/catalog/edit_item_modal.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/feedback/index.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/templates/user/my_list.html +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/kryten_webqueue/ws/manager.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/scripts/AGENTS.md +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/scripts/trigger_enrich.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/__init__.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_config_persistence.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_feedback.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_fetchurls_sharepoint.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_people_facets.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_phase1.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_phase2_jobs.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_phase3_jobs.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_phase4_live_fixes.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_playlist_import.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_presence_refund.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_promo_director.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_promo_pool_exclusion.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_providers.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_queue_announce.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_race_poller.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_recently_played_hide.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_save_results_to_playlist.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_schedule_lock.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_search_facets.py +0 -0
- {kryten_webqueue-0.38.0 → kryten_webqueue-0.38.2}/tests/test_watchlist.py +0 -0
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.38.2] - 2026-08-15
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Login 500 / `TemplateRuntimeError: No filter named 'escapejs'`.** The Delete
|
|
10
|
+
Permanently buttons added in 0.38.0 used `{{ item.title | escapejs }}`, but
|
|
11
|
+
`escapejs` is a Django filter and does not exist in Jinja2, so every render of
|
|
12
|
+
`catalog/browse.html` and `catalog/item_detail.html` raised a 500 — including the
|
|
13
|
+
post-login redirect to `/catalog/browse`. The title is now passed via
|
|
14
|
+
HTML-autoescaped `data-token`/`data-title` attributes and read in JS through
|
|
15
|
+
`this.dataset`, which is both correct for Jinja2 and XSS-safe.
|
|
16
|
+
|
|
17
|
+
## [0.38.1] - 2026-08-15
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **v0.38.0 shipped without its feature code.** The 0.38.0 release commit staged
|
|
22
|
+
only the version bump and `CHANGELOG.md`; the eleven modified template, CSS, JS,
|
|
23
|
+
and route files were left uncommitted in the working tree, so the published build
|
|
24
|
+
contained the new version string but none of the visual/UX changes. This release
|
|
25
|
+
commits and ships the actual implementation described under 0.38.0 below.
|
|
26
|
+
|
|
5
27
|
## [0.38.0] - 2026-08-15
|
|
6
28
|
|
|
7
29
|
### Added
|