setiastrosuitepro 1.6.8__tar.gz → 1.6.9__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.

Potentially problematic release.


This version of setiastrosuitepro might be problematic. Click here for more details.

Files changed (396) hide show
  1. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/PKG-INFO +1 -1
  2. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/pyproject.toml +1 -1
  3. setiastrosuitepro-1.6.9/src/setiastro/saspro/_generated/build_info.py +3 -0
  4. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/blink_comparator_pro.py +83 -46
  5. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/crop_dialog_pro.py +96 -2
  6. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/curve_editor_pro.py +60 -39
  7. setiastrosuitepro-1.6.9/src/setiastro/saspro/frequency_separation.py +2303 -0
  8. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/main_window.py +112 -19
  9. setiastrosuitepro-1.6.9/src/setiastro/saspro/imageops/stretch.py +707 -0
  10. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/legacy/numba_utils.py +43 -0
  11. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/multiscale_decomp.py +47 -12
  12. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/numba_utils.py +72 -2
  13. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/shortcuts.py +122 -12
  14. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/stat_stretch.py +408 -82
  15. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/subwindow.py +156 -50
  16. setiastrosuitepro-1.6.8/src/setiastro/saspro/_generated/build_info.py +0 -3
  17. setiastrosuitepro-1.6.8/src/setiastro/saspro/frequency_separation.py +0 -1352
  18. setiastrosuitepro-1.6.8/src/setiastro/saspro/imageops/stretch.py +0 -236
  19. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/LICENSE +0 -0
  20. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/README.md +0 -0
  21. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/license.txt +0 -0
  22. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/__init__.py +0 -0
  23. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/SASP_data.fits +0 -0
  24. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/List_of_Galaxies_with_Distances_Gly.csv +0 -0
  25. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/astrobin_filters.csv +0 -0
  26. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/astrobin_filters_page1_local.csv +0 -0
  27. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/cali2.csv +0 -0
  28. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/cali2color.csv +0 -0
  29. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/celestial_catalog - original.csv +0 -0
  30. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/celestial_catalog.csv +0 -0
  31. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/detected_stars.csv +0 -0
  32. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/fits_header_data.csv +0 -0
  33. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/test.csv +0 -0
  34. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/data/catalogs/updated_celestial_catalog.csv +0 -0
  35. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/Astro_Spikes.png +0 -0
  36. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/Background_startup.jpg +0 -0
  37. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/HRDiagram.png +0 -0
  38. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/LExtract.png +0 -0
  39. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/LInsert.png +0 -0
  40. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/Oxygenation-atm-2.svg.png +0 -0
  41. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/RGB080604.png +0 -0
  42. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/abeicon.png +0 -0
  43. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/aberration.png +0 -0
  44. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/acv_icon.png +0 -0
  45. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/andromedatry.png +0 -0
  46. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/andromedatry_satellited.png +0 -0
  47. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/annotated.png +0 -0
  48. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/aperture.png +0 -0
  49. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/astrosuite.ico +0 -0
  50. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/astrosuite.png +0 -0
  51. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/astrosuitepro.icns +0 -0
  52. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/astrosuitepro.ico +0 -0
  53. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/astrosuitepro.png +0 -0
  54. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/background.png +0 -0
  55. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/background2.png +0 -0
  56. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/benchmark.png +0 -0
  57. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/big_moon_stabilizer_timeline.png +0 -0
  58. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/big_moon_stabilizer_timeline_clean.png +0 -0
  59. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/blaster.png +0 -0
  60. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/blink.png +0 -0
  61. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/clahe.png +0 -0
  62. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/collage.png +0 -0
  63. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/colorwheel.png +0 -0
  64. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/contsub.png +0 -0
  65. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/convo.png +0 -0
  66. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/copyslot.png +0 -0
  67. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/cosmic.png +0 -0
  68. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/cosmicsat.png +0 -0
  69. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/crop1.png +0 -0
  70. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/cropicon.png +0 -0
  71. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/curves.png +0 -0
  72. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/cvs.png +0 -0
  73. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/debayer.png +0 -0
  74. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/denoise_cnn_custom.png +0 -0
  75. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/denoise_cnn_graph.png +0 -0
  76. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/disk.png +0 -0
  77. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/dse.png +0 -0
  78. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/exoicon.png +0 -0
  79. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/eye.png +0 -0
  80. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/first_quarter.png +0 -0
  81. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/fliphorizontal.png +0 -0
  82. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/flipvertical.png +0 -0
  83. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/font.png +0 -0
  84. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/freqsep.png +0 -0
  85. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/full_moon.png +0 -0
  86. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/functionbundle.png +0 -0
  87. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/graxpert.png +0 -0
  88. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/green.png +0 -0
  89. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/gridicon.png +0 -0
  90. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/halo.png +0 -0
  91. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/hdr.png +0 -0
  92. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/histogram.png +0 -0
  93. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/hubble.png +0 -0
  94. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/imagecombine.png +0 -0
  95. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/invert.png +0 -0
  96. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/isophote.png +0 -0
  97. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/isophote_demo_figure.png +0 -0
  98. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/isophote_demo_image.png +0 -0
  99. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/isophote_demo_model.png +0 -0
  100. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/isophote_demo_residual.png +0 -0
  101. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/jwstpupil.png +0 -0
  102. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/last_quarter.png +0 -0
  103. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/linearfit.png +0 -0
  104. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/livestacking.png +0 -0
  105. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/mask.png +0 -0
  106. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/maskapply.png +0 -0
  107. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/maskcreate.png +0 -0
  108. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/maskremove.png +0 -0
  109. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/morpho.png +0 -0
  110. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/mosaic.png +0 -0
  111. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/multiscale_decomp.png +0 -0
  112. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/nbtorgb.png +0 -0
  113. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/neutral.png +0 -0
  114. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/new_moon.png +0 -0
  115. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/nuke.png +0 -0
  116. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/openfile.png +0 -0
  117. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/pedestal.png +0 -0
  118. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/pen.png +0 -0
  119. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/pixelmath.png +0 -0
  120. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/platesolve.png +0 -0
  121. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/ppp.png +0 -0
  122. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/pro.png +0 -0
  123. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/project.png +0 -0
  124. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/psf.png +0 -0
  125. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/redo.png +0 -0
  126. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/redoicon.png +0 -0
  127. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rescale.png +0 -0
  128. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rgbalign.png +0 -0
  129. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rgbcombo.png +0 -0
  130. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rgbextract.png +0 -0
  131. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rotate180.png +0 -0
  132. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rotatearbitrary.png +0 -0
  133. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rotateclockwise.png +0 -0
  134. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/rotatecounterclockwise.png +0 -0
  135. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/satellite.png +0 -0
  136. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/script.png +0 -0
  137. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/selectivecolor.png +0 -0
  138. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/simbad.png +0 -0
  139. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot0.png +0 -0
  140. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot1.png +0 -0
  141. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot2.png +0 -0
  142. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot3.png +0 -0
  143. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot4.png +0 -0
  144. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot5.png +0 -0
  145. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot6.png +0 -0
  146. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot7.png +0 -0
  147. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot8.png +0 -0
  148. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/slot9.png +0 -0
  149. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/spcc.png +0 -0
  150. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/spin_precession_vs_lunar_distance.png +0 -0
  151. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/spinner.gif +0 -0
  152. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/stacking.png +0 -0
  153. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/staradd.png +0 -0
  154. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/staralign.png +0 -0
  155. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/starnet.png +0 -0
  156. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/starregistration.png +0 -0
  157. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/starspike.png +0 -0
  158. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/starstretch.png +0 -0
  159. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/statstretch.png +0 -0
  160. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/supernova.png +0 -0
  161. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/uhs.png +0 -0
  162. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/undoicon.png +0 -0
  163. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/upscale.png +0 -0
  164. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/viewbundle.png +0 -0
  165. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_crescent_1.png +0 -0
  166. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_crescent_2.png +0 -0
  167. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_crescent_3.png +0 -0
  168. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_crescent_4.png +0 -0
  169. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_crescent_5.png +0 -0
  170. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_gibbous_1.png +0 -0
  171. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_gibbous_2.png +0 -0
  172. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_gibbous_3.png +0 -0
  173. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_gibbous_4.png +0 -0
  174. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waning_gibbous_5.png +0 -0
  175. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_crescent_1.png +0 -0
  176. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_crescent_2.png +0 -0
  177. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_crescent_3.png +0 -0
  178. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_crescent_4.png +0 -0
  179. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_crescent_5.png +0 -0
  180. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_gibbous_1.png +0 -0
  181. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_gibbous_2.png +0 -0
  182. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_gibbous_3.png +0 -0
  183. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_gibbous_4.png +0 -0
  184. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/waxing_gibbous_5.png +0 -0
  185. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/whitebalance.png +0 -0
  186. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/wimi_icon_256x256.png +0 -0
  187. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/wimilogo.png +0 -0
  188. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/wims.png +0 -0
  189. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/wrench_icon.png +0 -0
  190. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/images/xisfliberator.png +0 -0
  191. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/qml/ResourceMonitor.qml +0 -0
  192. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/__init__.py +0 -0
  193. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/__main__.py +0 -0
  194. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/_generated/__init__.py +0 -0
  195. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/abe.py +0 -0
  196. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/abe_preset.py +0 -0
  197. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/aberration_ai.py +0 -0
  198. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/aberration_ai_preset.py +0 -0
  199. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/accel_installer.py +0 -0
  200. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/accel_workers.py +0 -0
  201. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/acv_exporter.py +0 -0
  202. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/add_stars.py +0 -0
  203. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/astrobin_exporter.py +0 -0
  204. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/astrospike.py +0 -0
  205. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/astrospike_python.py +0 -0
  206. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/autostretch.py +0 -0
  207. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/backgroundneutral.py +0 -0
  208. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/batch_convert.py +0 -0
  209. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/batch_renamer.py +0 -0
  210. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/blemish_blaster.py +0 -0
  211. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/bundles.py +0 -0
  212. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/bundles_dock.py +0 -0
  213. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/cheat_sheet.py +0 -0
  214. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/clahe.py +0 -0
  215. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/comet_stacking.py +0 -0
  216. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/common_tr.py +0 -0
  217. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/config.py +0 -0
  218. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/config_bootstrap.py +0 -0
  219. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/config_manager.py +0 -0
  220. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/continuum_subtract.py +0 -0
  221. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/convo.py +0 -0
  222. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/convo_preset.py +0 -0
  223. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/copyastro.py +0 -0
  224. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/cosmicclarity.py +0 -0
  225. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/cosmicclarity_preset.py +0 -0
  226. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/crop_preset.py +0 -0
  227. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/curves_preset.py +0 -0
  228. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/debayer.py +0 -0
  229. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/debug_utils.py +0 -0
  230. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/dnd_mime.py +0 -0
  231. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/doc_manager.py +0 -0
  232. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/exoplanet_detector.py +0 -0
  233. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/file_utils.py +0 -0
  234. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/fitsmodifier.py +0 -0
  235. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/fix_bom.py +0 -0
  236. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/free_torch_memory.py +0 -0
  237. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/function_bundle.py +0 -0
  238. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/generate_translations.py +0 -0
  239. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ghs_dialog_pro.py +0 -0
  240. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ghs_preset.py +0 -0
  241. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/graxpert.py +0 -0
  242. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/graxpert_preset.py +0 -0
  243. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/__init__.py +0 -0
  244. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/__init__.py +0 -0
  245. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/dock_mixin.py +0 -0
  246. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/file_mixin.py +0 -0
  247. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/geometry_mixin.py +0 -0
  248. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/header_mixin.py +0 -0
  249. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/mask_mixin.py +0 -0
  250. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/menu_mixin.py +0 -0
  251. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/theme_mixin.py +0 -0
  252. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/toolbar_mixin.py +0 -0
  253. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/update_mixin.py +0 -0
  254. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/mixins/view_mixin.py +0 -0
  255. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/gui/statistics_dialog.py +0 -0
  256. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/halobgon.py +0 -0
  257. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/header_viewer.py +0 -0
  258. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/headless_utils.py +0 -0
  259. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/histogram.py +0 -0
  260. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/history_explorer.py +0 -0
  261. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/i18n.py +0 -0
  262. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/image_combine.py +0 -0
  263. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/image_peeker_pro.py +0 -0
  264. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/imageops/__init__.py +0 -0
  265. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/imageops/mdi_snap.py +0 -0
  266. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/imageops/scnr.py +0 -0
  267. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/imageops/starbasedwhitebalance.py +0 -0
  268. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/isophote.py +0 -0
  269. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/layers.py +0 -0
  270. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/layers_dock.py +0 -0
  271. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/lazy_imports.py +0 -0
  272. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/legacy/__init__.py +0 -0
  273. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/legacy/image_manager.py +0 -0
  274. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/legacy/xisf.py +0 -0
  275. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/linear_fit.py +0 -0
  276. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/live_stacking.py +0 -0
  277. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/log_bus.py +0 -0
  278. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/logging_config.py +0 -0
  279. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/luminancerecombine.py +0 -0
  280. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/main_helpers.py +0 -0
  281. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/mask_creation.py +0 -0
  282. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/masks_core.py +0 -0
  283. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/mdi_widgets.py +0 -0
  284. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/memory_utils.py +0 -0
  285. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/metadata_patcher.py +0 -0
  286. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/mfdeconv.py +0 -0
  287. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/mfdeconv_earlystop.py +0 -0
  288. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/mfdeconvcudnn.py +0 -0
  289. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/mfdeconvsport.py +0 -0
  290. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/minorbodycatalog.py +0 -0
  291. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/morphology.py +0 -0
  292. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/nbtorgb_stars.py +0 -0
  293. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/numba_warmup.py +0 -0
  294. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/__init__.py +0 -0
  295. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/command_help_dialog.py +0 -0
  296. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/command_runner.py +0 -0
  297. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/commands.py +0 -0
  298. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/script_editor.py +0 -0
  299. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/scripts.py +0 -0
  300. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/ops/settings.py +0 -0
  301. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/parallel_utils.py +0 -0
  302. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/pedestal.py +0 -0
  303. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/perfect_palette_picker.py +0 -0
  304. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/pipeline.py +0 -0
  305. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/pixelmath.py +0 -0
  306. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/plate_solver.py +0 -0
  307. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/project_io.py +0 -0
  308. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/psf_utils.py +0 -0
  309. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/psf_viewer.py +0 -0
  310. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/pyi_rthook_astroquery.py +0 -0
  311. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/remove_green.py +0 -0
  312. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/remove_stars.py +0 -0
  313. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/remove_stars_preset.py +0 -0
  314. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/resources.py +0 -0
  315. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/rgb_combination.py +0 -0
  316. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/rgb_extract.py +0 -0
  317. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/rgbalign.py +0 -0
  318. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/runtime_imports.py +0 -0
  319. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/runtime_torch.py +0 -0
  320. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/save_options.py +0 -0
  321. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/selective_color.py +0 -0
  322. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/sfcc.py +0 -0
  323. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/signature_insert.py +0 -0
  324. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/stacking_suite.py +0 -0
  325. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/star_alignment.py +0 -0
  326. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/star_alignment_preset.py +0 -0
  327. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/star_metrics.py +0 -0
  328. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/star_spikes.py +0 -0
  329. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/star_stretch.py +0 -0
  330. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/status_log_dock.py +0 -0
  331. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/supernovaasteroidhunter.py +0 -0
  332. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/swap_manager.py +0 -0
  333. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/torch_backend.py +0 -0
  334. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/torch_rejection.py +0 -0
  335. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/all_source_strings.json +0 -0
  336. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/ar_translations.py +0 -0
  337. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/de_translations.py +0 -0
  338. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/es_translations.py +0 -0
  339. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/fr_translations.py +0 -0
  340. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/hi_translations.py +0 -0
  341. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/integrate_translations.py +0 -0
  342. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/it_translations.py +0 -0
  343. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/ja_translations.py +0 -0
  344. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/pt_translations.py +0 -0
  345. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/ru_translations.py +0 -0
  346. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_ar.qm +0 -0
  347. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_ar.ts +0 -0
  348. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_de.qm +0 -0
  349. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_de.ts +0 -0
  350. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_es.qm +0 -0
  351. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_es.ts +0 -0
  352. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_fr.qm +0 -0
  353. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_fr.ts +0 -0
  354. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_hi.qm +0 -0
  355. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_hi.ts +0 -0
  356. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_it.qm +0 -0
  357. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_it.ts +0 -0
  358. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_ja.qm +0 -0
  359. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_ja.ts +0 -0
  360. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_pt.qm +0 -0
  361. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_pt.ts +0 -0
  362. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_ru.qm +0 -0
  363. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_ru.ts +0 -0
  364. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_sw.qm +0 -0
  365. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_sw.ts +0 -0
  366. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_uk.qm +0 -0
  367. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_uk.ts +0 -0
  368. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_zh.qm +0 -0
  369. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/saspro_zh.ts +0 -0
  370. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/sw_translations.py +0 -0
  371. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/uk_translations.py +0 -0
  372. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/translations/zh_translations.py +0 -0
  373. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/versioning.py +0 -0
  374. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/view_bundle.py +0 -0
  375. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wavescale_hdr.py +0 -0
  376. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wavescale_hdr_preset.py +0 -0
  377. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wavescalede.py +0 -0
  378. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wavescalede_preset.py +0 -0
  379. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wcs_update.py +0 -0
  380. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/whitebalance.py +0 -0
  381. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/__init__.py +0 -0
  382. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/common_utilities.py +0 -0
  383. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/graphics_views.py +0 -0
  384. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/image_utils.py +0 -0
  385. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/minigame/game.js +0 -0
  386. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/minigame/index.html +0 -0
  387. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/minigame/style.css +0 -0
  388. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/preview_dialogs.py +0 -0
  389. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/resource_monitor.py +0 -0
  390. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/spinboxes.py +0 -0
  391. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/themed_buttons.py +0 -0
  392. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/widgets/wavelet_utils.py +0 -0
  393. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wimi.py +0 -0
  394. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/wims.py +0 -0
  395. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/window_shelf.py +0 -0
  396. {setiastrosuitepro-1.6.8 → setiastrosuitepro-1.6.9}/src/setiastro/saspro/xisf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: setiastrosuitepro
