@64mb/freelens-power 1.1.0 → 1.2.1

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.
Files changed (214) hide show
  1. package/README.md +5 -4
  2. package/THIRD_PARTY_LICENSES +1707 -0
  3. package/out/main/ai.js +63 -23
  4. package/out/main/ai.js.map +1 -1
  5. package/out/main/cluster-icons-catalog.js +28 -0
  6. package/out/main/cluster-icons-catalog.js.map +1 -0
  7. package/out/main/cluster-icons.js +125 -0
  8. package/out/main/cluster-icons.js.map +1 -0
  9. package/out/main/common/ai-terminal-context.js +51 -0
  10. package/out/main/common/ai-terminal-context.js.map +1 -0
  11. package/out/main/common/ai.js.map +1 -1
  12. package/out/main/common/cluster-icon-ipc.js +6 -0
  13. package/out/main/common/cluster-icon-ipc.js.map +1 -0
  14. package/out/main/common/cluster-icons.js +121 -0
  15. package/out/main/common/cluster-icons.js.map +1 -0
  16. package/out/main/common/dashboard.js +2 -1
  17. package/out/main/common/dashboard.js.map +1 -1
  18. package/out/main/common/settings-export.js +4 -2
  19. package/out/main/common/settings-export.js.map +1 -1
  20. package/out/main/common/store/cluster-icons-store.js +32 -0
  21. package/out/main/common/store/cluster-icons-store.js.map +1 -0
  22. package/out/main/common/store/dashboard-preferences-store.js +2 -1
  23. package/out/main/common/store/dashboard-preferences-store.js.map +1 -1
  24. package/out/main/common/store/monitoring-preferences-store.js +5 -0
  25. package/out/main/common/store/monitoring-preferences-store.js.map +1 -1
  26. package/out/main/dashboard-views.js +20 -10
  27. package/out/main/dashboard-views.js.map +1 -1
  28. package/out/main/diagnostics-menu-order.js +57 -0
  29. package/out/main/diagnostics-menu-order.js.map +1 -0
  30. package/out/main/index.js +9 -1
  31. package/out/main/index.js.map +1 -1
  32. package/out/main/monitoring-history.js +13 -3
  33. package/out/main/monitoring-history.js.map +1 -1
  34. package/out/renderer/_virtual/_global-external_react-dom.js +2 -1
  35. package/out/renderer/_virtual/_global-external_react.js +10 -5
  36. package/out/renderer/_virtual/_rolldown/runtime.js +22 -0
  37. package/out/renderer/ai-terminal-context.js +200 -0
  38. package/out/renderer/ai-terminal-context.js.map +1 -0
  39. package/out/renderer/ai.js +90 -9
  40. package/out/renderer/ai.js.map +1 -1
  41. package/out/renderer/appearance.js +1 -0
  42. package/out/renderer/appearance.js.map +1 -1
  43. package/out/renderer/cluster-icon-colors.js +188 -0
  44. package/out/renderer/cluster-icon-colors.js.map +1 -0
  45. package/out/renderer/cluster-icons.js +304 -0
  46. package/out/renderer/cluster-icons.js.map +1 -0
  47. package/out/renderer/dashboard.js +51 -14
  48. package/out/renderer/dashboard.js.map +1 -1
  49. package/out/renderer/details/secret-certificate-details.js +9 -2
  50. package/out/renderer/details/secret-certificate-details.js.map +1 -1
  51. package/out/renderer/diagnostics.css.js +39 -0
  52. package/out/renderer/diagnostics.css.js.map +1 -0
  53. package/out/renderer/diagnostics.js +796 -343
  54. package/out/renderer/diagnostics.js.map +1 -1
  55. package/out/renderer/index.js +9 -4
  56. package/out/renderer/index.js.map +1 -1
  57. package/out/renderer/monitoring-details-chart.js +42 -0
  58. package/out/renderer/monitoring-details-chart.js.map +1 -0
  59. package/out/renderer/monitoring-history-collection.js +2 -18
  60. package/out/renderer/monitoring-history-collection.js.map +1 -1
  61. package/out/renderer/monitoring-history-view.js +111 -34
  62. package/out/renderer/monitoring-history-view.js.map +1 -1
  63. package/out/renderer/monitoring.js +68 -27
  64. package/out/renderer/monitoring.js.map +1 -1
  65. package/out/renderer/node-monitoring.js +23 -12
  66. package/out/renderer/node-monitoring.js.map +1 -1
  67. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js +10 -0
  68. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js.map +1 -0
  69. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js +8 -0
  70. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js.map +1 -0
  71. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js +9 -0
  72. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js.map +1 -0
  73. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +9 -0
  74. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js.map +1 -0
  75. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js +8 -0
  76. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/classCallCheck.js.map +1 -0
  77. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js +15 -0
  78. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createClass.js.map +1 -0
  79. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js +19 -0
  80. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/createSuper.js.map +1 -0
  81. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js +14 -0
  82. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/defineProperty.js.map +1 -0
  83. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js +19 -0
  84. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js.map +1 -0
  85. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js +15 -0
  86. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js.map +1 -0
  87. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js +14 -0
  88. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/inherits.js.map +1 -0
  89. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js +18 -0
  90. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js.map +1 -0
  91. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js +8 -0
  92. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArray.js.map +1 -0
  93. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js +26 -0
  94. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js.map +1 -0
  95. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js +8 -0
  96. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js.map +1 -0
  97. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js +8 -0
  98. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js.map +1 -0
  99. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js +27 -0
  100. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectSpread2.js.map +1 -0
  101. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js +15 -0
  102. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js.map +1 -0
  103. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js +14 -0
  104. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js.map +1 -0
  105. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js +12 -0
  106. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js.map +1 -0
  107. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +15 -0
  108. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js.map +1 -0
  109. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js +12 -0
  110. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/slicedToArray.js.map +1 -0
  111. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js +8 -0
  112. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/taggedTemplateLiteral.js.map +1 -0
  113. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js +12 -0
  114. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toConsumableArray.js.map +1 -0
  115. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js +16 -0
  116. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPrimitive.js.map +1 -0
  117. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js +11 -0
  118. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js.map +1 -0
  119. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js +18 -0
  120. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/typeof.js.map +1 -0
  121. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js +13 -0
  122. package/out/renderer/node_modules/.pnpm/@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js.map +1 -0
  123. package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js +237 -0
  124. package/out/renderer/node_modules/.pnpm/@emotion_cache@11.14.0/node_modules/@emotion/cache/dist/emotion-cache.browser.esm.js.map +1 -0
  125. package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js +25 -0
  126. package/out/renderer/node_modules/.pnpm/@emotion_hash@0.9.2/node_modules/@emotion/hash/dist/emotion-hash.esm.js.map +1 -0
  127. package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js +12 -0
  128. package/out/renderer/node_modules/.pnpm/@emotion_memoize@0.9.0/node_modules/@emotion/memoize/dist/emotion-memoize.esm.js.map +1 -0
  129. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js +58 -0
  130. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js.map +1 -0
  131. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-react.browser.esm.js +54 -0
  132. package/out/renderer/node_modules/.pnpm/@emotion_react@11.14.0_@types_react@17.0.93_react@17.0.2/node_modules/@emotion/react/dist/emotion-react.browser.esm.js.map +1 -0
  133. package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js +133 -0
  134. package/out/renderer/node_modules/.pnpm/@emotion_serialize@1.3.3/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js.map +1 -0
  135. package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js +65 -0
  136. package/out/renderer/node_modules/.pnpm/@emotion_sheet@1.4.0/node_modules/@emotion/sheet/dist/emotion-sheet.esm.js.map +1 -0
  137. package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js +54 -0
  138. package/out/renderer/node_modules/.pnpm/@emotion_unitless@0.10.0/node_modules/@emotion/unitless/dist/emotion-unitless.esm.js.map +1 -0
  139. package/out/renderer/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@17.0.2/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js +12 -0
  140. package/out/renderer/node_modules/.pnpm/@emotion_use-insertion-effect-with-fallbacks@1.2.0_react@17.0.2/node_modules/@emotion/use-insertion-effect-with-fallbacks/dist/emotion-use-insertion-effect-with-fallbacks.browser.esm.js.map +1 -0
  141. package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js +30 -0
  142. package/out/renderer/node_modules/.pnpm/@emotion_utils@1.4.2/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js.map +1 -0
  143. package/out/renderer/node_modules/.pnpm/@floating-ui_dom@1.7.2/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +211 -0
  144. package/out/renderer/node_modules/.pnpm/@floating-ui_dom@1.7.2/node_modules/@floating-ui/dom/dist/floating-ui.dom.js.map +1 -0
  145. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +97 -0
  146. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +1 -0
  147. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +31 -0
  148. package/out/renderer/node_modules/.pnpm/@floating-ui_utils@0.2.10/node_modules/@floating-ui/utils/dist/floating-ui.utils.js.map +1 -0
  149. package/out/renderer/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +93 -0
  150. package/out/renderer/node_modules/.pnpm/hoist-non-react-statics@3.3.2/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +1 -0
  151. package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js +38 -0
  152. package/out/renderer/node_modules/.pnpm/memoize-one@6.0.0/node_modules/memoize-one/dist/memoize-one.esm.js.map +1 -0
  153. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js +159 -0
  154. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.development.js.map +1 -0
  155. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js +103 -0
  156. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js.map +1 -0
  157. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js +18 -0
  158. package/out/renderer/node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/index.js.map +1 -0
  159. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/Select-ef7c0426.esm.js +2200 -0
  160. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/Select-ef7c0426.esm.js.map +1 -0
  161. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/index-641ee5b8.esm.js +992 -0
  162. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/index-641ee5b8.esm.js.map +1 -0
  163. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/react-select.esm.js +14 -0
  164. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/react-select.esm.js.map +1 -0
  165. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/useStateManager-7e1e8489.esm.js +56 -0
  166. package/out/renderer/node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/useStateManager-7e1e8489.esm.js.map +1 -0
  167. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js +22 -0
  168. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Enum.js.map +1 -0
  169. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js +30 -0
  170. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Middleware.js.map +1 -0
  171. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js +164 -0
  172. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Parser.js.map +1 -0
  173. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js +37 -0
  174. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Serializer.js.map +1 -0
  175. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js +245 -0
  176. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Tokenizer.js.map +1 -0
  177. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js +120 -0
  178. package/out/renderer/node_modules/.pnpm/stylis@4.2.0/node_modules/stylis/src/Utility.js.map +1 -0
  179. package/out/renderer/node_modules/.pnpm/use-isomorphic-layout-effect@1.2.1_@types_react@17.0.93_react@17.0.2/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.js +6 -0
  180. package/out/renderer/node_modules/.pnpm/use-isomorphic-layout-effect@1.2.1_@types_react@17.0.93_react@17.0.2/node_modules/use-isomorphic-layout-effect/dist/use-isomorphic-layout-effect.browser.esm.js.map +1 -0
  181. package/out/renderer/pod-monitoring.js +15 -19
  182. package/out/renderer/pod-monitoring.js.map +1 -1
  183. package/out/renderer/preferences/ai-shortcuts-preferences.js +12 -4
  184. package/out/renderer/preferences/ai-shortcuts-preferences.js.map +1 -1
  185. package/out/renderer/preferences/dashboard-preferences.js +37 -6
  186. package/out/renderer/preferences/dashboard-preferences.js.map +1 -1
  187. package/out/renderer/preferences/monitoring-preferences.js +131 -44
  188. package/out/renderer/preferences/monitoring-preferences.js.map +1 -1
  189. package/out/renderer/preferences/preferences.js +31 -7
  190. package/out/renderer/preferences/preferences.js.map +1 -1
  191. package/out/renderer/read-only.js +2 -2
  192. package/out/renderer/read-only.js.map +1 -1
  193. package/out/renderer/src/common/ai-terminal-context.js +51 -0
  194. package/out/renderer/src/common/ai-terminal-context.js.map +1 -0
  195. package/out/renderer/src/common/ai.js.map +1 -1
  196. package/out/renderer/src/common/cluster-icon-ipc.js +6 -0
  197. package/out/renderer/src/common/cluster-icon-ipc.js.map +1 -0
  198. package/out/renderer/src/common/cluster-icons.js +133 -0
  199. package/out/renderer/src/common/cluster-icons.js.map +1 -0
  200. package/out/renderer/src/common/dashboard.js +2 -1
  201. package/out/renderer/src/common/dashboard.js.map +1 -1
  202. package/out/renderer/src/common/date-time.js +11 -0
  203. package/out/renderer/src/common/date-time.js.map +1 -0
  204. package/out/renderer/src/common/monitoring-history.js +2 -0
  205. package/out/renderer/src/common/monitoring-history.js.map +1 -1
  206. package/out/renderer/src/common/resource-diagnostics.js.map +1 -1
  207. package/out/renderer/src/common/settings-export.js.map +1 -1
  208. package/out/renderer/src/common/store/dashboard-preferences-store.js +2 -1
  209. package/out/renderer/src/common/store/dashboard-preferences-store.js.map +1 -1
  210. package/out/renderer/src/common/store/monitoring-preferences-store.js +5 -0
  211. package/out/renderer/src/common/store/monitoring-preferences-store.js.map +1 -1
  212. package/out/renderer/welcome.js +28 -6
  213. package/out/renderer/welcome.js.map +1 -1
  214. package/package.json +3 -2
