azimut 0.2.2__tar.gz → 0.2.4__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.
- {azimut-0.2.2 → azimut-0.2.4}/.github/workflows/release.yml +41 -36
- {azimut-0.2.2 → azimut-0.2.4}/.gitignore +1 -0
- {azimut-0.2.2 → azimut-0.2.4}/PKG-INFO +27 -30
- {azimut-0.2.2 → azimut-0.2.4}/README.md +25 -28
- {azimut-0.2.2 → azimut-0.2.4}/docs/ONTOLOGY.md +31 -5
- azimut-0.2.4/docs/RELEASE_NOTES.md +61 -0
- {azimut-0.2.2 → azimut-0.2.4}/docs/SPEC.md +81 -33
- {azimut-0.2.2 → azimut-0.2.4}/docs/STORAGE_AND_PERFORMANCE.md +99 -42
- azimut-0.2.4/docs/UI.md +202 -0
- azimut-0.2.4/extension/README.md +56 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/manifest.json +1 -1
- {azimut-0.2.2 → azimut-0.2.4}/extension/options.html +2 -3
- {azimut-0.2.2 → azimut-0.2.4}/extension/popup.html +5 -8
- {azimut-0.2.2 → azimut-0.2.4}/extension/popup.js +39 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/ui.css +3 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/e2e/app.fixture.js +53 -9
- {azimut-0.2.2 → azimut-0.2.4}/frontend/e2e/proof-canvas.spec.js +111 -3
- azimut-0.2.4/frontend/e2e/saved-linked-posts.spec.js +125 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/App.svelte +4 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/app.css +29 -0
- azimut-0.2.4/frontend/src/components/CaseSidebar.svelte +627 -0
- azimut-0.2.4/frontend/src/components/CaseSidebar.test.js +202 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/CaseSwitcher.svelte +39 -7
- azimut-0.2.4/frontend/src/components/CaseSwitcher.test.js +48 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/EntityDetails.svelte +10 -2
- azimut-0.2.4/frontend/src/components/EntityDetails.test.js +13 -0
- azimut-0.2.4/frontend/src/components/FolderBrowser.svelte +142 -0
- azimut-0.2.4/frontend/src/components/FolderBrowser.test.js +79 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/Icon.svelte +10 -5
- azimut-0.2.4/frontend/src/components/SearchInput.svelte +72 -0
- azimut-0.2.4/frontend/src/components/SearchInput.test.js +17 -0
- azimut-0.2.4/frontend/src/components/sidebar/DetailsDrawer.svelte +63 -0
- azimut-0.2.4/frontend/src/components/sidebar/EntityRow.svelte +141 -0
- azimut-0.2.4/frontend/src/components/sidebar/SidebarHeader.svelte +130 -0
- azimut-0.2.4/frontend/src/components/sidebar/SidebarResults.svelte +51 -0
- azimut-0.2.4/frontend/src/components/sidebar/SidebarTree.svelte +336 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/catalog.js +6 -3
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/catalog.test.js +44 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/composer.js +151 -80
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/composer.test.js +157 -100
- azimut-0.2.4/frontend/src/lib/entityIcon.js +35 -0
- azimut-0.2.4/frontend/src/lib/entityIcon.test.js +27 -0
- azimut-0.2.4/frontend/src/lib/fileSort.js +66 -0
- azimut-0.2.4/frontend/src/lib/fileSort.test.js +42 -0
- azimut-0.2.4/frontend/src/lib/folderBrowse.js +45 -0
- azimut-0.2.4/frontend/src/lib/folderBrowse.test.js +70 -0
- azimut-0.2.4/frontend/src/lib/folderView.js +79 -0
- azimut-0.2.4/frontend/src/lib/folderView.test.js +85 -0
- azimut-0.2.4/frontend/src/lib/geoTree.js +236 -0
- azimut-0.2.4/frontend/src/lib/geoTree.test.js +303 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/inspect.js +38 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/inspect.test.js +83 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/maplinks.js +2 -2
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/maplinks.test.js +1 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/mediaFilter.js +46 -5
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/mediaFilter.test.js +69 -1
- azimut-0.2.4/frontend/src/lib/mediaQuery.js +19 -0
- azimut-0.2.4/frontend/src/lib/mediaQuery.test.js +29 -0
- azimut-0.2.4/frontend/src/lib/naming.js +94 -0
- azimut-0.2.4/frontend/src/lib/naming.test.js +118 -0
- azimut-0.2.4/frontend/src/lib/pagedList.svelte.js +97 -0
- azimut-0.2.4/frontend/src/lib/pagedList.test.js +107 -0
- azimut-0.2.4/frontend/src/lib/panelWidth.js +52 -0
- azimut-0.2.4/frontend/src/lib/panelWidth.test.js +76 -0
- azimut-0.2.4/frontend/src/lib/pasteAsset.js +35 -0
- azimut-0.2.4/frontend/src/lib/pasteAsset.test.js +50 -0
- azimut-0.2.4/frontend/src/lib/poll.js +24 -0
- azimut-0.2.4/frontend/src/lib/poll.test.js +32 -0
- azimut-0.2.4/frontend/src/lib/rowSelect.js +29 -0
- azimut-0.2.4/frontend/src/lib/rowSelect.test.js +45 -0
- azimut-0.2.4/frontend/src/lib/savedMarkers.js +74 -0
- azimut-0.2.4/frontend/src/lib/savedMarkers.test.js +98 -0
- azimut-0.2.4/frontend/src/lib/sidebar.js +16 -0
- azimut-0.2.4/frontend/src/lib/sidebarSearch.js +42 -0
- azimut-0.2.4/frontend/src/lib/sidebarSearch.test.js +60 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/state.svelte.js +4 -3
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/Files.svelte +560 -88
- azimut-0.2.4/frontend/src/tools/Files.test.js +105 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/Inspector.svelte +557 -98
- azimut-0.2.4/frontend/src/tools/Inspector.test.js +172 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/MediaLibrary.svelte +490 -120
- azimut-0.2.4/frontend/src/tools/MediaLibrary.test.js +226 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/Notebook.svelte +81 -18
- azimut-0.2.4/frontend/src/tools/Notebook.test.js +67 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/PostComposer.svelte +112 -15
- azimut-0.2.4/frontend/src/tools/PostComposer.test.js +66 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/ProofComposer.svelte +692 -156
- azimut-0.2.4/frontend/src/tools/ProofComposer.test.js +429 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/ReverseSearch.svelte +222 -48
- azimut-0.2.4/frontend/src/tools/ReverseSearch.test.js +37 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/Satellite.svelte +554 -409
- azimut-0.2.4/frontend/src/tools/Satellite.test.js +255 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/Settings.svelte +67 -125
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/CollageMenu.svelte +67 -4
- azimut-0.2.4/frontend/src/tools/inspect/CollageMenu.test.js +37 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/SaveGallery.svelte +54 -26
- azimut-0.2.4/frontend/src/tools/inspect/SaveGallery.test.js +69 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/SaveMenu.svelte +17 -4
- azimut-0.2.4/frontend/src/tools/inspect/SaveMenu.test.js +37 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/proof/NewProofDialog.svelte +65 -34
- azimut-0.2.4/frontend/src/tools/proof/NewProofDialog.test.js +88 -0
- azimut-0.2.4/frontend/src/tools/proof/PanelCategories.svelte +46 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/proof/ProofLayersPanel.svelte +129 -6
- azimut-0.2.4/frontend/src/tools/proof/ProofLayersPanel.test.js +25 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/satellite/MapToolCluster.svelte +49 -17
- azimut-0.2.4/frontend/src/tools/satellite/SavedOverlay.svelte +248 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedPopup.svelte +395 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedPopup.test.js +185 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedRow.svelte +312 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedSearch.svelte +173 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedSearch.test.js +139 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedTree.svelte +458 -0
- azimut-0.2.4/frontend/src/tools/satellite/SavedTree.test.js +272 -0
- {azimut-0.2.2 → azimut-0.2.4}/pyproject.toml +9 -2
- azimut-0.2.4/scripts/vendor_ffmpeg.py +246 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/__init__.py +9 -1
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/cases.py +7 -5
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/drafts.py +34 -21
- azimut-0.2.4/src/azimut/api/files.py +45 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/ingest.py +67 -1
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/inspect.py +39 -19
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/media.py +54 -3
- azimut-0.2.4/src/azimut/api/naming.py +44 -0
- azimut-0.2.4/src/azimut/api/proofs.py +364 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/satellite.py +101 -15
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/settings.py +7 -14
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/config.py +2 -2
- azimut-0.2.4/src/azimut/engine/continents.py +127 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/coords.py +1 -1
- azimut-0.2.4/src/azimut/engine/countries.py +113 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/geo.py +97 -6
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/inspect.py +44 -29
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/links.py +5 -5
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/mapsites.py +33 -4
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/media.py +18 -29
- azimut-0.2.4/src/azimut/engine/satellite.py +467 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/thumbnails.py +20 -3
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/tiles.py +7 -27
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/repository.py +57 -13
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/sqlite_backend.py +461 -34
- azimut-0.2.4/src/azimut/static/assets/Coordinates-BTvv-wM-.js +1 -0
- azimut-0.2.4/src/azimut/static/assets/Files-B2_kQAyd.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/Files-Dk4RDk90.js +1 -0
- azimut-0.2.4/src/azimut/static/assets/FolderBrowser-Bw_BtxXT.js +1 -0
- azimut-0.2.4/src/azimut/static/assets/FolderBrowser-CIzLfX1P.css +1 -0
- azimut-0.2.2/src/azimut/static/assets/Icon-BgA9a5tG.js → azimut-0.2.4/src/azimut/static/assets/Icon-BbBIW1NX.js +2 -2
- azimut-0.2.4/src/azimut/static/assets/Inspector-DYlVevMi.js +6 -0
- azimut-0.2.4/src/azimut/static/assets/Inspector-Kzis3eVb.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/MediaLibrary-B5jleDki.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/MediaLibrary-BfWpwusH.js +4 -0
- azimut-0.2.4/src/azimut/static/assets/Notebook-K-LyWdfA.js +65 -0
- azimut-0.2.4/src/azimut/static/assets/Notebook-qbBuViJS.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/PostComposer-1GLnb8o5.js +5 -0
- azimut-0.2.2/src/azimut/static/assets/PostComposer-C1P4_rp3.css → azimut-0.2.4/src/azimut/static/assets/PostComposer-CoKuI09l.css +1 -1
- azimut-0.2.4/src/azimut/static/assets/ProofComposer-8LPf0C7W.js +3 -0
- azimut-0.2.4/src/azimut/static/assets/ProofComposer-wT6PjcOM.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/ReverseSearch--XzLo8zC.js +1 -0
- azimut-0.2.2/src/azimut/static/assets/ReverseSearch-DqIrU_Pa.css → azimut-0.2.4/src/azimut/static/assets/ReverseSearch-DyguTuti.css +1 -1
- azimut-0.2.4/src/azimut/static/assets/Satellite-BNf2aMJ9.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/Satellite-DHLE7Zxq.js +31 -0
- azimut-0.2.4/src/azimut/static/assets/Settings-CbwII4OD.js +7 -0
- azimut-0.2.4/src/azimut/static/assets/composer-BOgT80fX.js +1 -0
- azimut-0.2.2/src/azimut/static/assets/gmaps-D52n5msu.js → azimut-0.2.4/src/azimut/static/assets/gmaps-UfC9RQrO.js +1 -1
- azimut-0.2.4/src/azimut/static/assets/index-B5LoFWtr.js +2 -0
- azimut-0.2.4/src/azimut/static/assets/index-D5HHtD16.css +1 -0
- azimut-0.2.4/src/azimut/static/assets/maplinks-Cnh2ZfxE.js +1 -0
- azimut-0.2.4/src/azimut/static/assets/mediaFilter-D6wNuzNu.js +2 -0
- azimut-0.2.4/src/azimut/static/assets/naming-6rrJTXku.js +1 -0
- azimut-0.2.4/src/azimut/static/assets/poll-g_Pnx6yJ.js +1 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/index.html +3 -5
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/workspace.py +62 -19
- {azimut-0.2.2 → azimut-0.2.4}/tests/bigcase.py +8 -15
- {azimut-0.2.2 → azimut-0.2.4}/tests/conftest.py +15 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_bigcase.py +3 -4
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_cases_api.py +39 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_drafts_api.py +47 -5
- azimut-0.2.4/tests/test_files_api.py +66 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_geo_api.py +36 -0
- azimut-0.2.4/tests/test_geo_locate.py +233 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_hardening.py +13 -1
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_ingest_api.py +128 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_inspect_api.py +194 -8
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_links_api.py +34 -36
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_mapsites.py +30 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_media_api.py +178 -0
- azimut-0.2.4/tests/test_naming.py +50 -0
- azimut-0.2.4/tests/test_proofs_api.py +531 -0
- azimut-0.2.4/tests/test_proofs_assets_api.py +245 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_release_gate.py +36 -5
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_repository.py +43 -2
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_satellite_api.py +331 -1
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_sqlite_backend.py +126 -6
- azimut-0.2.4/tests/test_vendor_ffmpeg.py +143 -0
- {azimut-0.2.2 → azimut-0.2.4}/uv.lock +0 -1
- azimut-0.2.2/bench/case_baseline.py +0 -149
- azimut-0.2.2/docs/RELEASE_NOTES.md +0 -19
- azimut-0.2.2/docs/UI.md +0 -111
- azimut-0.2.2/extension/README.md +0 -65
- azimut-0.2.2/frontend/src/components/CaseSidebar.svelte +0 -887
- azimut-0.2.2/frontend/src/lib/sidebar.js +0 -46
- azimut-0.2.2/frontend/src/tools/MediaLibrary.test.js +0 -95
- azimut-0.2.2/frontend/src/tools/Notebook.test.js +0 -39
- azimut-0.2.2/frontend/src/tools/PostComposer.test.js +0 -21
- azimut-0.2.2/frontend/src/tools/ProofComposer.test.js +0 -175
- azimut-0.2.2/src/azimut/api/files.py +0 -27
- azimut-0.2.2/src/azimut/api/proofs.py +0 -151
- azimut-0.2.2/src/azimut/engine/satellite.py +0 -65
- azimut-0.2.2/src/azimut/static/assets/Coordinates-Zk6hc7rX.js +0 -1
- azimut-0.2.2/src/azimut/static/assets/Files-B_kDrMmA.js +0 -1
- azimut-0.2.2/src/azimut/static/assets/Files-DoSPZhF-.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/Inspector-3v5iq-jW.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/Inspector-CbDQE9mL.js +0 -5
- azimut-0.2.2/src/azimut/static/assets/MediaLibrary-DxDbISiM.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/MediaLibrary-aa18XUg0.js +0 -5
- azimut-0.2.2/src/azimut/static/assets/Modal-CuJYoHU9.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/Modal-DHCHN-zW.js +0 -1
- azimut-0.2.2/src/azimut/static/assets/Notebook-6bRvw0Ld.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/Notebook-De7CIAen.js +0 -65
- azimut-0.2.2/src/azimut/static/assets/PostComposer-BoRw8SZk.js +0 -5
- azimut-0.2.2/src/azimut/static/assets/ProofComposer-C5mWoc8h.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/ProofComposer-hy7ZrvOu.js +0 -2
- azimut-0.2.2/src/azimut/static/assets/ReverseSearch-BP3C1CxL.js +0 -1
- azimut-0.2.2/src/azimut/static/assets/Satellite-BhhCtezr.js +0 -31
- azimut-0.2.2/src/azimut/static/assets/Satellite-DGCcPv9w.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/Settings-CnfrsP9_.js +0 -30
- azimut-0.2.2/src/azimut/static/assets/composer-C17apZ5p.js +0 -1
- azimut-0.2.2/src/azimut/static/assets/index-B8MBkQLT.js +0 -3
- azimut-0.2.2/src/azimut/static/assets/index-BaaWj0p3.css +0 -1
- azimut-0.2.2/src/azimut/static/assets/maplinks-LmyLzEQg.js +0 -1
- azimut-0.2.2/tests/test_proofs_api.py +0 -119
- {azimut-0.2.2 → azimut-0.2.4}/.github/workflows/ci.yml +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/LICENSE +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/docs/IMAGERY_PROVIDERS.md +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/background.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/bridge.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/icons/icon128.png +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/icons/icon16.png +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/icons/icon32.png +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/icons/icon48.png +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/options.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/extension/overlay.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/e2e/satellite-canvas.spec.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/index.html +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/jsconfig.json +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/package-lock.json +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/package.json +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/playwright.config.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/public/favicon.svg +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/assets/logo-source.svg +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/ConfirmDialog.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/FolderSelect.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/FolderSelect.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/Logo.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/Modal.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/PostTemplateEditor.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/ProofPreview.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/ProofTemplateEditor.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/Toasts.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/Toasts.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/UpdateModal.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/components/Wordmark.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/api.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/appUpdate.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/appUpdate.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/bidi.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/bidi.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/bookmarks.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/bookmarks.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/captureSize.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/captureSize.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/chain.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/chain.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/coords.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/coords.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/events.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/events.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/extBridge.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/extBridge.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/extension.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/filing.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/filing.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/folderTree.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/folderTree.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/frameRotate.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/frameRotate.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/fullscreen.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/fullscreen.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/gmaps.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/gmaps.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/gridSearch.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/gridSearch.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/gridSelect.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/gridSelect.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/history.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/history.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/markdown.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/markdown.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/measure.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/measure.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/navigate.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/navigate.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebook.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebook.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebookContent.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebookContent.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebookPdf.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebookPdf.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebookTabs.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notebookTabs.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notes.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/notes.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/post.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/post.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/refViewers.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/refViewers.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/reverseSearch.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/reverseSearch.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/satRotate.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/satRotate.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/screenCrop.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/screenCrop.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/sentinel.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/sentinel.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/sidebar.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/state.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/theme.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/theme.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/toast.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/toolLoader.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/toolLoader.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/usage.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/usage.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/workspaces.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/lib/workspaces.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/main.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/Coordinates.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/RefViewer.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/AdjustSliders.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/CollageCanvas.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/CollagePreview.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/CropBox.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/CropControls.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/FrameMenu.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/OrientationControls.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/PieceCropModal.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/SelectionMenu.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/VideoPlayer.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/inspect/VideoPlayer.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/proof/ProofCanvas.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/proof/ProofToolbar.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/proof/ProofToolbar.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/proof/canvasLifecycle.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/satellite/CaptureOptions.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/satellite/GridSearchPanel.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/satellite/SentinelPicker.svelte +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/src/tools/satellite/SentinelPicker.test.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/frontend/vite.config.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/packaging/azimut.ico +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/packaging/azimut.spec +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/packaging/entry.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/scripts/relaunch.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/scripts/smoke_binary.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/__main__.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/__init__.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/events.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/limits.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/api/templates.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/cli.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/__init__.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/ffmpeg.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/google_tiles.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/scrapers.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/sentinel.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/stitch.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/tilecache.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/engine/updates.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/jobs.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/launcher.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/server.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/Coordinates-CkOCsDYx.css +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/Settings-Nqf90D6_.css +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/bidi-wWDUT82v.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/frameRotate-F1nGHpcH.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/history-D8hJuA9t.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/leaflet-rotate-hAaDqhcJ.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/lib-Ce199MB2.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/markdown-Db8boR5D.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-400-normal-BnNz-3Mf.woff +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-400-normal-DcSlRu53.woff2 +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-600-normal-DNQhW0y0.woff +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-600-normal-DW9ldEDP.woff2 +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-700-normal-b_KP-pae.woff +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-700-normal-l0hKEjh4.woff2 +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-ext-400-normal-B1qoybeA.woff2 +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-ext-400-normal-ngSbnDVv.woff +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-ext-600-normal-B2S5WIA4.woff2 +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-ext-600-normal-DywhiVWf.woff +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-ext-700-normal-BSlCClLu.woff2 +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/oxanium-latin-ext-700-normal-CPlnVieJ.woff +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/post-COJahl2R.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/assets/rolldown-runtime-Bh1tDfsg.js +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/src/azimut/static/favicon.svg +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/graph_read.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/legacy_case.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_binary_smoke.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_config.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_coords.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_events_api.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_ffmpeg.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_focus.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_geo_formats.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_google_tiles.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_jobs.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_launcher.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_migrations.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_relaunch.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_scrapers.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_sentinel.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_server_guard.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_settings_api.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_settings_backup.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_stitch.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_templates_api.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_thumbnails.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_tiles.py +0 -0
- {azimut-0.2.2 → azimut-0.2.4}/tests/test_updates.py +0 -0
|
@@ -11,8 +11,37 @@ permissions:
|
|
|
11
11
|
id-token: write # PyPI Trusted Publishing (OIDC) — no token secret needed
|
|
12
12
|
|
|
13
13
|
jobs:
|
|
14
|
+
guard:
|
|
15
|
+
name: Version + release gate
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: astral-sh/setup-uv@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
# Install the app (editable) + dev tools, like the CI backend job, so the
|
|
23
|
+
# gate can import azimut and run its tests. No frontend build: these tests
|
|
24
|
+
# don't touch the built UI, and the app tolerates a missing static dir.
|
|
25
|
+
- run: uv sync --frozen --extra dev
|
|
26
|
+
# The pushed tag must equal the version baked into the code. When it
|
|
27
|
+
# didn't (0.2.2 shipped a stale __version__), the binary's self-update
|
|
28
|
+
# check nagged every user about the very release they were running. This
|
|
29
|
+
# is the check the release used to lack — it runs before anything builds.
|
|
30
|
+
- name: Tag matches the code version
|
|
31
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
32
|
+
run: |
|
|
33
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
34
|
+
ver="$(uv run --no-sync python -c 'import azimut; print(azimut.__version__)')"
|
|
35
|
+
echo "tag=$tag __version__=$ver"
|
|
36
|
+
[ "$tag" = "$ver" ] || { echo "::error::tag v$tag != __version__ $ver — bump src/azimut/__init__.py"; exit 1; }
|
|
37
|
+
# The version-parity gate the release workflow used to skip: pyproject's
|
|
38
|
+
# single-sourced version and the extension manifest must line up.
|
|
39
|
+
- name: Release gate + version parity
|
|
40
|
+
run: uv run --no-sync pytest tests/test_release_gate.py tests/test_updates.py -q
|
|
41
|
+
|
|
14
42
|
dist:
|
|
15
43
|
name: Build wheel + sdist
|
|
44
|
+
needs: guard
|
|
16
45
|
runs-on: ubuntu-latest
|
|
17
46
|
steps:
|
|
18
47
|
- uses: actions/checkout@v4
|
|
@@ -45,6 +74,7 @@ jobs:
|
|
|
45
74
|
|
|
46
75
|
binaries:
|
|
47
76
|
name: Binary (${{ matrix.os }})
|
|
77
|
+
needs: guard
|
|
48
78
|
runs-on: ${{ matrix.os }}
|
|
49
79
|
strategy:
|
|
50
80
|
fail-fast: false
|
|
@@ -52,13 +82,15 @@ jobs:
|
|
|
52
82
|
include:
|
|
53
83
|
- os: ubuntu-latest
|
|
54
84
|
asset: azimut-linux-x86_64
|
|
85
|
+
ffmpeg_target: linux-x86_64
|
|
55
86
|
- os: windows-latest
|
|
56
87
|
asset: azimut-windows-x86_64.exe
|
|
88
|
+
ffmpeg_target: windows-x86_64
|
|
57
89
|
- os: macos-latest
|
|
58
90
|
asset: azimut-macos-arm64
|
|
59
|
-
|
|
60
|
-
#
|
|
61
|
-
#
|
|
91
|
+
ffmpeg_target: macos-arm64
|
|
92
|
+
# macos-latest is Apple Silicon. Intel remains a documented Python
|
|
93
|
+
# package install rather than a standalone release asset.
|
|
62
94
|
steps:
|
|
63
95
|
- uses: actions/checkout@v4
|
|
64
96
|
- uses: actions/setup-node@v4
|
|
@@ -76,40 +108,13 @@ jobs:
|
|
|
76
108
|
run: |
|
|
77
109
|
uv sync --frozen --no-dev --group release --no-install-project
|
|
78
110
|
uv sync --frozen --no-dev --group release --no-build-isolation --no-editable
|
|
79
|
-
# ffmpeg is a native program, not a Python dep
|
|
80
|
-
#
|
|
81
|
-
# box (packaging/azimut.spec picks them up; engine/ffmpeg.py finds them at
|
|
82
|
-
# runtime). One host, one arch per runner; each zip holds a single binary.
|
|
111
|
+
# ffmpeg is a native program, not a Python dep. The helper pins and hashes
|
|
112
|
+
# each upstream archive, then extracts only the expected tools.
|
|
83
113
|
- name: Vendor static ffmpeg + ffprobe into the binary
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
# martin-riedl.de stopped publishing Windows builds; BtbN's
|
|
89
|
-
# "latest" release tag always points at the newest static win64
|
|
90
|
-
# build, so pull ffmpeg.exe/ffprobe.exe out of its nested bin/.
|
|
91
|
-
curl -fL "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-win64-gpl.zip" -o ffmpeg.zip
|
|
92
|
-
uv run --no-sync python -c "
|
|
93
|
-
import zipfile
|
|
94
|
-
zf = zipfile.ZipFile('ffmpeg.zip')
|
|
95
|
-
for n in zf.namelist():
|
|
96
|
-
tail = n.rsplit('/', 1)[-1]
|
|
97
|
-
if tail in ('ffmpeg.exe', 'ffprobe.exe'):
|
|
98
|
-
open('packaging/vendor/' + tail, 'wb').write(zf.read(n))
|
|
99
|
-
"
|
|
100
|
-
else
|
|
101
|
-
case "${{ runner.os }}" in
|
|
102
|
-
Linux) plat=linux/amd64 ;;
|
|
103
|
-
macOS) plat=macos/arm64 ;;
|
|
104
|
-
esac
|
|
105
|
-
base="https://ffmpeg.martin-riedl.de/redirect/latest/$plat/release"
|
|
106
|
-
for tool in ffmpeg ffprobe; do
|
|
107
|
-
curl -fL "$base/$tool.zip" -o "$tool.zip"
|
|
108
|
-
uv run --no-sync python -c "import sys, zipfile; zipfile.ZipFile(sys.argv[1]).extractall('packaging/vendor')" "$tool.zip"
|
|
109
|
-
done
|
|
110
|
-
fi
|
|
111
|
-
chmod +x packaging/vendor/* 2>/dev/null || true
|
|
112
|
-
ls -l packaging/vendor
|
|
114
|
+
run: >-
|
|
115
|
+
uv run --no-sync python scripts/vendor_ffmpeg.py
|
|
116
|
+
"${{ matrix.ffmpeg_target }}"
|
|
117
|
+
--output packaging/vendor
|
|
113
118
|
- name: Build single-file binary
|
|
114
119
|
run: uv run --no-sync pyinstaller packaging/azimut.spec --distpath dist-bin --workpath build-bin
|
|
115
120
|
- name: Smoke-test the binary
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: azimut
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: A local OSINT workspace for media, geolocation proofs and case management.
|
|
5
5
|
Project-URL: Homepage, https://github.com/OsintMeThat/azimut
|
|
6
6
|
Author: OsintMeThat
|
|
7
7
|
License: AGPL-3.0-only
|
|
8
8
|
License-File: LICENSE
|
|
9
9
|
Keywords: geoint,geolocation,investigation,osint,verification
|
|
10
|
-
Classifier: Development Status ::
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Environment :: Web Environment
|
|
12
12
|
Classifier: Intended Audience :: Other Audience
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
@@ -47,7 +47,7 @@ case is a plain folder that can be reopened, archived or shared.
|
|
|
47
47
|
*The name is the French word for azimuth, the compass bearing you sight along
|
|
48
48
|
to fix a point on the map.*
|
|
49
49
|
|
|
50
|
-
## v0.2.
|
|
50
|
+
## v0.2.4: Saved work and scalable browsing
|
|
51
51
|
|
|
52
52
|
| Tool | What it does |
|
|
53
53
|
|------|--------------|
|
|
@@ -67,15 +67,18 @@ extension, and cross-platform binaries with a bundled ffmpeg.
|
|
|
67
67
|
Every tool works one-shot (a scratch session, no setup) or inside a case, a
|
|
68
68
|
plain directory holding the whole investigation.
|
|
69
69
|
|
|
70
|
-
New in v0.2.
|
|
70
|
+
New in v0.2.4:
|
|
71
71
|
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
- Saved places, captures, filed screenshots and proofs are easier to find,
|
|
73
|
+
preview and place on the map.
|
|
74
|
+
- The case sidebar and Files now support search, filters, folder browsing,
|
|
75
|
+
multi-select filing and a details list.
|
|
76
|
+
- Media and Files use bounded SQLite queries, including complete category
|
|
77
|
+
counts and search results beyond the first page.
|
|
78
|
+
- Inspect, Geo Proof and Geo Report use named saves. Their pickers can search
|
|
79
|
+
and browse folders.
|
|
80
|
+
- Release binaries now fetch pinned, SHA-256-verified ffmpeg archives. Images
|
|
81
|
+
above 100 MP are rejected before decode.
|
|
79
82
|
|
|
80
83
|
## Install & run
|
|
81
84
|
|
|
@@ -101,12 +104,9 @@ opens Azimut in your browser.
|
|
|
101
104
|
|----|-------|
|
|
102
105
|
| Windows | `azimut-windows-x86_64.exe` |
|
|
103
106
|
| macOS (Apple Silicon) | `azimut-macos-arm64` |
|
|
104
|
-
| macOS (Intel) | No standalone binary; install with `pipx` or `pip` |
|
|
107
|
+
| macOS (Intel, 14+) | No standalone binary; install with `pipx` or `pip` |
|
|
105
108
|
| Linux | `azimut-linux-x86_64` |
|
|
106
109
|
|
|
107
|
-
Intel Macs are supported through the Python package. They do not have a
|
|
108
|
-
downloadable standalone binary.
|
|
109
|
-
|
|
110
110
|
First run, the binaries are **unsigned**, so the OS warns before letting them
|
|
111
111
|
open:
|
|
112
112
|
- **macOS**: right-click the file → **Open** → **Open** (Gatekeeper only
|
|
@@ -116,10 +116,10 @@ open:
|
|
|
116
116
|
info** → **Run anyway**.
|
|
117
117
|
- **Linux**: mark it executable with `chmod +x azimut-linux-x86_64`.
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
119
|
+
Azimut checks for a newer release on startup by default and links the download.
|
|
120
|
+
Settings can disable that check, and **Settings → About → Check for updates**
|
|
121
|
+
runs it manually. Replace the old binary with the new one. To uninstall, delete
|
|
122
|
+
the binary. Either way `~/Azimut` stays put, so cases open unchanged.
|
|
123
123
|
|
|
124
124
|
The downloadable binaries bundle a static **ffmpeg** (and ffprobe), so video
|
|
125
125
|
thumbnails, frame scans, video enhancement, and downloads that merge separate
|
|
@@ -235,7 +235,7 @@ wheel + Windows/Linux/macOS binaries, attaches them to a GitHub release, and
|
|
|
235
235
|
publishes to PyPI. **Don't publish by hand.**
|
|
236
236
|
|
|
237
237
|
```bash
|
|
238
|
-
git tag v0.2.
|
|
238
|
+
git tag v0.2.4 && git push origin v0.2.4
|
|
239
239
|
```
|
|
240
240
|
|
|
241
241
|
One-time setup: register the repo as a
|
|
@@ -244,17 +244,14 @@ One-time setup: register the repo as a
|
|
|
244
244
|
|
|
245
245
|
## Principles
|
|
246
246
|
|
|
247
|
-
1.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
in per-case SQLite. A closed case folder is complete and portable; a ZIP
|
|
252
|
-
import/export workflow is planned.
|
|
247
|
+
1. No account, telemetry or automatic upload. The server binds to
|
|
248
|
+
`127.0.0.1`, and Azimut never posts on your behalf.
|
|
249
|
+
2. A case contains the investigation's files and SQLite graph. A closed case
|
|
250
|
+
folder is complete and portable; ZIP import/export is planned.
|
|
253
251
|
3. One tab = one tool, useful in 30 seconds.
|
|
254
|
-
4.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
6. **Honest output.** Every artifact records how it was produced.
|
|
252
|
+
4. Azimut integrates specialized services instead of recreating them.
|
|
253
|
+
5. The analyst decides; tools do not produce automated verdicts.
|
|
254
|
+
6. Every artifact records how it was produced.
|
|
258
255
|
7. Free and open source. No paid key is ever required; bring your own for
|
|
259
256
|
more basemaps.
|
|
260
257
|
|
|
@@ -9,7 +9,7 @@ case is a plain folder that can be reopened, archived or shared.
|
|
|
9
9
|
*The name is the French word for azimuth, the compass bearing you sight along
|
|
10
10
|
to fix a point on the map.*
|
|
11
11
|
|
|
12
|
-
## v0.2.
|
|
12
|
+
## v0.2.4: Saved work and scalable browsing
|
|
13
13
|
|
|
14
14
|
| Tool | What it does |
|
|
15
15
|
|------|--------------|
|
|
@@ -29,15 +29,18 @@ extension, and cross-platform binaries with a bundled ffmpeg.
|
|
|
29
29
|
Every tool works one-shot (a scratch session, no setup) or inside a case, a
|
|
30
30
|
plain directory holding the whole investigation.
|
|
31
31
|
|
|
32
|
-
New in v0.2.
|
|
32
|
+
New in v0.2.4:
|
|
33
33
|
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
- Saved places, captures, filed screenshots and proofs are easier to find,
|
|
35
|
+
preview and place on the map.
|
|
36
|
+
- The case sidebar and Files now support search, filters, folder browsing,
|
|
37
|
+
multi-select filing and a details list.
|
|
38
|
+
- Media and Files use bounded SQLite queries, including complete category
|
|
39
|
+
counts and search results beyond the first page.
|
|
40
|
+
- Inspect, Geo Proof and Geo Report use named saves. Their pickers can search
|
|
41
|
+
and browse folders.
|
|
42
|
+
- Release binaries now fetch pinned, SHA-256-verified ffmpeg archives. Images
|
|
43
|
+
above 100 MP are rejected before decode.
|
|
41
44
|
|
|
42
45
|
## Install & run
|
|
43
46
|
|
|
@@ -63,12 +66,9 @@ opens Azimut in your browser.
|
|
|
63
66
|
|----|-------|
|
|
64
67
|
| Windows | `azimut-windows-x86_64.exe` |
|
|
65
68
|
| macOS (Apple Silicon) | `azimut-macos-arm64` |
|
|
66
|
-
| macOS (Intel) | No standalone binary; install with `pipx` or `pip` |
|
|
69
|
+
| macOS (Intel, 14+) | No standalone binary; install with `pipx` or `pip` |
|
|
67
70
|
| Linux | `azimut-linux-x86_64` |
|
|
68
71
|
|
|
69
|
-
Intel Macs are supported through the Python package. They do not have a
|
|
70
|
-
downloadable standalone binary.
|
|
71
|
-
|
|
72
72
|
First run, the binaries are **unsigned**, so the OS warns before letting them
|
|
73
73
|
open:
|
|
74
74
|
- **macOS**: right-click the file → **Open** → **Open** (Gatekeeper only
|
|
@@ -78,10 +78,10 @@ open:
|
|
|
78
78
|
info** → **Run anyway**.
|
|
79
79
|
- **Linux**: mark it executable with `chmod +x azimut-linux-x86_64`.
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
Azimut checks for a newer release on startup by default and links the download.
|
|
82
|
+
Settings can disable that check, and **Settings → About → Check for updates**
|
|
83
|
+
runs it manually. Replace the old binary with the new one. To uninstall, delete
|
|
84
|
+
the binary. Either way `~/Azimut` stays put, so cases open unchanged.
|
|
85
85
|
|
|
86
86
|
The downloadable binaries bundle a static **ffmpeg** (and ffprobe), so video
|
|
87
87
|
thumbnails, frame scans, video enhancement, and downloads that merge separate
|
|
@@ -197,7 +197,7 @@ wheel + Windows/Linux/macOS binaries, attaches them to a GitHub release, and
|
|
|
197
197
|
publishes to PyPI. **Don't publish by hand.**
|
|
198
198
|
|
|
199
199
|
```bash
|
|
200
|
-
git tag v0.2.
|
|
200
|
+
git tag v0.2.4 && git push origin v0.2.4
|
|
201
201
|
```
|
|
202
202
|
|
|
203
203
|
One-time setup: register the repo as a
|
|
@@ -206,17 +206,14 @@ One-time setup: register the repo as a
|
|
|
206
206
|
|
|
207
207
|
## Principles
|
|
208
208
|
|
|
209
|
-
1.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
in per-case SQLite. A closed case folder is complete and portable; a ZIP
|
|
214
|
-
import/export workflow is planned.
|
|
209
|
+
1. No account, telemetry or automatic upload. The server binds to
|
|
210
|
+
`127.0.0.1`, and Azimut never posts on your behalf.
|
|
211
|
+
2. A case contains the investigation's files and SQLite graph. A closed case
|
|
212
|
+
folder is complete and portable; ZIP import/export is planned.
|
|
215
213
|
3. One tab = one tool, useful in 30 seconds.
|
|
216
|
-
4.
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
6. **Honest output.** Every artifact records how it was produced.
|
|
214
|
+
4. Azimut integrates specialized services instead of recreating them.
|
|
215
|
+
5. The analyst decides; tools do not produce automated verdicts.
|
|
216
|
+
6. Every artifact records how it was produced.
|
|
220
217
|
7. Free and open source. No paid key is ever required; bring your own for
|
|
221
218
|
more basemaps.
|
|
222
219
|
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
**Storage schema: `3`.** The manifest carries `{"azimut": {"schema": 3,
|
|
8
8
|
"storage": "sqlite"}}`; schema 3 moved the graph from `case.json` to per-case
|
|
9
9
|
`case.db`. The entity/link shape is unchanged since v1. Breaking changes require
|
|
10
|
-
a schema bump and migration.
|
|
10
|
+
a manifest schema bump and migration. The internal SQLite schema is version 4;
|
|
11
|
+
it adds search and media browse indexes without changing this logical model.
|
|
11
12
|
|
|
12
13
|
Legend: ✅ implemented in code · 🔶 machinery exists, unused · ⬜ proposed.
|
|
13
14
|
|
|
@@ -26,8 +27,9 @@ presents it as this logical shape:
|
|
|
26
27
|
- **Links** are typed directed edges. Every save records its inputs; see §3. ✅
|
|
27
28
|
- **Folders** are `/`-nested analyst buckets in `attrs.folder`, not semantic
|
|
28
29
|
links. ✅
|
|
29
|
-
- Media sidecars hold kind, size, uploader, duration and thumbnail data.
|
|
30
|
-
|
|
30
|
+
- Media sidecars hold kind, size, uploader, duration and thumbnail data. A
|
|
31
|
+
SQLite browse index mirrors searchable fields. Entities retain only what the
|
|
32
|
+
graph needs for identity, links and deduplication.
|
|
31
33
|
|
|
32
34
|
## 2. Entity
|
|
33
35
|
|
|
@@ -43,13 +45,22 @@ presents it as this logical shape:
|
|
|
43
45
|
`type` is extensible: unknown strings are stored but receive no custom renderer.
|
|
44
46
|
`label` is editable and never defines identity.
|
|
45
47
|
|
|
48
|
+
`geo` is the country a saved point falls in, resolved once and kept:
|
|
49
|
+
`{state, country_code, country, region?, region_en?}` with `state` one of `ok`,
|
|
50
|
+
`nocoords` (no position to look up), `nocountry` (open sea) or `failed` (the
|
|
51
|
+
lookup did not answer — the only state a later pass retries). `country` and
|
|
52
|
+
`region` are the local-language names; `region_en` is a second lookup in English
|
|
53
|
+
and is absent when it failed or matched the native name. Continent and the
|
|
54
|
+
English country name are *not* stored: both are derived from `country_code` at
|
|
55
|
+
read time, so extending those tables repairs existing cases with no migration.
|
|
56
|
+
|
|
46
57
|
### Entity type registry
|
|
47
58
|
|
|
48
59
|
| Type | State | Produced by | Key `attrs` | File-backed |
|
|
49
60
|
|---|---|---|---|---|
|
|
50
61
|
| `media` | ✅ | media-library | `path`, `sha256`, `source_url?` | yes (+ sidecar) |
|
|
51
|
-
| `capture` | ✅ | satellite | `coords`, `lat`, `lon`, `plus_code`, `zoom`, `bearing`, `path` | yes (image) |
|
|
52
|
-
| `place` | ✅ | satellite | `coords`, `lat`, `lon`, `plus_code`, `zoom`, `bearing`, `notes?` | no (a point) |
|
|
62
|
+
| `capture` | ✅ | satellite | `coords`, `lat`, `lon`, `plus_code`, `zoom`, `bearing`, `path`, `geo?` | yes (image) |
|
|
63
|
+
| `place` | ✅ | satellite, ingest | `coords`, `lat`, `lon`, `plus_code`, `zoom`, `bearing`, `notes?`, `geo?`, `source_url?`, `site?` | no (a point) |
|
|
53
64
|
| `proof` | ✅ | proof-composer | `spec` (json), `path` (png) | yes |
|
|
54
65
|
| `post` | ✅ | post-composer | `draft` (json) | yes |
|
|
55
66
|
| `inspect-session` | ✅ | inspect | `spec` (json) | yes |
|
|
@@ -67,6 +78,11 @@ New types coming from the roadmap (declare here when built): `panorama`,
|
|
|
67
78
|
Per-type attribute schemas remain open work. Today attribute keys are conventions,
|
|
68
79
|
not a validated contract between tools.
|
|
69
80
|
|
|
81
|
+
The file-backed pointers of `proof`, `post` and `inspect-session` (`spec`,
|
|
82
|
+
`draft`, `path`) are not stable: the file's name follows the label, so renaming
|
|
83
|
+
one in its tool rewrites the pointer on the same entity. Look these up by id, or
|
|
84
|
+
re-read the pointer — never cache one across a save.
|
|
85
|
+
|
|
70
86
|
## 3. Link
|
|
71
87
|
|
|
72
88
|
```jsonc
|
|
@@ -106,6 +122,13 @@ A tool selects one of two deletion behaviours through its link type:
|
|
|
106
122
|
|
|
107
123
|
- `derived-from` never cascades into an output. A post keeps its text when its
|
|
108
124
|
proof is deleted; a frame keeps its pixels when its video is deleted.
|
|
125
|
+
- It is also read backwards, as geography. The Saved panel counts the proofs
|
|
126
|
+
hanging off each saved point through this edge, and a proof with no point of
|
|
127
|
+
its own is placed at the point of every capture it composes, one hop back.
|
|
128
|
+
A proof does carry its own point first, though: `coordsText` (what the analyst
|
|
129
|
+
typed, in any supported format) then `coords` (what the panels gave it, frozen
|
|
130
|
+
at save). That is what keeps a proof on the map once its capture is deleted —
|
|
131
|
+
a tombstone records the path, the sha256 and the URL, never coordinates.
|
|
109
132
|
- `attrs.lost_sources[]` stores `{label, type, path, sha256, source_url, at}`.
|
|
110
133
|
Tombstones are keyed by path and never stacked.
|
|
111
134
|
- Every UI deletion uses the same dependency-aware service. The confirmation
|
|
@@ -133,6 +156,9 @@ How it is wired (`engine/links.py`):
|
|
|
133
156
|
resolves path → entity and emits the edge.
|
|
134
157
|
- Every save restates sources through `sync`. Removing a panel removes its edge;
|
|
135
158
|
repeated saves keep one edge per panel.
|
|
159
|
+
- A proof's pasted images are read as decoration, not sources: they carry no case
|
|
160
|
+
path, so they file no entity and earn no edge. Only panels put a proof in a
|
|
161
|
+
chain.
|
|
136
162
|
- A missing source path produces a tombstone instead of a link.
|
|
137
163
|
- Media derivatives are all filed through one registration point, so any future
|
|
138
164
|
tool producing imagery gets its chain for free. A derivative that **dedupes**
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Azimut v0.2.4
|
|
2
|
+
|
|
3
|
+
## OSINT toolkit at a glance
|
|
4
|
+
|
|
5
|
+
- **Sources:** import or download media, use an existing login when a post
|
|
6
|
+
requires it, record hashes and provenance, inspect frames, crops, collages,
|
|
7
|
+
panoramas and ELA, then prepare reverse-image searches.
|
|
8
|
+
- **Maps:** convert coordinates, geocode places, capture attributed imagery,
|
|
9
|
+
compare providers, rotate and measure maps, save references and review AOI
|
|
10
|
+
grids.
|
|
11
|
+
- **Evidence:** organise media, places, proofs and notes in portable cases with
|
|
12
|
+
folders, links, Markdown notebooks and PDF output.
|
|
13
|
+
- **Publishing:** build annotated Geo Proofs and prepare evidence-linked Geo
|
|
14
|
+
Reports for X, Bluesky or Mastodon without posting automatically.
|
|
15
|
+
|
|
16
|
+
## What changed
|
|
17
|
+
|
|
18
|
+
- **Saved work on the map.** Places, captures and filed screenshots can be
|
|
19
|
+
browsed by geography or case folder, searched in English or the local name,
|
|
20
|
+
previewed and shown on the map. Proofs appear at their own coordinates or at
|
|
21
|
+
the captures they use.
|
|
22
|
+
- **Case organisation.** The sidebar adds search, type and status filters,
|
|
23
|
+
multi-select filing and a details drawer. Files adds Small, Large and List
|
|
24
|
+
views with sortable columns and complete folder browsing.
|
|
25
|
+
- **Named work.** Inspect, Geo Proof and Geo Report name their documents in the
|
|
26
|
+
header and keep that name when saved or renamed. Inspect's save dialog can
|
|
27
|
+
name a batch and attach one note.
|
|
28
|
+
- **Faster browsing.** Media and Files now query a SQLite browse index. Search,
|
|
29
|
+
folder filters and Media category counts cover the complete case instead of
|
|
30
|
+
only the first 200 items. Files requests thumbnail metadata only for paths it
|
|
31
|
+
can display.
|
|
32
|
+
- **Better pickers and proofs.** Inspect, Reverse Search, Geo Proof and Notebook
|
|
33
|
+
pickers can search and browse folders. Geo Proof supports coloured panel
|
|
34
|
+
frames, layer controls and pasted overlays stored with that proof.
|
|
35
|
+
- **Capture extension.** A map point can be saved as a place, and any page can
|
|
36
|
+
be saved as a bookmark. Map captures keep their source metadata and
|
|
37
|
+
attribution.
|
|
38
|
+
- **Case-switch fix.** Saved Satellite items and Media thumbnail state are
|
|
39
|
+
cleared before a different case loads, so data from the previous case no
|
|
40
|
+
longer remains until refresh.
|
|
41
|
+
- **Release and security hardening.** Release builds use pinned, SHA-256-checked
|
|
42
|
+
ffmpeg archives and extract only the expected tools. Images above 100 MP are
|
|
43
|
+
rejected before decode. SQLite schema 4 adds the media browse index and
|
|
44
|
+
upgrades existing cases automatically.
|
|
45
|
+
|
|
46
|
+
The read-only GitHub release check still runs on startup by default. It can be
|
|
47
|
+
disabled in Settings, and offline failures remain silent.
|
|
48
|
+
|
|
49
|
+
## Install or upgrade
|
|
50
|
+
|
|
51
|
+
Download the ready-to-run asset for Windows x86_64, Linux x86_64 or Apple
|
|
52
|
+
Silicon macOS and run it. Each binary includes the browser UI, `ffmpeg` and
|
|
53
|
+
`ffprobe`; no Python or system FFmpeg is needed.
|
|
54
|
+
|
|
55
|
+
Intel Macs require macOS 14 or newer and the Python package:
|
|
56
|
+
`pipx install azimut` or `pip install azimut`.
|
|
57
|
+
|
|
58
|
+
The binaries are unsigned. Follow the operating system prompt described in the
|
|
59
|
+
README on first launch.
|
|
60
|
+
|
|
61
|
+
Existing cases upgrade in place. No manual export or import is required.
|