3
- Version: 1.6.8
3
+ Version: 1.6.9
4
4
  Summary: Seti Astro Suite Pro - Advanced astrophotography toolkit for image calibration, stacking, registration, photometry, and visualization
5
5
  License: GPL-3.0
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "setiastrosuitepro"
3
- version = "1.6.8"
3
+ version = "1.6.9"
4
4
  description = "Seti Astro Suite Pro - Advanced astrophotography toolkit for image calibration, stacking, registration, photometry, and visualization"
5
5
  authors = ["Franklin Marek <info@setiastro.com>"]
6
6
  readme = "README.md"
@@ -0,0 +1,3 @@
1
+ # Auto-generated at build time. Do not edit.
2
+ BUILD_TIMESTAMP = "2026-01-02T21:35:46Z"
3
+ APP_VERSION = "1.6.9"
@@ -150,7 +150,6 @@ class MetricsPanel(QWidget):
150
150
  orig_back = entry.get('orig_background', np.nan)
151
151
  return idx, fwhm, ecc, orig_back, star_cnt
152
152
 
153
-
154
153
  def compute_all_metrics(self, loaded_images) -> bool:
155
154
  """Run SEP over the full list in parallel using threads and cache results.
156
155
  Returns True if metrics were computed, False if user declined/canceled.
@@ -163,71 +162,109 @@ class MetricsPanel(QWidget):
163
162
  self._threshold_initialized = [False] * 4
164
163
  return True
165
164
 
165
+ def _has_metrics(md):
166
+ try:
167
+ return md is not None and len(md) == 4 and md[0] is not None and len(md[0]) > 0
168
+ except Exception:
169
+ return False
170
+
166
171
  settings = QSettings()
167
- show = settings.value("metrics/showWarning", True, type=bool)
168
- if show:
172
+ show_warning = settings.value("metrics/showWarning", True, type=bool)
173
+
174
+ if (not show_warning) and (not _has_metrics(getattr(self, "metrics_data", None))):
175
+ settings.setValue("metrics/showWarning", True)
176
+ show_warning = True
177
+
178
+ # ----------------------------
179
+ # 1) Optional warning gate
180
+ # ----------------------------
181
+ if show_warning:
169
182
  msg = QMessageBox(self)
170
183
  msg.setWindowTitle(self.tr("Heads-up"))
171
184
  msg.setText(self.tr(
172
185
  "This is going to use ALL your CPU cores and the UI may lock up until it finishes.\n\n"
173
186
  "Continue?"
174
187
  ))
175
- msg.setStandardButtons(QMessageBox.StandardButton.Yes |
176
- QMessageBox.StandardButton.No)
188
+ msg.setStandardButtons(
189
+ QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
190
+ )
177
191
  cb = QCheckBox(self.tr("Don't show again"), msg)
178
192
  msg.setCheckBox(cb)
179
193
 
180
- if msg.exec() != QMessageBox.StandardButton.Yes:
181
- # IMPORTANT: leave caches alone; caller (plot) will clear/return
194
+ clicked = msg.exec()
195
+ clicked_yes = (clicked == QMessageBox.StandardButton.Yes)
196
+
197
+ if not clicked_yes:
198
+ # If they said NO, never allow "Don't show again" to lock them out.
199
+ # Keep the warning enabled so they can opt-in later.
200
+ if cb.isChecked():
201
+ settings.setValue("metrics/showWarning", True)
182
202
  return False
183
203
 
204
+ # They said YES: now it's safe to honor "Don't show again"
184
205
  if cb.isChecked():
185
206
  settings.setValue("metrics/showWarning", False)
186
207
 
187
- # pre-allocate result arrays
188
- m0 = np.full(n, np.nan, dtype=np.float32) # FWHM
189
- m1 = np.full(n, np.nan, dtype=np.float32) # Eccentricity
190
- m2 = np.full(n, np.nan, dtype=np.float32) # Background (cached)
191
- m3 = np.full(n, np.nan, dtype=np.float32) # Star count
192
- flags = [e.get('flagged', False) for e in loaded_images]
193
-
194
- # progress dialog
195
- prog = QProgressDialog(self.tr("Computing frame metrics…"), self.tr("Cancel"), 0, n, self)
196
- prog.setWindowModality(Qt.WindowModality.WindowModal)
197
- prog.setMinimumDuration(0)
198
- prog.setValue(0)
199
- prog.show()
200
- QApplication.processEvents()
208
+ # If show_warning is False, we compute with no prompt.
209
+
210
+ # ----------------------------
211
+ # 2) Allocate result arrays
212
+ # ----------------------------
213
+ m0 = np.full(n, np.nan, dtype=np.float32) # FWHM
214
+ m1 = np.full(n, np.nan, dtype=np.float32) # Eccentricity
215
+ m2 = np.full(n, np.nan, dtype=np.float32) # Background (cached)
216
+ m3 = np.full(n, np.nan, dtype=np.float32) # Star count
217
+ flags = [e.get('flagged', False) for e in loaded_images]
218
+
219
+ # ----------------------------
220
+ # 3) Progress dialog
221
+ # ----------------------------
222
+ prog = QProgressDialog(self.tr("Computing frame metrics…"), self.tr("Cancel"), 0, n, self)
223
+ prog.setWindowModality(Qt.WindowModality.WindowModal)
224
+ prog.setMinimumDuration(0)
225
+ prog.setValue(0)
226
+ prog.show()
227
+ QApplication.processEvents()
201
228
 
202
- workers = min(os.cpu_count() or 1, 60)
203
- tasks = [(i, loaded_images[i]) for i in range(n)]
204
- done = 0 # <-- FIX: initialize before incrementing
229
+ workers = min(os.cpu_count() or 1, 60)
230
+ tasks = [(i, loaded_images[i]) for i in range(n)]
231
+ done = 0
232
+ canceled = False
205
233
 
206
- try:
207
- with ThreadPoolExecutor(max_workers=workers) as exe:
208
- futures = {exe.submit(self._compute_one, t): t[0] for t in tasks}
209
- for fut in as_completed(futures):
210
- if prog.wasCanceled():
211
- break
212
- try:
213
- idx, fwhm, ecc, orig_back, star_cnt = fut.result()
214
- except Exception:
215
- # On failure, leave NaNs/sentinels and continue
216
- idx, fwhm, ecc, orig_back, star_cnt = futures[fut], np.nan, np.nan, np.nan, 0
234
+ try:
235
+ with ThreadPoolExecutor(max_workers=workers) as exe:
236
+ futures = {exe.submit(self._compute_one, t): t[0] for t in tasks}
237
+ for fut in as_completed(futures):
238
+ if prog.wasCanceled():
239
+ canceled = True
240
+ break
241
+ try:
242
+ idx, fwhm, ecc, orig_back, star_cnt = fut.result()
243
+ except Exception:
244
+ idx = futures.get(fut, 0)
245
+ fwhm, ecc, orig_back, star_cnt = np.nan, np.nan, np.nan, 0
246
+
247
+ if 0 <= idx < n:
217
248
  m0[idx], m1[idx], m2[idx], m3[idx] = fwhm, ecc, orig_back, float(star_cnt)
218
- done += 1
219
- prog.setValue(done)
220
- QApplication.processEvents()
221
- finally:
222
- prog.close()
223
249
 
224
- # stash results
225
- self._orig_images = loaded_images
226
- self.metrics_data = [m0, m1, m2, m3]
227
- self.flags = flags
228
- self._threshold_initialized = [False] * 4
229
- return True
250
+ done += 1
251
+ prog.setValue(done)
252
+ QApplication.processEvents()
253
+ finally:
254
+ prog.close()
255
+
256
+ if canceled:
257
+ # IMPORTANT: leave caches alone; caller will clear/return
258
+ return False
230
259
 
260
+ # ----------------------------
261
+ # 4) Stash results
262
+ # ----------------------------
263
+ self._orig_images = loaded_images
264
+ self.metrics_data = [m0, m1, m2, m3]
265
+ self.flags = flags
266
+ self._threshold_initialized = [False] * 4
267
+ return True
231
268
 
232
269
  def plot(self, loaded_images, indices=None):
233
270
  """