@@ -0,0 +1,304 @@
1
+ const require_extensions = require("./_virtual/_global-external_@freelensapp/extensions.js");
2
+ const require__global_external_react = require("./_virtual/_global-external_react.js");
3
+ const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runtime.js");
4
+ const require_cluster_icon_ipc = require("./src/common/cluster-icon-ipc.js");
5
+ const require_cluster_icons = require("./src/common/cluster-icons.js");
6
+ const require_cluster_icon_colors = require("./cluster-icon-colors.js");
7
+ const require_settings_modal = require("./preferences/settings-modal.js");
8
+ let electron = require("electron");
9
+ //#region src/renderer/cluster-icons.tsx
10
+ var styles = `
11
+ .ClusterManager main.power-icon-studio, .power-icon-studio { display: block; position: relative; z-index: 2; flex: 1; min-width: 0; height: 100%; overflow: auto; padding: 32px; box-sizing: border-box; background: var(--mainBackground); color: var(--textColorPrimary); }
12
+ .power-icon-studio > .power-icon-content { max-width: 1000px; margin: 0 auto; }
13
+ .power-icon-header { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 28px; }
14
+ .power-icon-header h1 { font-size: 24px; font-weight: 600; margin: 0 0 8px; color: var(--textColorAccent); }
15
+ .power-icon-header p { margin: 0; color: var(--textColorSecondary); }
16
+ .power-icon-search { width: 240px; }
17
+ .power-icon-grid { display: grid; grid-template-columns: repeat(5,minmax(0,1fr)); gap: 16px; }
18
+ .power-icon-card { display: flex; flex-direction: column; align-items: center; gap: 12px; position: relative; padding: 20px 14px 16px; min-width: 0; border: 1px solid var(--borderFaintColor); border-radius: 14px; background: var(--contentColor); color: var(--textColorPrimary); font: inherit; cursor: pointer; transition: border-color 150ms ease, background-color 150ms ease, transform 150ms ease; }
19
+ .power-icon-card:hover { border-color: var(--primary); background: color-mix(in srgb,var(--primary) 4%,var(--contentColor)); transform: translateY(-2px); }
20
+ .power-icon-card:focus-visible, .power-icon-glyph:focus-visible, .power-icon-swatch:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
21
+ .power-icon-card > img, .power-icon-card .power-icon-current-avatar { width: 64px; height: 64px; object-fit: contain; border-radius: 16px; }
22
+ .power-icon-card-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
23
+ .power-icon-empty { padding: 64px 24px; text-align: center; border: 1px dashed var(--borderFaintColor); border-radius: 14px; color: var(--textColorSecondary); }
24
+ .power-icon-editor { display: grid; grid-template-columns: 144px minmax(0,1fr); gap: 24px; }
25
+ .power-icon-preview { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; padding: 24px 12px; border: 1px solid var(--borderFaintColor); border-radius: 12px; background: var(--contentColor); }
26
+ .power-icon-preview-main { width: 96px; height: 96px; }
27
+ .power-icon-preview-sizes { display: flex; align-items: center; gap: 14px; }
28
+ .power-icon-preview-caption { font-size: 11px; color: var(--textColorSecondary); }
29
+ .power-icon-fields { display: grid; gap: 16px; }
30
+ .power-icon-field { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; }
31
+ .power-icon-field input[type=text] { width: 100px; padding: 8px 10px; border: 1px solid var(--borderFaintColor); border-radius: 6px; background: var(--contentColor); color: var(--textColorPrimary); font: inherit; }
32
+ .power-icon-field input:focus-visible { outline: 1px solid var(--primary); }
33
+ .power-icon-section-label { color: var(--textColorSecondary); font-size: 12px; margin-bottom: 10px; }
34
+ .power-icon-glyphs { display: grid; grid-template-columns: repeat(5,minmax(0,1fr)); gap: 8px; }
35
+ .power-icon-glyph { display: flex; align-items: center; justify-content: center; min-height: 54px; padding: 6px; border: 1px solid var(--borderFaintColor); border-radius: 8px; background: var(--contentColor); cursor: pointer; transition: border-color 150ms ease, background-color 150ms ease; }
36
+ .power-icon-glyph:hover, .power-icon-glyph[aria-pressed=true] { border-color: var(--primary); background: color-mix(in srgb,var(--primary) 8%,var(--contentColor)); }
37
+ .power-icon-glyph img { width: 38px; height: 38px; }
38
+ .power-icon-swatches { display: flex; align-items: center; gap: 8px; }
39
+ .power-icon-swatch { width: 22px; height: 22px; border: 2px solid transparent; border-radius: 50%; cursor: pointer; }
40
+ .power-icon-swatch[aria-pressed=true] { box-shadow: 0 0 0 2px var(--mainBackground),0 0 0 3px var(--primary); }
41
+ .power-icon-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 12px; border-top: 1px solid var(--borderFaintColor); }
42
+ .power-icon-footer-actions { display: flex; gap: 8px; margin-left: auto; }
43
+ .power-icon-error { color: var(--colorError); font-size: 12px; line-height: 1.5; }
44
+ @media (max-width: 900px) { .power-icon-grid { grid-template-columns: repeat(4,minmax(0,1fr)); } }
45
+ @media (max-width: 700px) { .power-icon-header { align-items: stretch; flex-direction: column; } .power-icon-search { width: 100%; } .power-icon-grid { grid-template-columns: repeat(3,minmax(0,1fr)); } .ClusterManager main.power-icon-studio, .power-icon-studio { padding: 20px; } }
46
+ @media (max-width: 480px) { .power-icon-grid { grid-template-columns: repeat(2,minmax(0,1fr)); } .power-icon-editor { grid-template-columns: 1fr; } .power-icon-preview { flex-direction: row; padding: 16px; } .power-icon-preview-main { width: 72px; height: 72px; } }
47
+ @media (prefers-reduced-motion: reduce) { .power-icon-card { transition: none; transform: none; } }
48
+ `;
49
+ function IconEditor({ entry, onClose, onSaved }) {
50
+ const [design, setDesign] = require__global_external_react.useState(() => entry.design ?? require_cluster_icons.defaultClusterIconDesign(entry.name));
51
+ const [busy, setBusy] = require__global_external_react.useState(false);
52
+ const [error, setError] = require__global_external_react.useState("");
53
+ const paletteOpen = require__global_external_react.useRef(false);
54
+ const onPaletteOpenChange = require__global_external_react.useCallback((open) => {
55
+ paletteOpen.current = open;
56
+ }, []);
57
+ const update = (key, value) => setDesign((previous) => ({
58
+ ...previous,
59
+ [key]: value
60
+ }));
61
+ const save = async () => {
62
+ setBusy(true);
63
+ setError("");
64
+ try {
65
+ onSaved(await electron.ipcRenderer.invoke(require_cluster_icon_ipc.CLUSTER_ICONS_CHANNEL, {
66
+ operation: "apply",
67
+ id: entry.id,
68
+ design
69
+ }));
70
+ } catch {
71
+ setError("Unable to save this cluster icon. Try again.");
72
+ } finally {
73
+ setBusy(false);
74
+ }
75
+ };
76
+ let validDesign;
77
+ try {
78
+ validDesign = require_cluster_icons.normalizeClusterIconDesign(design);
79
+ } catch {
80
+ validDesign = void 0;
81
+ }
82
+ const previewDesign = validDesign ?? require_cluster_icons.defaultClusterIconDesign(entry.name);
83
+ const preview = require_cluster_icons.clusterIconDataUrl(previewDesign);
84
+ return /* @__PURE__ */ require_jsx_runtime.jsxs(require_settings_modal.SettingsModal, {
85
+ id: "power-cluster-icon-editor",
86
+ title: entry.name,
87
+ onClose: () => {
88
+ if (!busy && !paletteOpen.current) onClose();
89
+ },
90
+ children: [
91
+ /* @__PURE__ */ require_jsx_runtime.jsx("style", { children: styles }),
92
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
93
+ className: "power-icon-editor",
94
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", {
95
+ className: "power-icon-preview",
96
+ children: [
97
+ /* @__PURE__ */ require_jsx_runtime.jsx("img", {
98
+ className: "power-icon-preview-main",
99
+ src: preview,
100
+ alt: "Cluster icon preview"
101
+ }),
102
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
103
+ className: "power-icon-preview-sizes",
104
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("img", {
105
+ src: preview,
106
+ width: 36,
107
+ height: 36,
108
+ alt: ""
109
+ })
110
+ }),
111
+ /* @__PURE__ */ require_jsx_runtime.jsx("span", {
112
+ className: "power-icon-preview-caption",
113
+ children: "Sidebar preview"
114
+ })
115
+ ]
116
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
117
+ className: "power-icon-fields",
118
+ children: [
119
+ /* @__PURE__ */ require_jsx_runtime.jsxs("label", {
120
+ className: "power-icon-field",
121
+ htmlFor: "power-icon-label",
122
+ children: ["Label", /* @__PURE__ */ require_jsx_runtime.jsx("input", {
123
+ id: "power-icon-label",
124
+ type: "text",
125
+ value: design.label,
126
+ onChange: (event) => update("label", Array.from(event.target.value).slice(0, 3).join("")),
127
+ disabled: busy,
128
+ autoFocus: true
129
+ })]
130
+ }),
131
+ [
132
+ ["outlineColor", "Outline"],
133
+ ["labelColor", "Label color"],
134
+ ["iconColor", "Icon color"]
135
+ ].map(([key, label]) => /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
136
+ className: "power-icon-field",
137
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", { children: label }), /* @__PURE__ */ require_jsx_runtime.jsx(require_cluster_icon_colors.IconColorPicker, {
138
+ label,
139
+ value: design[key],
140
+ onChange: (color) => update(key, color),
141
+ disabled: busy,
142
+ onOpenChange: onPaletteOpenChange
143
+ })]
144
+ }, key)),
145
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("div", {
146
+ className: "power-icon-section-label",
147
+ children: "Matching outline & label"
148
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
149
+ className: "power-icon-swatches",
150
+ children: require_cluster_icon_colors.MATCHING_ICON_COLORS.map(({ name, color }) => /* @__PURE__ */ require_jsx_runtime.jsx("button", {
151
+ type: "button",
152
+ className: "power-icon-swatch",
153
+ style: { background: color },
154
+ title: `${name} · ${color}`,
155
+ "aria-label": `Use ${color} for outline and label`,
156
+ "aria-pressed": design.outlineColor === color && design.labelColor === color,
157
+ disabled: busy,
158
+ onClick: () => setDesign((previous) => ({
159
+ ...previous,
160
+ outlineColor: color,
161
+ labelColor: color
162
+ }))
163
+ }, color))
164
+ })] })
165
+ ]
166
+ })]
167
+ }),
168
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("div", {
169
+ className: "power-icon-section-label",
170
+ children: "Choose an icon"
171
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
172
+ className: "power-icon-glyphs",
173
+ children: require_cluster_icons.GLYPHS.map((glyph) => /* @__PURE__ */ require_jsx_runtime.jsx("button", {
174
+ type: "button",
175
+ className: "power-icon-glyph",
176
+ title: glyph.label,
177
+ "aria-label": glyph.label,
178
+ "aria-pressed": design.glyph === glyph.id,
179
+ disabled: busy,
180
+ onClick: () => update("glyph", glyph.id),
181
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("img", {
182
+ src: require_cluster_icons.clusterIconDataUrl({
183
+ ...previewDesign,
184
+ glyph: glyph.id
185
+ }),
186
+ alt: ""
187
+ })
188
+ }, glyph.id))
189
+ })] }),
190
+ !validDesign && /* @__PURE__ */ require_jsx_runtime.jsx("div", {
191
+ role: "alert",
192
+ className: "power-icon-error",
193
+ children: "Use up to three visible characters for the label."
194
+ }),
195
+ error && /* @__PURE__ */ require_jsx_runtime.jsx("div", {
196
+ role: "alert",
197
+ className: "power-icon-error",
198
+ children: error
199
+ }),
200
+ /* @__PURE__ */ require_jsx_runtime.jsx("div", {
201
+ className: "power-icon-footer",
202
+ children: /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
203
+ className: "power-icon-footer-actions",
204
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Button, {
205
+ label: "Cancel",
206
+ disabled: busy,
207
+ onClick: onClose
208
+ }), /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Button, {
209
+ primary: true,
210
+ label: busy ? "Applying…" : "Apply",
211
+ disabled: busy || !validDesign,
212
+ onClick: () => void save()
213
+ })]
214
+ })
215
+ })
216
+ ]
217
+ });
218
+ }
219
+ function ClusterIconsPage() {
220
+ const [entries, setEntries] = require__global_external_react.useState([]);
221
+ const [loading, setLoading] = require__global_external_react.useState(true);
222
+ const [error, setError] = require__global_external_react.useState("");
223
+ const [query, setQuery] = require__global_external_react.useState("");
224
+ const [editing, setEditing] = require__global_external_react.useState();
225
+ const load = () => {
226
+ setLoading(true);
227
+ setError("");
228
+ return electron.ipcRenderer.invoke(require_cluster_icon_ipc.CLUSTER_ICONS_CHANNEL, { operation: "list" }).then(setEntries).catch(() => setError("Unable to load saved clusters. Try again.")).finally(() => setLoading(false));
229
+ };
230
+ require__global_external_react.useEffect(() => {
231
+ load();
232
+ }, []);
233
+ const visible = entries.filter((entry) => entry.name.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase()));
234
+ return /* @__PURE__ */ require_jsx_runtime.jsxs("main", {
235
+ className: "power-icon-studio",
236
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("style", { children: styles }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
237
+ className: "power-icon-content",
238
+ children: [
239
+ /* @__PURE__ */ require_jsx_runtime.jsxs("header", {
240
+ className: "power-icon-header",
241
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("div", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("h1", { children: "Cluster icons" }), /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "A shared style. A distinct identity for every cluster." })] }), /* @__PURE__ */ require_jsx_runtime.jsx("div", {
242
+ className: "power-icon-search",
243
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Input, {
244
+ value: query,
245
+ onChange: setQuery,
246
+ placeholder: "Find a cluster…",
247
+ "aria-label": "Find a cluster"
248
+ })
249
+ })]
250
+ }),
251
+ error ? /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
252
+ className: "power-icon-empty",
253
+ role: "alert",
254
+ children: [
255
+ error,
256
+ " ",
257
+ /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Button, {
258
+ label: "Retry",
259
+ onClick: () => void load()
260
+ })
261
+ ]
262
+ }) : loading ? /* @__PURE__ */ require_jsx_runtime.jsx("div", {
263
+ className: "power-icon-empty",
264
+ role: "status",
265
+ children: "Loading clusters…"
266
+ }) : visible.length === 0 ? /* @__PURE__ */ require_jsx_runtime.jsx("div", {
267
+ className: "power-icon-empty",
268
+ children: entries.length ? "No matching clusters" : "Your saved clusters will appear here"
269
+ }) : /* @__PURE__ */ require_jsx_runtime.jsx("div", {
270
+ className: "power-icon-grid",
271
+ children: visible.map((entry) => /* @__PURE__ */ require_jsx_runtime.jsxs("button", {
272
+ type: "button",
273
+ className: "power-icon-card",
274
+ title: `Edit icon for ${entry.name}`,
275
+ onClick: () => setEditing(entry),
276
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Avatar, {
277
+ title: entry.name,
278
+ size: 64,
279
+ src: entry.icon?.startsWith("data:image/") ? entry.icon : void 0,
280
+ background: entry.icon && !entry.icon.startsWith("data:") ? entry.icon : void 0,
281
+ colorHash: `${entry.name}-${require_extensions.Renderer.Catalog.catalogEntities.getById(entry.id)?.metadata.source ?? ""}`,
282
+ className: "power-icon-current-avatar"
283
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("span", {
284
+ className: "power-icon-card-name",
285
+ children: entry.name
286
+ })]
287
+ }, entry.id))
288
+ }),
289
+ editing && /* @__PURE__ */ require_jsx_runtime.jsx(IconEditor, {
290
+ entry: editing,
291
+ onClose: () => setEditing(void 0),
292
+ onSaved: (next) => {
293
+ setEntries(next);
294
+ setEditing(void 0);
295
+ }
296
+ }, editing.id)
297
+ ]
298
+ })]
299
+ });
300
+ }
301
+ //#endregion
302
+ exports.ClusterIconsPage = ClusterIconsPage;
303
+
304
+ //# sourceMappingURL=cluster-icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cluster-icons.js","names":[],"sources":["../../src/renderer/cluster-icons.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { ipcRenderer } from \"electron\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { CLUSTER_ICONS_CHANNEL, type ClusterIconEntry } from \"../common/cluster-icon-ipc\";\nimport {\n type ClusterIconDesign,\n clusterIconDataUrl,\n defaultClusterIconDesign,\n GLYPHS,\n normalizeClusterIconDesign,\n} from \"../common/cluster-icons\";\nimport { IconColorPicker, MATCHING_ICON_COLORS } from \"./cluster-icon-colors\";\nimport { SettingsModal } from \"./preferences/settings-modal\";\n\nconst styles = `\n.ClusterManager main.power-icon-studio, .power-icon-studio { display: block; position: relative; z-index: 2; flex: 1; min-width: 0; height: 100%; overflow: auto; padding: 32px; box-sizing: border-box; background: var(--mainBackground); color: var(--textColorPrimary); }\n.power-icon-studio > .power-icon-content { max-width: 1000px; margin: 0 auto; }\n.power-icon-header { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 28px; }\n.power-icon-header h1 { font-size: 24px; font-weight: 600; margin: 0 0 8px; color: var(--textColorAccent); }\n.power-icon-header p { margin: 0; color: var(--textColorSecondary); }\n.power-icon-search { width: 240px; }\n.power-icon-grid { display: grid; grid-template-columns: repeat(5,minmax(0,1fr)); gap: 16px; }\n.power-icon-card { display: flex; flex-direction: column; align-items: center; gap: 12px; position: relative; padding: 20px 14px 16px; min-width: 0; border: 1px solid var(--borderFaintColor); border-radius: 14px; background: var(--contentColor); color: var(--textColorPrimary); font: inherit; cursor: pointer; transition: border-color 150ms ease, background-color 150ms ease, transform 150ms ease; }\n.power-icon-card:hover { border-color: var(--primary); background: color-mix(in srgb,var(--primary) 4%,var(--contentColor)); transform: translateY(-2px); }\n.power-icon-card:focus-visible, .power-icon-glyph:focus-visible, .power-icon-swatch:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }\n.power-icon-card > img, .power-icon-card .power-icon-current-avatar { width: 64px; height: 64px; object-fit: contain; border-radius: 16px; }\n.power-icon-card-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.power-icon-empty { padding: 64px 24px; text-align: center; border: 1px dashed var(--borderFaintColor); border-radius: 14px; color: var(--textColorSecondary); }\n.power-icon-editor { display: grid; grid-template-columns: 144px minmax(0,1fr); gap: 24px; }\n.power-icon-preview { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; padding: 24px 12px; border: 1px solid var(--borderFaintColor); border-radius: 12px; background: var(--contentColor); }\n.power-icon-preview-main { width: 96px; height: 96px; }\n.power-icon-preview-sizes { display: flex; align-items: center; gap: 14px; }\n.power-icon-preview-caption { font-size: 11px; color: var(--textColorSecondary); }\n.power-icon-fields { display: grid; gap: 16px; }\n.power-icon-field { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; }\n.power-icon-field input[type=text] { width: 100px; padding: 8px 10px; border: 1px solid var(--borderFaintColor); border-radius: 6px; background: var(--contentColor); color: var(--textColorPrimary); font: inherit; }\n.power-icon-field input:focus-visible { outline: 1px solid var(--primary); }\n.power-icon-section-label { color: var(--textColorSecondary); font-size: 12px; margin-bottom: 10px; }\n.power-icon-glyphs { display: grid; grid-template-columns: repeat(5,minmax(0,1fr)); gap: 8px; }\n.power-icon-glyph { display: flex; align-items: center; justify-content: center; min-height: 54px; padding: 6px; border: 1px solid var(--borderFaintColor); border-radius: 8px; background: var(--contentColor); cursor: pointer; transition: border-color 150ms ease, background-color 150ms ease; }\n.power-icon-glyph:hover, .power-icon-glyph[aria-pressed=true] { border-color: var(--primary); background: color-mix(in srgb,var(--primary) 8%,var(--contentColor)); }\n.power-icon-glyph img { width: 38px; height: 38px; }\n.power-icon-swatches { display: flex; align-items: center; gap: 8px; }\n.power-icon-swatch { width: 22px; height: 22px; border: 2px solid transparent; border-radius: 50%; cursor: pointer; }\n.power-icon-swatch[aria-pressed=true] { box-shadow: 0 0 0 2px var(--mainBackground),0 0 0 3px var(--primary); }\n.power-icon-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 12px; border-top: 1px solid var(--borderFaintColor); }\n.power-icon-footer-actions { display: flex; gap: 8px; margin-left: auto; }\n.power-icon-error { color: var(--colorError); font-size: 12px; line-height: 1.5; }\n@media (max-width: 900px) { .power-icon-grid { grid-template-columns: repeat(4,minmax(0,1fr)); } }\n@media (max-width: 700px) { .power-icon-header { align-items: stretch; flex-direction: column; } .power-icon-search { width: 100%; } .power-icon-grid { grid-template-columns: repeat(3,minmax(0,1fr)); } .ClusterManager main.power-icon-studio, .power-icon-studio { padding: 20px; } }\n@media (max-width: 480px) { .power-icon-grid { grid-template-columns: repeat(2,minmax(0,1fr)); } .power-icon-editor { grid-template-columns: 1fr; } .power-icon-preview { flex-direction: row; padding: 16px; } .power-icon-preview-main { width: 72px; height: 72px; } }\n@media (prefers-reduced-motion: reduce) { .power-icon-card { transition: none; transform: none; } }\n`;\n\nfunction IconEditor({\n entry,\n onClose,\n onSaved,\n}: {\n entry: ClusterIconEntry;\n onClose: () => void;\n onSaved: (entries: ClusterIconEntry[]) => void;\n}) {\n const [design, setDesign] = useState<ClusterIconDesign>(() => entry.design ?? defaultClusterIconDesign(entry.name));\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState(\"\");\n const paletteOpen = useRef(false);\n const onPaletteOpenChange = useCallback((open: boolean) => {\n paletteOpen.current = open;\n }, []);\n const update = (key: keyof ClusterIconDesign, value: string) =>\n setDesign((previous) => ({ ...previous, [key]: value }));\n const save = async () => {\n setBusy(true);\n setError(\"\");\n try {\n const entries = await ipcRenderer.invoke(CLUSTER_ICONS_CHANNEL, {\n operation: \"apply\",\n id: entry.id,\n design,\n });\n onSaved(entries);\n } catch {\n setError(\"Unable to save this cluster icon. Try again.\");\n } finally {\n setBusy(false);\n }\n };\n let validDesign: ClusterIconDesign | undefined;\n try {\n validDesign = normalizeClusterIconDesign(design);\n } catch {\n validDesign = undefined;\n }\n const previewDesign = validDesign ?? defaultClusterIconDesign(entry.name);\n const preview = clusterIconDataUrl(previewDesign);\n return (\n <SettingsModal\n id=\"power-cluster-icon-editor\"\n title={entry.name}\n onClose={() => {\n if (!busy && !paletteOpen.current) onClose();\n }}\n >\n <style>{styles}</style>\n <div className=\"power-icon-editor\">\n <div className=\"power-icon-preview\">\n <img className=\"power-icon-preview-main\" src={preview} alt=\"Cluster icon preview\" />\n <div className=\"power-icon-preview-sizes\">\n <img src={preview} width={36} height={36} alt=\"\" />\n </div>\n <span className=\"power-icon-preview-caption\">Sidebar preview</span>\n </div>\n <div className=\"power-icon-fields\">\n <label className=\"power-icon-field\" htmlFor=\"power-icon-label\">\n Label\n <input\n id=\"power-icon-label\"\n type=\"text\"\n value={design.label}\n onChange={(event) => update(\"label\", Array.from(event.target.value).slice(0, 3).join(\"\"))}\n disabled={busy}\n autoFocus\n />\n </label>\n {(\n [\n [\"outlineColor\", \"Outline\"],\n [\"labelColor\", \"Label color\"],\n [\"iconColor\", \"Icon color\"],\n ] as const\n ).map(([key, label]) => (\n <div className=\"power-icon-field\" key={key}>\n <span>{label}</span>\n <IconColorPicker\n label={label}\n value={design[key]}\n onChange={(color) => update(key, color)}\n disabled={busy}\n onOpenChange={onPaletteOpenChange}\n />\n </div>\n ))}\n <div>\n <div className=\"power-icon-section-label\">Matching outline & label</div>\n <div className=\"power-icon-swatches\">\n {MATCHING_ICON_COLORS.map(({ name, color }) => (\n <button\n key={color}\n type=\"button\"\n className=\"power-icon-swatch\"\n style={{ background: color }}\n title={`${name} · ${color}`}\n aria-label={`Use ${color} for outline and label`}\n aria-pressed={design.outlineColor === color && design.labelColor === color}\n disabled={busy}\n onClick={() => setDesign((previous) => ({ ...previous, outlineColor: color, labelColor: color }))}\n />\n ))}\n </div>\n </div>\n </div>\n </div>\n <div>\n <div className=\"power-icon-section-label\">Choose an icon</div>\n <div className=\"power-icon-glyphs\">\n {GLYPHS.map((glyph) => (\n <button\n type=\"button\"\n key={glyph.id}\n className=\"power-icon-glyph\"\n title={glyph.label}\n aria-label={glyph.label}\n aria-pressed={design.glyph === glyph.id}\n disabled={busy}\n onClick={() => update(\"glyph\", glyph.id)}\n >\n <img src={clusterIconDataUrl({ ...previewDesign, glyph: glyph.id })} alt=\"\" />\n </button>\n ))}\n </div>\n </div>\n {!validDesign && (\n <div role=\"alert\" className=\"power-icon-error\">\n Use up to three visible characters for the label.\n </div>\n )}\n {error && (\n <div role=\"alert\" className=\"power-icon-error\">\n {error}\n </div>\n )}\n <div className=\"power-icon-footer\">\n <div className=\"power-icon-footer-actions\">\n <Renderer.Component.Button label=\"Cancel\" disabled={busy} onClick={onClose} />\n <Renderer.Component.Button\n primary\n label={busy ? \"Applying…\" : \"Apply\"}\n disabled={busy || !validDesign}\n onClick={() => void save()}\n />\n </div>\n </div>\n </SettingsModal>\n );\n}\n\nexport function ClusterIconsPage() {\n const [entries, setEntries] = useState<ClusterIconEntry[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(\"\");\n const [query, setQuery] = useState(\"\");\n const [editing, setEditing] = useState<ClusterIconEntry>();\n const load = () => {\n setLoading(true);\n setError(\"\");\n return ipcRenderer\n .invoke(CLUSTER_ICONS_CHANNEL, { operation: \"list\" })\n .then(setEntries)\n .catch(() => setError(\"Unable to load saved clusters. Try again.\"))\n .finally(() => setLoading(false));\n };\n useEffect(() => {\n void load();\n }, []);\n const visible = entries.filter((entry) => entry.name.toLocaleLowerCase().includes(query.trim().toLocaleLowerCase()));\n return (\n <main className=\"power-icon-studio\">\n <style>{styles}</style>\n <div className=\"power-icon-content\">\n <header className=\"power-icon-header\">\n <div>\n <h1>Cluster icons</h1>\n <p>A shared style. A distinct identity for every cluster.</p>\n </div>\n <div className=\"power-icon-search\">\n <Renderer.Component.Input\n value={query}\n onChange={setQuery}\n placeholder=\"Find a cluster…\"\n aria-label=\"Find a cluster\"\n />\n </div>\n </header>\n {error ? (\n <div className=\"power-icon-empty\" role=\"alert\">\n {error} <Renderer.Component.Button label=\"Retry\" onClick={() => void load()} />\n </div>\n ) : loading ? (\n <div className=\"power-icon-empty\" role=\"status\">\n Loading clusters…\n </div>\n ) : visible.length === 0 ? (\n <div className=\"power-icon-empty\">\n {entries.length ? \"No matching clusters\" : \"Your saved clusters will appear here\"}\n </div>\n ) : (\n <div className=\"power-icon-grid\">\n {visible.map((entry) => (\n <button\n type=\"button\"\n key={entry.id}\n className=\"power-icon-card\"\n title={`Edit icon for ${entry.name}`}\n onClick={() => setEditing(entry)}\n >\n <Renderer.Component.Avatar\n title={entry.name}\n size={64}\n src={entry.icon?.startsWith(\"data:image/\") ? entry.icon : undefined}\n background={entry.icon && !entry.icon.startsWith(\"data:\") ? entry.icon : undefined}\n colorHash={`${entry.name}-${Renderer.Catalog.catalogEntities.getById(entry.id)?.metadata.source ?? \"\"}`}\n className=\"power-icon-current-avatar\"\n />\n <span className=\"power-icon-card-name\">{entry.name}</span>\n </button>\n ))}\n </div>\n )}\n {editing && (\n <IconEditor\n key={editing.id}\n entry={editing}\n onClose={() => setEditing(undefined)}\n onSaved={(next) => {\n setEntries(next);\n setEditing(undefined);\n }}\n />\n )}\n </div>\n </main>\n );\n}\n"],"mappings":"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"}
@@ -51,14 +51,20 @@ var styles = `
51
51
  .freelens-power-dashboard button.power-dashboard-expand[aria-pressed="true"] .Icon { color: var(--primary); }
52
52
  .freelens-power-dashboard button.power-dashboard-expand[aria-pressed="true"]:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }
53
53
  .freelens-power-dashboard button.power-dashboard-expand:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
54
- .freelens-power-dashboard .power-dashboard-card-s { grid-column: span 1; grid-row: span 1; }
55
- .freelens-power-dashboard .power-dashboard-card-m { grid-column: span var(--power-medium-span, 2); grid-row: span 2; }
56
- .freelens-power-dashboard .power-dashboard-card-l { grid-column: span var(--power-large-span, 4); grid-row: span 4; }
54
+ .freelens-power-dashboard .power-dashboard-card-xs { grid-column: span 1; grid-row: span 1; }
55
+ .freelens-power-dashboard .power-dashboard-card-s { grid-column: span var(--power-small-span, 2); grid-row: span 2; }
56
+ .freelens-power-dashboard .power-dashboard-card-m { grid-column: span var(--power-medium-span, 4); grid-row: span 2; }
57
+ .freelens-power-dashboard .power-dashboard-card-l { grid-column: span var(--power-large-span, 4); grid-row: span 3; }
58
+ .freelens-power-dashboard .power-dashboard-card-xl { grid-column: span var(--power-columns, 4); grid-row: span 3; }
57
59
  .freelens-power-dashboard .power-dashboard-card-header {
58
60
  display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 12px;
59
61
  }
60
62
  .freelens-power-dashboard h2 { margin: 0; font-size: 14px; overflow-wrap: anywhere; }
61
63
  .freelens-power-dashboard .power-dashboard-card-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
64
+ .freelens-power-dashboard .power-dashboard-card-title h2 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
65
+ .freelens-power-dashboard .power-dashboard-card-xs .power-dashboard-card-header { flex-wrap: wrap; row-gap: 4px; }
66
+ .freelens-power-dashboard .power-dashboard-card-xs .power-dashboard-card-title { flex-basis: 100%; }
67
+ .freelens-power-dashboard .power-dashboard-card-xs .power-dashboard-card-actions { margin-left: auto; }
62
68
  .freelens-power-dashboard .power-dashboard-site-icon { width: 16px; height: 16px; border-radius: 4px; object-fit: contain; flex-shrink: 0; }
63
69
  .freelens-power-dashboard .power-dashboard-card-header a {
64
70
  flex-shrink: 0; color: var(--textColorPrimary); font-size: 12px; transition: color 160ms ease;
@@ -73,6 +79,7 @@ var styles = `
73
79
  @keyframes power-dashboard-loading { 50% { opacity: .45; } }