@@ -58,7 +58,8 @@ class ResizableRotatableRectItem(QGraphicsRectItem):
58
58
  self._rotating = False
59
59
  self._angle0 = 0.0
60
60
  self._pivot_scene = QPointF()
61
-
61
+ self._bounds_scene: QRectF | None = None
62
+ self._clamp_eps_deg = 0.25 # treat as "unrotated" if |angle| < eps (deg)
62
63
  self._grab_pad = 20 # ← extra hit slop in screen px
63
64
  self._edge_pad_px = EDGE_GRAB_PX
64
65
  self.setZValue(100) # ← keep above pixmap
@@ -83,7 +84,26 @@ class ResizableRotatableRectItem(QGraphicsRectItem):
83
84
  dx = p1.x() - p0.x()
84
85
  dy = p1.y() - p0.y()
85
86
  return math.hypot(dx, dy)
86
-
87
+ def setBoundsSceneRect(self, r: QRectF | None):
88
+ """Set the scene-rect bounds we should stay within when unrotated."""
89
+ self._bounds_scene = QRectF(r) if r is not None else None
90
+
91
+ def _is_unrotated(self) -> bool:
92
+ # normalize angle to [-180, 180]
93
+ a = float(self.rotation()) % 360.0
94
+ if a > 180.0:
95
+ a -= 360.0
96
+ return abs(a) < self._clamp_eps_deg
97
+
98
+ def _bounds_local(self) -> QRectF | None:
99
+ """Bounds rect mapped into the item's local coordinates (only valid when unrotated)."""
100
+ if self._bounds_scene is None:
101
+ return None
102
+ # When unrotated, this is safe and stable.
103
+ tl = self.mapFromScene(self._bounds_scene.topLeft())
104
+ br = self.mapFromScene(self._bounds_scene.bottomRight())
105
+ return QRectF(tl, br).normalized()
106
+
87
107
  def _edge_under_cursor(self, scene_pos: QPointF) -> Optional[str]:
88
108
  """
89
109
  Return 'l', 'r', 't', or 'b' if the pointer is near an edge (within px-tolerance),
@@ -218,12 +238,52 @@ class ResizableRotatableRectItem(QGraphicsRectItem):
218
238
  QGraphicsItem.GraphicsItemChange.ItemTransformHasChanged,
219
239
  ):
220
240
  self._sync_handles()
241
+
242
+ if change == QGraphicsItem.GraphicsItemChange.ItemPositionChange:
243
+ if self._bounds_scene is not None and self._is_unrotated():
244
+ new_pos = QPointF(value)
245
+
246
+ # current scene rect of the item (at current pos)
247
+ sr0 = self.mapRectToScene(self.rect()) # QRectF in scene coords
248
+
249
+ # shift it by the delta between proposed pos and current pos
250
+ d = new_pos - self.pos()
251
+ sr = sr0.translated(d)
252
+
253
+ b = self._bounds_scene
254
+ dx = 0.0
255
+ dy = 0.0
256
+
257
+ if sr.left() < b.left():
258
+ dx = b.left() - sr.left()
259
+ elif sr.right() > b.right():
260
+ dx = b.right() - sr.right()
261
+
262
+ if sr.top() < b.top():
263
+ dy = b.top() - sr.top()
264
+ elif sr.bottom() > b.bottom():
265
+ dy = b.bottom() - sr.bottom()
266
+
267
+ if dx != 0.0 or dy != 0.0:
268
+ return new_pos + QPointF(dx, dy)
269
+
270
+ return new_pos
271
+
221
272
  return super().itemChange(change, value)
222
273
 
223
274
  def _resize_via_handle(self, scene_pt: QPointF):
224
275
  r = self.rect()
225
276
  p = self.mapFromScene(scene_pt)
226
277
 
278
+ # Clamp handle drag to bounds only when unrotated.
279
+ if self._bounds_scene is not None and self._is_unrotated():
280
+ bL = self._bounds_local()
281
+ if bL is not None:
282
+ # NOTE: bL is in the same local coordinate space as r/p.
283
+ px = min(max(p.x(), bL.left()), bL.right())
284
+ py = min(max(p.y(), bL.top()), bL.bottom())
285
+ p = QPointF(px, py)
286
+
227
287
  # Corners
228
288
  if self._active == "tl": r.setTopLeft(p)
229
289
  elif self._active == "tr": r.setTopRight(p)
@@ -616,6 +676,7 @@ class CropDialogPro(QDialog):
616
676
  if e.type() == QEvent.Type.MouseMove and self._drawing:
617
677
  r = QRectF(self._origin, scene_pt).normalized()
618
678
  r = self._apply_ar_to_rect(r, live=True, scene_pt=scene_pt)
679
+ r = self._clamp_rect_to_pixmap(r)
619
680
  self._draw_live_rect(r)
620
681
 
621
682
  # ⬇️ live dims from the temporary rect (axis-aligned TL,TR,BR,BL)
@@ -627,9 +688,12 @@ class CropDialogPro(QDialog):
627
688
  self._drawing = False
628
689
  r = QRectF(self._origin, scene_pt).normalized()
629
690
  r = self._apply_ar_to_rect(r, live=False, scene_pt=scene_pt)
691
+ r = self._clamp_rect_to_pixmap(r)
630
692
  self._clear_live_rect()
693
+
631
694
  self._rect_item = ResizableRotatableRectItem(r)
632
695
  self._rect_item.setZValue(10)
696
+ self._rect_item.setBoundsSceneRect(self._bounds_scene_rect())
633
697
  self._rect_item.setFixedAspectRatio(self._current_ar_value())
634
698
  self.scene.addItem(self._rect_item)
635
699
 
@@ -715,6 +779,7 @@ class CropDialogPro(QDialog):
715
779
  if self._rect_item is None:
716
780
  self._rect_item = ResizableRotatableRectItem(r)
717
781
  self._rect_item.setZValue(10)
782
+ self._rect_item.setBoundsSceneRect(self._bounds_scene_rect())
718
783
  self.scene.addItem(self._rect_item)
719
784
  else:
720
785
  self._rect_item.setRotation(0.0)
@@ -758,6 +823,32 @@ class CropDialogPro(QDialog):
758
823
  if hasattr(self, "_live_rect") and self._live_rect:
759
824
  self.scene.removeItem(self._live_rect); self._live_rect = None
760
825
 
826
+ def _pixmap_scene_rect(self) -> QRectF | None:
827
+ """Scene rect occupied by the pixmap (image) item."""
828
+ if not self._pix_item:
829
+ return None
830
+ return self._pix_item.mapRectToScene(self._pix_item.boundingRect())
831
+
832
+ def _clamp_rect_to_pixmap(self, r: QRectF) -> QRectF:
833
+ """Intersect an axis-aligned QRectF with the pixmap scene rect."""
834
+ bounds = self._pixmap_scene_rect()
835
+ if bounds is None:
836
+ return r.normalized()
837
+ rr = r.normalized().intersected(bounds)
838
+ # avoid empty rects (keep at least 1x1 scene unit)
839
+ if rr.isNull() or rr.width() <= 1e-6 or rr.height() <= 1e-6:
840
+ # fallback: clamp to a 1x1 rect at the nearest point inside bounds
841
+ x = min(max(r.center().x(), bounds.left()), bounds.right())
842
+ y = min(max(r.center().y(), bounds.top()), bounds.bottom())
843
+ rr = QRectF(x, y, 1.0, 1.0)
844
+ return rr.normalized()
845
+
846
+ def _bounds_scene_rect(self) -> QRectF | None:
847
+ if not self._pix_item:
848
+ return None
849
+ return self._pix_item.mapRectToScene(self._pix_item.boundingRect())
850
+
851
+
761
852
  # ---------- preview toggles ----------
762
853
  def _toggle_autostretch(self):
763
854
  self._autostretch_on = not self._autostretch_on
@@ -777,6 +868,7 @@ class CropDialogPro(QDialog):
777
868
  r, ang, pos = state
778
869
  self._rect_item = ResizableRotatableRectItem(r)
779
870
  self._rect_item.setZValue(10)
871
+ self._rect_item.setBoundsSceneRect(self._bounds_scene_rect())
780
872
  self._rect_item.setFixedAspectRatio(self._current_ar_value())
781
873
  self._rect_item.setRotation(ang)
782
874
  self._rect_item.setPos(pos)
@@ -794,6 +886,7 @@ class CropDialogPro(QDialog):
794
886
  r = QRectF(CropDialogPro._prev_rect)
795
887
  self._rect_item = ResizableRotatableRectItem(r)
796
888
  self._rect_item.setZValue(10)
889
+ self._rect_item.setBoundsSceneRect(self._bounds_scene_rect())
797
890
  self._rect_item.setFixedAspectRatio(self._current_ar_value())
798
891
  self._rect_item.setRotation(CropDialogPro._prev_angle)
799
892
  self._rect_item.setPos(CropDialogPro._prev_pos)
@@ -812,6 +905,7 @@ class CropDialogPro(QDialog):
812
905
  sx, sy = w_img / pm.width(), h_img / pm.height()
813
906
  return np.array([pt_scene.x() * sx, pt_scene.y() * sy], dtype=np.float32)
814
907
 
908
+
815
909
  def _apply_one(self):
816
910
  if not self._rect_item:
817
911
  QMessageBox.warning(self, self.tr("No Selection"), self.tr("Draw & finalize a crop first."))
@@ -521,32 +521,6 @@ class CurveEditor(QGraphicsView):
521
521
  if ln is not None:
522
522
  ln.setVisible(False)
523
523
 
524
- def _scene_to_norm_points(self, pts_scene: list[tuple[float,float]]) -> list[tuple[float,float]]:
525
- """(x:[0..360], y:[0..360] down) → (x,y in [0..1] up). Ensures endpoints present & strictly increasing x."""
526
- out = []
527
- lastx = -1e9
528
- for (x, y) in sorted(pts_scene, key=lambda t: t[0]):
529
- x = float(np.clip(x, 0.0, 360.0))
530
- y = float(np.clip(y, 0.0, 360.0))
531
- # strictly increasing X
532
- if x <= lastx:
533
- x = lastx + 1e-3
534
- lastx = x
535
- out.append((x / 360.0, 1.0 - (y / 360.0)))
536
- # ensure endpoints
537
- if not any(abs(px - 0.0) < 1e-6 for px, _ in out): out.insert(0, (0.0, 0.0))
538
- if not any(abs(px - 1.0) < 1e-6 for px, _ in out): out.append((1.0, 1.0))
539
- # clamp
540
- return [(float(np.clip(x,0,1)), float(np.clip(y,0,1))) for (x,y) in out]
541
-
542
- def _collect_points_norm_from_editor(self) -> list[tuple[float,float]]:
543
- """Take endpoints+handles from editor => normalized points."""
544
- pts_scene = []
545
- for p in (self.editor.end_points + self.editor.control_points):
546
- pos = p.scenePos()
547
- pts_scene.append((float(pos.x()), float(pos.y())))
548
- return self._scene_to_norm_points(pts_scene)
549
-
550
524
 
551
525
  def redistributeHandlesByPivot(self, u: float):
552
526
  """