74
80
  @media (prefers-reduced-motion: reduce) { .freelens-power-dashboard .power-dashboard-skeleton span { animation: none; } }
75
81
  .freelens-power-dashboard .power-dashboard-hint { margin: 16px 0 0; font-size: 12px; }
82
+ .power-dashboard-right-tooltip { position: fixed !important; left: calc(anchor(right) + 8px) !important; top: anchor(center) !important; right: auto !important; bottom: auto !important; translate: 0 -50%; white-space: nowrap !important; max-width: none !important; }
76
83
  .freelens-power-dashboard .power-dashboard-empty {
77
84
  padding: 40px 24px; border: 1px solid var(--borderFaintColor); border-radius: 12px;
78
85
  background: var(--contentColor); text-align: center;
@@ -83,6 +90,22 @@ var styles = `
83
90
  .freelens-power-dashboard .power-dashboard-header { flex-wrap: wrap; }
84
91
  }
85
92
  `;
93
+ function DashboardActionIcon({ material, tooltip }) {
94
+ const [anchor] = require__global_external_react.useState(() => `--power-dashboard-action-${crypto.randomUUID()}`);
95
+ return /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
96
+ material,
97
+ size: 18,
98
+ style: {
99
+ anchorName: anchor,
100
+ "--size": "18px"
101
+ },
102
+ tooltip: {
103
+ children: tooltip,
104
+ className: "power-dashboard-right-tooltip",
105
+ style: { positionAnchor: anchor }
106
+ }
107
+ });
108
+ }
86
109
  function WebsiteIcon({ url, favicon }) {
87
110
  const [failed, setFailed] = require__global_external_react.useState(false);
88
111
  if (failed) return /* @__PURE__ */ require_jsx_runtime.jsx("span", {
@@ -234,10 +257,11 @@ var DashboardPage = require__global_external_mobx_react.observer(({ onOpenPrefer
234
257
  frame = 0;
235
258
  const containerStyle = window.getComputedStyle(container);
236
259
  const contentWidth = container.clientWidth - (Number.parseFloat(containerStyle.paddingLeft) || 0) - (Number.parseFloat(containerStyle.paddingRight) || 0);
237
- const columns = Math.max(1, Math.min(12, Math.floor((contentWidth + 20) / 260)));
260
+ const columns = contentWidth >= 1200 ? 6 : contentWidth >= 800 ? 4 : contentWidth >= 520 ? 2 : 1;
238
261
  for (const [property, value] of Object.entries({
239
262
  "--power-columns": columns,
240
- "--power-medium-span": Math.min(2, columns),
263
+ "--power-small-span": Math.min(2, columns),
264
+ "--power-medium-span": Math.min(4, columns),
241
265
  "--power-large-span": Math.min(4, columns)
242
266
  })) if (container.style.getPropertyValue(property) !== String(value)) container.style.setProperty(property, String(value));
243
267
  const containerBounds = container.getBoundingClientRect();
@@ -382,18 +406,33 @@ var DashboardPage = require__global_external_mobx_react.observer(({ onOpenPrefer
382
406
  }), /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
383
407
  className: "power-dashboard-card-actions",
384
408
  children: [
409
+ /* @__PURE__ */ require_jsx_runtime.jsx("button", {
410
+ type: "button",
411
+ className: "power-dashboard-expand",
412
+ "aria-label": `Auto-refresh ${card.title} every 10 seconds`,
413
+ "aria-pressed": card.refreshEvery10Seconds === true,
414
+ onClick: () => {
415
+ preferences.upsertCard({
416
+ ...card,
417
+ refreshEvery10Seconds: !card.refreshEvery10Seconds
418
+ });
419
+ },
420
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(DashboardActionIcon, {
421
+ material: "autorenew",
422
+ tooltip: card.refreshEvery10Seconds ? "Disable refresh" : "Enable refresh (10s)"
423
+ })
424
+ }),
385
425
  /* @__PURE__ */ require_jsx_runtime.jsx("button", {
386
426
  type: "button",
387
427
  className: "power-dashboard-expand",
388
428
  "aria-label": `${pinnedCards.includes(card.id) ? "Unpin" : "Pin"} ${card.title}`,
389
429
  "aria-pressed": pinnedCards.includes(card.id),
390
- title: pinnedCards.includes(card.id) ? "Close pinned window" : "Pin above other windows",
391
430
  onClick: () => {
392
431
  togglePinned(card.id);
393
432
  },
394
- children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
433
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(DashboardActionIcon, {
395
434
  material: "push_pin",
396
- size: 18
435
+ tooltip: pinnedCards.includes(card.id) ? "Unpin" : "Pin"
397
436
  })
398
437
  }),
399
438
  /* @__PURE__ */ require_jsx_runtime.jsx("button", {
@@ -401,14 +440,13 @@ var DashboardPage = require__global_external_mobx_react.observer(({ onOpenPrefer
401
440
  className: "power-dashboard-expand",
402
441
  "aria-label": `${expanded === card.id ? "Restore" : "Expand"} ${card.title}`,
403
442
  "aria-pressed": expanded === card.id,
404
- title: expanded === card.id ? "Restore" : "Expand",
405
443
  onClick: () => {
406
444
  if (!expanded) gridScrollTop.current = root.current?.scrollTop ?? 0;
407
445
  setExpandedId(expanded === card.id ? null : card.id);
408
446
  },
409
- children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
447
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(DashboardActionIcon, {
410
448
  material: expanded === card.id ? "fullscreen_exit" : "fullscreen",
411
- size: 18
449
+ tooltip: expanded === card.id ? "Restore" : "Expand"
412
450
  })
413
451
  }),
414
452
  /* @__PURE__ */ require_jsx_runtime.jsx("a", {
@@ -420,10 +458,9 @@ var DashboardPage = require__global_external_mobx_react.observer(({ onOpenPrefer
420
458
  target: "_blank",
421
459
  rel: "noopener noreferrer",
422
460
  "aria-label": `Open ${card.title} in browser`,
423
- children: /* @__PURE__ */ require_jsx_runtime.jsx(require_extensions.Renderer.Component.Icon, {
461
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(DashboardActionIcon, {
424
462
  material: "open_in_new",
425
- size: 18,
426
- tooltip: "Open in browser"
463
+ tooltip: "Open"
427
464
  })
428
465
  })
429
466
  ]