@@ -1048,7 +1022,14 @@ class CurvesDialogPro(QDialog):
1048
1022
  self._cdf = None
1049
1023
  self._cdf_bins = 1024
1050
1024
  self._cdf_total = 0
1051
-
1025
+ # Debounce: coalesce rapid curve edits into one rebuild
1026
+ self._curve_debounce_ms = 120 # tweak: 80–200ms feels good
1027
+ self._curve_debounce = QTimer(self)
1028
+ self._curve_debounce.setSingleShot(True)
1029
+ self._curve_debounce.timeout.connect(self._rebuild_preview_from_curve_debounced)
1030
+
1031
+ # Optional: generation counter so stale results can't “win”
1032
+ self._curve_gen = 0
1052
1033
  self._clip_scale = 1.0 # preview→full multiplier
1053
1034
  self._cdf_total_full = 0 # total pixels in full image (H*W)
1054
1035
  self._cdf_total_preview = 0 # total pixels in preview (H*W)
@@ -1220,18 +1201,34 @@ class CurvesDialogPro(QDialog):
1220
1201
 
1221
1202
  def _on_editor_curve_changed(self, _lut8=None):
1222
1203
  """
1223
- Called on every editor redraw/drag. Persist the currently edited curve
1224
- into the store, refresh overlays, and do a realtime preview.
1204
+ Called on every editor redraw/drag. Persist points and refresh overlays.
1205
+ Preview rebuild is DEBOUNCED to avoid spamming.
1225
1206
  """
1226
1207
  try:
1227
1208
  self._curves_store[self._current_mode_key] = self._editor_points_norm()
1228
1209
  except Exception:
1229
1210
  pass
1230
- # show the true shapes of other channels too
1211
+
1212
+ # cheap: overlay redraw is fine every move (or you can debounce this too)
1231
1213
  self._refresh_overlays()
1232
- # now build from *all* current curves (including the just-edited one)
1233
- self._quick_preview()
1234
1214
 
1215
+ # expensive: debounce the preview rebuild
1216
+ self._curve_gen += 1
1217
+ self._curve_debounce.start(self._curve_debounce_ms)
1218
+
1219
+ def _rebuild_preview_from_curve_debounced(self):
1220
+ """
1221
+ Runs after the user pauses dragging for _curve_debounce_ms.
1222
+ Only rebuild if we have images loaded.
1223
+ """
1224
+ if self._preview_orig is None and self._preview_img is None:
1225
+ return
1226
+ # If your preview toggle is off, you may want to skip:
1227
+ if not getattr(self, "btn_preview", None) or not self.btn_preview.isChecked():
1228
+ return
1229
+
1230
+ # Do the real work (what you were doing before)
1231
+ self._quick_preview()
1235
1232
 
1236
1233
  def _active_mode_key(self) -> str:
1237
1234
  for b in self.mode_group.buttons():
@@ -1678,29 +1675,53 @@ class CurvesDialogPro(QDialog):
1678
1675
 
1679
1676
  # 1) Put this helper inside CurvesDialogPro (near other helpers)
1680
1677
  def _map_label_xy_to_image_ij(self, x: float, y: float):
1681
- """Map label-local coords (x,y) to _preview_img pixel (i,j). Returns (ix, iy) or None."""
1678
+ """
1679
+ Map label-local coords (x,y) to _preview_img pixel (ix, iy).
1680
+ Correct even when the pixmap is centered inside a larger label.
1681
+ Returns None if cursor is outside the displayed pixmap area.
1682
+ """
1682
1683
  if self._pix is None:
1683
1684
  return None
1685
+
1684
1686
  pm_disp = self.label.pixmap()
1685
1687
  if pm_disp is None or pm_disp.isNull():
1686
1688
  return None
1687
1689
 
1688
- src_w = self._pix.width() # size of the *source* pixmap (preview image)
1689
- src_h = self._pix.height()
1690
- disp_w = pm_disp.width() # size of the *displayed* pixmap on the label
1690
+ # Displayed pixmap size (after zoom)
1691
+ disp_w = pm_disp.width()
1691
1692
  disp_h = pm_disp.height()
1692
- if src_w <= 0 or src_h <= 0 or disp_w <= 0 or disp_h <= 0:
1693
+
1694
+ # Label may be bigger -> pixmap is centered with margins
1695
+ lbl_w = self.label.width()
1696
+ lbl_h = self.label.height()
1697
+
1698
+ off_x = max(0, (lbl_w - disp_w) // 2)
1699
+ off_y = max(0, (lbl_h - disp_h) // 2)
1700
+
1701
+ # Remove margins: label-local -> pixmap-local
1702
+ px = float(x) - float(off_x)
1703
+ py = float(y) - float(off_y)
1704
+
1705
+ if px < 0 or py < 0 or px >= disp_w or py >= disp_h:
1706
+ return None # outside actual image area
1707
+
1708
+ # Now convert displayed pixmap pixel -> source preview pixel
1709
+ src_w = self._pix.width()
1710
+ src_h = self._pix.height()
1711
+ if src_w <= 0 or src_h <= 0:
1693
1712
  return None
1694
1713
 
1695
1714
  sx = disp_w / float(src_w)
1696
1715
  sy = disp_h / float(src_h)
1697
1716
 
1698
- ix = int(x / sx)
1699
- iy = int(y / sy)
1717
+ ix = int(px / sx)
1718
+ iy = int(py / sy)
1719
+
1700
1720
  if ix < 0 or iy < 0 or ix >= src_w or iy >= src_h:
1701
1721
  return None
1702
1722
  return ix, iy
1703
1723
 
1724
+
1704
1725
  def _scene_to_norm_points(self, pts_scene: list[tuple[float,float]]) -> list[tuple[float,float]]:
1705
1726
  """(x:[0..360], y:[0..360] down) → (x,y in [0..1] up). Ensures endpoints present & strictly increasing x."""
1706
1727
  out = []