blue-chestnut-solar-expert 0.0.25 → 0.0.27

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 (59) hide show
  1. package/dist/cjs/eraser-icon.house-icon.icon-selector.map-draw.map-selector.move-icon.octagon-minus-icon.polygon-buttons.polygon-information.search-icon.settings-icon.settings-modal.solar-expert.solar-system-form.tool-box.undo-icon.entry.cjs.js.map +1 -1
  2. package/dist/cjs/eraser-icon_16.cjs.entry.js +47 -47
  3. package/dist/cjs/eraser-icon_16.cjs.entry.js.map +1 -1
  4. package/dist/cjs/loading-widget.cjs.entry.js +1 -1
  5. package/dist/cjs/solar-calculator.cjs.entry.js +1 -1
  6. package/dist/collection/components/map-draw/map-draw.js +6 -6
  7. package/dist/collection/components/map-draw/map-draw.js.map +1 -1
  8. package/dist/collection/components/settings/settings.js +8 -8
  9. package/dist/collection/components/settings/settings.js.map +1 -1
  10. package/dist/collection/components/solar-calculator/solar-calculator.js +1 -1
  11. package/dist/collection/components/solar-expert/solar-expert.js +1 -1
  12. package/dist/collection/components/solar-system-form/solar-system-form.js +31 -31
  13. package/dist/collection/components/widgets/loading-widget.js +1 -1
  14. package/dist/collection/store.js +1 -1
  15. package/dist/collection/store.js.map +1 -1
  16. package/dist/components/loading-widget.js +1 -1
  17. package/dist/components/map-draw.js +1 -1
  18. package/dist/components/map-selector.js +1 -1
  19. package/dist/components/{p-BLXc1FjC.js → p-BFcukOp8.js} +3 -3
  20. package/dist/components/{p-BLXc1FjC.js.map → p-BFcukOp8.js.map} +1 -1
  21. package/dist/components/{p-BLraILof.js → p-BraaSfVN.js} +34 -34
  22. package/dist/components/{p-BLraILof.js.map → p-BraaSfVN.js.map} +1 -1
  23. package/dist/components/{p-SerH3z5y.js → p-C6-nmq3h.js} +3 -3
  24. package/dist/components/{p-SerH3z5y.js.map → p-C6-nmq3h.js.map} +1 -1
  25. package/dist/components/{p-B1ywivYa.js → p-CUOVbcj0.js} +3 -3
  26. package/dist/components/{p-B1ywivYa.js.map → p-CUOVbcj0.js.map} +1 -1
  27. package/dist/components/{p-CQNcW74f.js → p-Cfxk__-m.js} +14 -14
  28. package/dist/components/p-Cfxk__-m.js.map +1 -0
  29. package/dist/components/{p-DMkbzkL_.js → p-D3zeTcOR.js} +3 -3
  30. package/dist/components/{p-DMkbzkL_.js.map → p-D3zeTcOR.js.map} +1 -1
  31. package/dist/components/{p-BcV6HHN8.js → p-DXg4w3Tg.js} +3 -3
  32. package/dist/components/{p-BcV6HHN8.js.map → p-DXg4w3Tg.js.map} +1 -1
  33. package/dist/components/{p-DgWwkE8N.js → p-aI3c1NCj.js} +11 -11
  34. package/dist/components/p-aI3c1NCj.js.map +1 -0
  35. package/dist/components/polygon-buttons.js +1 -1
  36. package/dist/components/polygon-information.js +1 -1
  37. package/dist/components/settings-modal.js +1 -1
  38. package/dist/components/solar-calculator.js +1 -1
  39. package/dist/components/solar-expert.js +9 -9
  40. package/dist/components/solar-system-form.js +1 -1
  41. package/dist/components/tool-box.js +1 -1
  42. package/dist/esm/eraser-icon.house-icon.icon-selector.map-draw.map-selector.move-icon.octagon-minus-icon.polygon-buttons.polygon-information.search-icon.settings-icon.settings-modal.solar-expert.solar-system-form.tool-box.undo-icon.entry.js.map +1 -1
  43. package/dist/esm/eraser-icon_16.entry.js +47 -47
  44. package/dist/esm/eraser-icon_16.entry.js.map +1 -1
  45. package/dist/esm/loading-widget.entry.js +1 -1
  46. package/dist/esm/solar-calculator.entry.js +1 -1
  47. package/dist/stencil-library/eraser-icon.house-icon.icon-selector.map-draw.map-selector.move-icon.octagon-minus-icon.polygon-buttons.polygon-information.search-icon.settings-icon.settings-modal.solar-expert.solar-system-form.tool-box.undo-icon.entry.esm.js.map +1 -1
  48. package/dist/stencil-library/{p-91bf731c.entry.js → p-74e0c2f0.entry.js} +2 -2
  49. package/dist/stencil-library/{p-f85ca33a.entry.js → p-7e0b62d2.entry.js} +2 -2
  50. package/dist/stencil-library/p-e423f7bb.entry.js +2 -0
  51. package/dist/stencil-library/p-e423f7bb.entry.js.map +1 -0
  52. package/dist/stencil-library/stencil-library.esm.js +1 -1
  53. package/package.json +1 -1
  54. package/dist/components/p-CQNcW74f.js.map +0 -1
  55. package/dist/components/p-DgWwkE8N.js.map +0 -1
  56. package/dist/stencil-library/p-c96335dc.entry.js +0 -2
  57. package/dist/stencil-library/p-c96335dc.entry.js.map +0 -1
  58. /package/dist/stencil-library/{p-91bf731c.entry.js.map → p-74e0c2f0.entry.js.map} +0 -0
  59. /package/dist/stencil-library/{p-f85ca33a.entry.js.map → p-7e0b62d2.entry.js.map} +0 -0
@@ -9,7 +9,7 @@ const LoadingWidget = class {
9
9
  index.registerInstance(this, hostRef);
10
10
  }
11
11
  render() {
12
- return (index.h("div", { key: '9352dcd45754fb5ce49405774a7cf16689ee8c10', class: "absolute flex items-center justify-center bg-muted bg-opacity-75 z-20 pt-7 rounded-4xl" }, index.h("div", { key: 'a8cb7bfccfd18837e44aa1ad437b94f2632e18ba', class: "animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-secondary" })));
12
+ return (index.h("div", { key: '53e8e35b4de7d6d272ca070f67a5fe266fa787f4', class: "absolute flex items-center justify-center bg-muted bg-opacity-75 z-20 pt-7 rounded-4xl" }, index.h("div", { key: '906b14debcd98b44be5547035b41d94cf8dc052f', class: "animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-secondary" })));
13
13
  }
14
14
  };
15
15
  LoadingWidget.style = outputCss;
@@ -210,7 +210,7 @@ const SolarCalculator = class {
210
210
  });
211
211
  }
212
212
  render() {
213
- return (index.h("div", { key: 'caa09baccc8825a26b3917be5123d0d25d4e55b0', class: "flex flex-col w-full h-full p-3" }, index.h("div", { key: '770f517caa0a3e92d4233b1d5e3d29a84b4674be', class: "pb-3" }, index.h("div", { key: '1e35a2da7b80bd678eaffb81f01baa18ca7a72cf', class: "relative" }, index.h("i", { key: 'e5cc8ff44508ace9147e90041fe3e817da9eff5d', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-text-placeholder " }), index.h("input", { key: '568e1e0dbdb207ca496062302bee33d4c3e726d6', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-border rounded-4xl focus:outline-none focus:ring-2 focus:ring-info bg-muted" }))), this.buildingInsights && (index.h("div", { key: 'f3669e7ef307e641867f18cdb07523a7ee4c5838' }, "buildingInsights", index.h("div", { key: '6fc1aa4732666fcb25c61c41871c0769897317d8' }, JSON.stringify(this.buildingInsights))))));
213
+ return (index.h("div", { key: 'b7e6c360cd1b155c37eb41c91724d2dc61034b15', class: "flex flex-col w-full h-full p-3" }, index.h("div", { key: 'e4db04c2ae45a3371013496ad656ce862f0b1b2a', class: "pb-3" }, index.h("div", { key: '56cc5e5db9c6c1a6edc3b4751e7f5187b6abf571', class: "relative" }, index.h("i", { key: '636aa61ed640439d9263f3a53041dc9a9e34a671', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-text-placeholder " }), index.h("input", { key: 'a502ea7fcf871e1e8a3eba531a7a4bd117bb6b03', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-border rounded-4xl focus:outline-none focus:ring-2 focus:ring-info bg-muted" }))), this.buildingInsights && (index.h("div", { key: 'd2b113dc19f6d42df8a2698aa870f6c3b2343168' }, "buildingInsights", index.h("div", { key: '7e3e814e8c001d63ac0c260e9d7aec64f801ca45' }, JSON.stringify(this.buildingInsights))))));
214
214
  }
215
215
  };
216
216
  SolarCalculator.style = outputCss;
@@ -624,20 +624,20 @@ export class MapDraw {
624
624
  const currentPolygon = this.getCurrentPolygon();
625
625
  return (h("div", { key: '8f3ead7eb4acb8b26cf9e8d3a7f9f1cb7027b06b', class: "flex flex-col justify-center items-center w-full h-full gap-4 bg-primary", id: "map-draw" }, this.showInstructions && !state.isMobile && (h("div", { key: '314f035a8f0bc087936041ec1249ddc12d27a43a', class: "w-full rounded-4xl p-4 bg-muted text-muted-foreground" }, t.mapDraw.instructions.parts.roof, " ", h("button", { key: '4b50b9afab6c7bfd180eedab22eaa7aed6346d26', class: "inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors", onClick: () => this.handleToolSelect(roofTool) }, h("icon-selector", { key: '980fb93346b72807638793a711c3adf4f6c60fb8', name: "house", inline: true })), " ", t.mapDraw.instructions.parts.obstruction, " ", h("button", { key: 'c1d0edac8cbb504c8db4c57d6bb078c4c2746cd9', class: "inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors", onClick: () => this.handleToolSelect(obstructionTool) }, h("icon-selector", { key: '12956e51ff2ed628980597746ee4853d93c7d19d', name: "octagon-minus", inline: true })), " ", t.mapDraw.instructions.parts.delete, " ", h("button", { key: 'fc0c507764c04fd1699024c00d708430a2275df1', class: "inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors", onClick: () => this.handleToolSelect(deleteTool) }, h("icon-selector", { key: 'aabac0ddf1c029655accf3f4812219cad3744da5', name: "eraser", inline: true })), " ", t.mapDraw.instructions.parts.move, " ", h("button", { key: '850f0261e7b1da12cc1cc2b81356ece9d8ea1df8', class: "inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors", onClick: () => this.handleToolSelect(moveTool) }, h("icon-selector", { key: 'a25004dca55e42a1e0f13806cdceb95d0f16c8b5', name: "move", inline: true })), " ", t.mapDraw.instructions.parts.end)), h("div", { key: '93e10a821a9d8ad5f6ad8c62bcf56a5c015ba6a3', class: "w-full flex flex-row justify-between items-center" }, !state.isMobile && (this.showInstructions
626
626
  ? (h("button", { class: "px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground", onClick: () => this.showInstructions = false }, t.mapDraw.instructions.hide))
627
- : (h("button", { class: "px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground", onClick: () => this.showInstructions = true }, t.mapDraw.instructions.show))), h("button", { key: '7f6ec4e11d855a38563b9bb8d56f6d4c215e78e9', class: "flex items-center gap-2 bg-muted p-2 rounded-4xl hover:bg-surface-hover text-muted-foreground", onClick: this.handleSettingsClick }, h("settings-icon", { key: '34055a481938812d55f65295b045879649f99c35' }))), h("div", { key: '3a4f6caf453ccde75e4a1b80fa1fc78c39c82206', class: "w-full" }, !state.isMobile && (h("tool-box", { key: '6f95e7ace22619ff9472220f8119f4187622060a', currentTool: this.currentTool, onToolSelect: (tool) => this.handleToolSelect(tool), undoCallback: () => this.undo() }))), this.loadingState === "empty" && (h("div", { key: '6849146204c0ce8c9a674e28325f0c98c57dc251', class: "w-full" }, h("p", { key: 'd9b52b653f98f4b2775c1c371d4e3a5f024a0242', class: "text-muted text-center flex items-center justify-center rounded-4xl p-4 w-full bg-text-secondary" }, t.mapDraw.noAddressSelected, " ", state.isIOS))), (state.latitude && state.longitude &&
628
- this.loadingState === "loading") && (h("div", { key: '56292468ddfd3e40e248da2b9dcc97e36a20db2b', class: "flex items-center justify-center w-full bg-opacity-75 z-20 pt-7 rounded-4xl" }, h("div", { key: '7d3b05876eb75257204db68c8664ab738fa31254', class: "animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-secondary" }))), h("div", { key: 'd3cfef0bc836e51cf831da3cb23b99b4a8b75f8e', class: "flex items-start justify-center h-full w-full bg-primary rounded-4xl" }, h("div", { key: '5241c4a2f9691ddf7e48360913c19bf355591a1f', class: "relative h-full flex items-center justify-center w-full rounded-4xl bg-secondary", style: {
627
+ : (h("button", { class: "px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground", onClick: () => this.showInstructions = true }, t.mapDraw.instructions.show))), h("button", { key: '7f6ec4e11d855a38563b9bb8d56f6d4c215e78e9', class: "flex items-center gap-2 bg-muted p-2 rounded-4xl hover:bg-surface-hover text-muted-foreground", onClick: this.handleSettingsClick }, h("settings-icon", { key: '34055a481938812d55f65295b045879649f99c35' }))), h("div", { key: '3a4f6caf453ccde75e4a1b80fa1fc78c39c82206', class: "w-full" }, !state.isMobile && (h("tool-box", { key: '6f95e7ace22619ff9472220f8119f4187622060a', currentTool: this.currentTool, onToolSelect: (tool) => this.handleToolSelect(tool), undoCallback: () => this.undo() }))), this.loadingState === "empty" && (h("div", { key: '6849146204c0ce8c9a674e28325f0c98c57dc251', class: "w-full" }, h("p", { key: 'd9b52b653f98f4b2775c1c371d4e3a5f024a0242', class: "text-muted text-center flex items-center justify-center rounded-4xl p-4 w-full bg-text-secondary" }, t.mapDraw.noAddressSelected))), (state.latitude && state.longitude &&
628
+ this.loadingState === "loading") && (h("div", { key: '7507c117e5816158b407b506b2e2280de4979009', class: "flex items-center justify-center w-full bg-opacity-75 z-20 pt-7 rounded-4xl" }, h("div", { key: 'fc8351bd8d0c3f4f18d1ca5a6ed360f6d647c219', class: "animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-secondary" }))), h("div", { key: '6f90d40009a0e8ceba3b94c4bd1b1c2e32962168', class: "flex items-start justify-center h-full w-full bg-primary rounded-4xl" }, h("div", { key: '256ee7feb26d9045312c588888dddc5db72eaeaa', class: "relative h-full flex items-center justify-center w-full rounded-4xl bg-secondary", style: {
629
629
  aspectRatio: this.rgbTiff
630
630
  ? `${this.rgbTiff.width}/${this.rgbTiff.height}`
631
631
  : "1/1",
632
- } }, h("canvas", { key: '0d94bed2a7bb1a6f3db68db0d6f5817b1e73dcbb', ref: (el) => this.canvasElement = el, class: "absolute top-0 left-0 w-full h-full rounded-4xl", id: "map-draw-canvas", style: {
632
+ } }, h("canvas", { key: 'e4d3790a48ca3bb05106c93c1a0753e42168a6f0', ref: (el) => this.canvasElement = el, class: "absolute top-0 left-0 w-full h-full rounded-4xl", id: "map-draw-canvas", style: {
633
633
  cursor: this.currentTool.cursor,
634
- } }), h("canvas", { key: '31d17f7e2df707242742438400f05c9ea797f3a7', ref: (el) => this.polygonCanvas = el, class: "absolute top-0 left-0 w-full h-full rounded-4xl", style: {
634
+ } }), h("canvas", { key: '7831fb29a9b4bf1f396577ed9d2385dea40b4539', ref: (el) => this.polygonCanvas = el, class: "absolute top-0 left-0 w-full h-full rounded-4xl", style: {
635
635
  cursor: this.currentTool.cursor,
636
- } }))), currentPolygon?.closed && (h("div", { key: '4191ce792a784533f1eb3fac2b7b2e228ed972dc', class: "w-full" }, h("polygon-buttons", { key: '79393fad3f34afd22819420a64b5d5f60fc971e0', currentTool: this.currentTool.name, calculateSolarPanels: () => this.calculateSolarPanels(), selectEdgeTool: () => this.handleToolSelect(markRoofEdgeTool) }))), !state.isMobile && (h("div", { key: '2da231f3486711b9bd4fa3bbd03b5164557c0004', class: "w-full" }, h("polygon-information", { key: '8f56db238ea6e99640e5e49cbfd1caa22048b486', currentPolygon: currentPolygon, positionedPanels: currentPolygon
636
+ } }))), currentPolygon?.closed && (h("div", { key: 'e703e5a2313f55d0dc08b8f44d63f469a91fd724', class: "w-full" }, h("polygon-buttons", { key: '1d679142b0f2223a76e29db21949841b94c96f81', currentTool: this.currentTool.name, calculateSolarPanels: () => this.calculateSolarPanels(), selectEdgeTool: () => this.handleToolSelect(markRoofEdgeTool) }))), !state.isMobile && (h("div", { key: 'bccf61ba5a86ad1b44a5b46d8c2b2027022dd8ba', class: "w-full" }, h("polygon-information", { key: 'bbd60623873d8c2249c5d7ab74e03a4bade998be', currentPolygon: currentPolygon, positionedPanels: currentPolygon
637
637
  ? this
638
638
  .roofPolygonsSolarPanels[currentPolygon._id]
639
639
  ?.positionedPanels
640
- : undefined, handleAzimuthChange: (event) => this.handleAzimuthChange(event), handlePitchChange: (event) => this.handlePitchChange(event), calculateSolarPanels: () => this.calculateSolarPanels() }))), h("div", { key: '8c7ade957185b4f30f08d0cd57cb8fe311c1c120', class: "w-full" }, h("solar-system-form", { key: '61a6f2f4cf2d24eefa4356f245b9623ccf29c59e', systemConfigs: this.roofPolygonsSolarPanels, roofPolygons: this.roofPolygons, obstructionPolygons: this.obstructionPolygons })), this.showSettings && (h("settings-modal", { key: 'c3eb531b9c988a1e16b80e60575d670d5d663046', settings: state.settings, onClose: this.handleSettingsClose, onSave: this.handleSettingsSave }))));
640
+ : undefined, handleAzimuthChange: (event) => this.handleAzimuthChange(event), handlePitchChange: (event) => this.handlePitchChange(event), calculateSolarPanels: () => this.calculateSolarPanels() }))), h("div", { key: '9b804506b0ed890f99ceaba92f18c87b06951728', class: "w-full" }, h("solar-system-form", { key: '5383943dde347f1b75f919f4817a8d33b4b66b92', systemConfigs: this.roofPolygonsSolarPanels, roofPolygons: this.roofPolygons, obstructionPolygons: this.obstructionPolygons })), this.showSettings && (h("settings-modal", { key: '2397b2ab774504e514db8b0fd9537d124dcb17ed', settings: state.settings, onClose: this.handleSettingsClose, onSave: this.handleSettingsSave }))));
641
641
  }
642
642
  static get is() { return "map-draw"; }
643
643
  static get originalStyleUrls() {
@@ -1 +1 @@
1
- {"version":3,"file":"map-draw.js","sourceRoot":"","sources":["../../../src/components/map-draw/map-draw.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Component,\r\n Element,\r\n h,\r\n Listen,\r\n Prop,\r\n State,\r\n Watch,\r\n} from \"@stencil/core\";\r\n\r\nimport {\r\n renderCombinedWithZoom,\r\n renderSolarPanel,\r\n} from \"../../utils/visualize\";\r\nimport {\r\n BuildingInsightsResponse,\r\n GeoTiff,\r\n SolarPanelType,\r\n} from \"../../utils/solar\";\r\nimport { fetchSolarData, getBuildingImages } from \"../../utils/api\";\r\nimport { drawPolygon, isPointInPolygon } from \"../../utils/render/polygon\";\r\nimport { projectPointPerpendicularToLine } from \"../../utils/render/projection\";\r\nimport { Point, Polygon, SelectedPolygon } from \"../../types/shapes\";\r\nimport {\r\n deleteTool,\r\n markRoofEdgeTool,\r\n moveTool,\r\n obstructionTool,\r\n roofTool,\r\n Tool,\r\n tools,\r\n} from \"../../utils/render/tools\";\r\nimport {\r\n DEFAULT_SOLAR_EXPERT_CONFIG,\r\n DEFAULT_SOLAR_PANEL_TYPE,\r\n SolarExpertConfig,\r\n} from \"../../config\";\r\nimport { getFillColor } from \"../../utils/render/color\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport { calculatePolygonArea, getPixelInMeters } from \"../../utils/utils\";\r\nimport {\r\n getBestFittingRoofSegment,\r\n SolarPanelSystemPart,\r\n} from \"../../utils/geometry/fitting\";\r\nimport { getOptimalSolarPositionFully } from \"../../utils/geometry/gridMatch\";\r\nimport { BORDER_INSET, DEFAULT_SUNNINESS } from \"../../constants\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\nimport { onChange, Settings, state } from \"../../store\";\r\n\r\n@Component({\r\n tag: \"map-draw\",\r\n styleUrl: \"../../output.css\",\r\n shadow: false,\r\n})\r\nexport class MapDraw {\r\n @Prop()\r\n apiKey: string = \"\";\r\n @Prop()\r\n config: SolarExpertConfig = DEFAULT_SOLAR_EXPERT_CONFIG;\r\n @Prop()\r\n solarPanel: SolarPanelType = DEFAULT_SOLAR_PANEL_TYPE;\r\n\r\n @State()\r\n showInstructions: boolean = true;\r\n @State()\r\n showSettings: boolean = false;\r\n @State()\r\n zoom: number = 1;\r\n @State()\r\n loadingState: \"empty\" | \"loading\" | \"loaded\" = \"empty\";\r\n @State()\r\n rgbTiff: GeoTiff | null = null;\r\n @State()\r\n draggedPointIndex: number | null = null;\r\n @State()\r\n hoveredPointIndex: number | null = null;\r\n @State()\r\n hoveredPolygon: SelectedPolygon | null = null;\r\n @State()\r\n shiftKeyPressed: boolean = false;\r\n @State()\r\n altKeyPressed: boolean = false;\r\n @State()\r\n mousePoint: Point | null = null;\r\n @State()\r\n currentTool: Tool = roofTool;\r\n @State()\r\n roofPolygons: { [id: string]: Polygon } = {};\r\n @State()\r\n roofPolygonsSolarPanels: { [id: string]: SolarPanelSystemPart } = {};\r\n @State()\r\n obstructionPolygons: { [id: string]: Polygon } = {};\r\n @State()\r\n selectedPolygon: SelectedPolygon | null = null;\r\n @State()\r\n buildingInsights: BuildingInsightsResponse | null = null;\r\n @State()\r\n pixelInMeters: number = 0.2;\r\n @State()\r\n isMobile: boolean = false;\r\n @State()\r\n highlightedEdge: { pointA: Point; pointB: Point } | null = null;\r\n\r\n @Element()\r\n el: HTMLElement;\r\n private canvasElement?: HTMLCanvasElement;\r\n private polygonCanvas?: HTMLCanvasElement;\r\n private polygonCtx?: CanvasRenderingContext2D;\r\n\r\n private getCurrentPolygon(): Polygon | null {\r\n if (!this.selectedPolygon) {\r\n return null;\r\n }\r\n const { _id, type } = this.selectedPolygon;\r\n return type === \"roof\"\r\n ? this.roofPolygons[_id]\r\n : this.obstructionPolygons[_id];\r\n }\r\n\r\n componentWillLoad() {\r\n onChange(\"latitude\", () => {\r\n this.getBuildingImages();\r\n this.getBuildingInsights();\r\n });\r\n onChange(\"longitude\", () => {\r\n this.getBuildingImages();\r\n this.getBuildingInsights();\r\n });\r\n }\r\n\r\n componentDidLoad() {\r\n if (state.latitude && state.longitude) {\r\n this.loadingState = \"loading\";\r\n this.getBuildingInsights();\r\n this.getBuildingImages();\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n if (this.canvasElement) {\r\n const rect = this.canvasElement.getBoundingClientRect();\r\n this.canvasElement.width = rect.width;\r\n this.canvasElement.height = rect.height;\r\n this.drawMap();\r\n }\r\n });\r\n }\r\n\r\n private sizeCanvas(width: number, height: number) {\r\n if (this.canvasElement) {\r\n this.canvasElement.width = width;\r\n this.canvasElement.height = height;\r\n }\r\n if (this.polygonCanvas) {\r\n this.polygonCanvas.width = width;\r\n this.polygonCanvas.height = height;\r\n this.polygonCtx = this.polygonCanvas.getContext(\"2d\");\r\n }\r\n }\r\n\r\n async getBuildingInsights() {\r\n if (!state.latitude || !state.longitude) {\r\n return;\r\n }\r\n this.loadingState = \"loading\";\r\n\r\n if (this.buildingInsights) {\r\n const sameLocation =\r\n this.buildingInsights.center.latitude === state.latitude &&\r\n this.buildingInsights.center.longitude === state.longitude;\r\n if (sameLocation) {\r\n return;\r\n }\r\n this.obstructionPolygons = {};\r\n this.roofPolygons = {};\r\n this.selectedPolygon = null;\r\n this.hoveredPolygon = null;\r\n this.canvasElement.getContext(\"2d\")?.clearRect(\r\n 0,\r\n 0,\r\n this.canvasElement.width,\r\n this.canvasElement.height,\r\n );\r\n this.polygonCtx?.clearRect(\r\n 0,\r\n 0,\r\n this.polygonCanvas.width,\r\n this.polygonCanvas.height,\r\n );\r\n this.rgbTiff = null;\r\n }\r\n this.buildingInsights = await fetchSolarData(\r\n state.latitude,\r\n state.longitude,\r\n this.apiKey,\r\n );\r\n if (!this.buildingInsights) {\r\n alert(\"No building insights found. Please enter them manually.\");\r\n }\r\n\r\n // If on mobile, automatically calculate panels using Google API data\r\n if (state.isMobile && this.buildingInsights) {\r\n const maxPanels =\r\n this.buildingInsights.solarPotential.maxArrayPanelsCount;\r\n const approximatedPanels = Math.floor(maxPanels * 3 / 4); // Use two thirds of max panels\r\n\r\n const positionedPanels = Array(approximatedPanels).fill(null)\r\n .map((_, __) => ({\r\n panel: this.solarPanel,\r\n pixelPosition: {\r\n x: -1,\r\n y: -1,\r\n },\r\n horizontal: true,\r\n rotation: 0,\r\n }));\r\n\r\n this.roofPolygonsSolarPanels = {\r\n ...this.roofPolygonsSolarPanels,\r\n [\"mobile-panels\"]: {\r\n positionedPanels,\r\n sunniness:\r\n this.buildingInsights.solarPotential.buildingStats\r\n .sunshineQuantiles[5] ?? DEFAULT_SUNNINESS,\r\n },\r\n };\r\n }\r\n }\r\n\r\n async getBuildingImages() {\r\n if (!state.latitude || !state.longitude) {\r\n return;\r\n }\r\n if (this.buildingInsights) {\r\n const sameLocation =\r\n this.buildingInsights.center.latitude === state.latitude &&\r\n this.buildingInsights.center.longitude === state.longitude;\r\n if (sameLocation) {\r\n return;\r\n }\r\n }\r\n this.rgbTiff = await getBuildingImages(\r\n state.latitude,\r\n state.longitude,\r\n this.apiKey,\r\n state.radiusMeters,\r\n );\r\n this.pixelInMeters = getPixelInMeters(this.rgbTiff);\r\n this.loadingState = \"loaded\";\r\n }\r\n\r\n private convertToCanvasCoordinates(event: MouseEvent): Point {\r\n const rect = this.polygonCanvas.getBoundingClientRect();\r\n const siteX = event.clientX - rect.left;\r\n const siteY = event.clientY - rect.top;\r\n return {\r\n x: siteX / (rect.right - rect.left) * this.canvasElement.width,\r\n y: siteY / (rect.bottom - rect.top) * this.canvasElement.height,\r\n };\r\n }\r\n\r\n @Watch(\"rgbTiff\")\r\n @Watch(\"buildingInsights\")\r\n @Watch(\"canvasElement\")\r\n async drawMap() {\r\n if (\r\n !this.canvasElement || !this.rgbTiff || !this.buildingInsights\r\n ) return;\r\n\r\n this.sizeCanvas(this.rgbTiff.width, this.rgbTiff.height);\r\n\r\n renderCombinedWithZoom({\r\n rgb: this.rgbTiff,\r\n zoom: this.zoom,\r\n canvas: this.canvasElement,\r\n });\r\n }\r\n\r\n @Listen(\"mousemove\", { target: \"document\" })\r\n handleMouseMove(event: MouseEvent) {\r\n if (state.isMobile) return; // Prevent interactions on mobile\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n\r\n // translate the website pixel coordinates to the canvas coordinates\r\n const { x, y } = this.convertToCanvasCoordinates(event);\r\n this.mousePoint = { x, y };\r\n\r\n const currentPolygon = this.getCurrentPolygon();\r\n let redraw = false;\r\n\r\n if (this.currentTool.name === \"markRoofEdge\") {\r\n let distances = [];\r\n for (let i = 0; i < currentPolygon?.points.length; i++) {\r\n const pointA = currentPolygon?.points[i];\r\n const pointB = currentPolygon\r\n ?.points[(i + 1) % currentPolygon?.points.length];\r\n const distanceA = Math.sqrt(\r\n Math.pow(x - pointA.x, 2) + Math.pow(y - pointA.y, 2),\r\n );\r\n const distanceB = Math.sqrt(\r\n Math.pow(x - pointB.x, 2) + Math.pow(y - pointB.y, 2),\r\n );\r\n const edgeLength = Math.sqrt(\r\n Math.pow(pointA.x - pointB.x, 2) +\r\n Math.pow(pointA.y - pointB.y, 2),\r\n );\r\n distances.push({\r\n dist: distanceA + distanceB - edgeLength,\r\n edge: { pointA, pointB },\r\n });\r\n }\r\n const closestEdge = distances.sort((a, b) => a.dist - b.dist)[0];\r\n if (closestEdge && (closestEdge.dist < 10)) {\r\n this.highlightedEdge = closestEdge.edge;\r\n redraw = true;\r\n } else if (this.highlightedEdge) {\r\n this.highlightedEdge = null;\r\n redraw = true;\r\n }\r\n }\r\n\r\n // Check for point hover\r\n const newHoveredPointIndex = currentPolygon?.points.findIndex(\r\n (point) => {\r\n const distance = Math.sqrt(\r\n Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2),\r\n );\r\n return distance < 10;\r\n },\r\n );\r\n\r\n // Check for polygon hover\r\n let newHoveredPolygon = null;\r\n for (const polygon of Object.values(this.obstructionPolygons)) {\r\n if (isPointInPolygon({ x, y }, polygon)) {\r\n newHoveredPolygon = { _id: polygon._id, type: \"obstruction\" };\r\n break;\r\n }\r\n }\r\n // obstruction polygons get priority\r\n if (!newHoveredPolygon) {\r\n for (const polygon of Object.values(this.roofPolygons)) {\r\n if (isPointInPolygon({ x, y }, polygon)) {\r\n newHoveredPolygon = { _id: polygon._id, type: \"roof\" };\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // Only redraw if hover state changed\r\n if (\r\n this.hoveredPolygon ||\r\n newHoveredPointIndex !== this.hoveredPointIndex ||\r\n JSON.stringify(newHoveredPolygon) !==\r\n JSON.stringify(this.hoveredPolygon)\r\n ) {\r\n this.hoveredPointIndex = newHoveredPointIndex;\r\n this.hoveredPolygon = newHoveredPolygon;\r\n redraw = true;\r\n }\r\n\r\n // Handle dragging\r\n if (\r\n this.draggedPointIndex !== null && currentPolygon &&\r\n this.currentTool.name === \"move\"\r\n ) {\r\n currentPolygon.points[this.draggedPointIndex] = { x, y };\r\n // Recalculate area if this is a roof polygon\r\n if (currentPolygon.type === \"roof\" && currentPolygon.closed) {\r\n const metersInPixels = 1 / this.pixelInMeters;\r\n const area = calculatePolygonArea(currentPolygon.points) /\r\n (metersInPixels * metersInPixels);\r\n currentPolygon.details.area = area;\r\n }\r\n redraw = true;\r\n }\r\n\r\n if (this.shiftKeyPressed) {\r\n redraw = true;\r\n }\r\n\r\n if (redraw) {\r\n this.drawPolygons();\r\n }\r\n }\r\n\r\n private drawPolygons() {\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n\r\n // Clear the canvas and redraw the map\r\n this.polygonCtx.clearRect(\r\n 0,\r\n 0,\r\n this.polygonCanvas.width,\r\n this.polygonCanvas.height,\r\n );\r\n\r\n // draw roof polygons\r\n for (const polygon of Object.values(this.roofPolygons)) {\r\n const fillColor = getFillColor(\r\n this.selectedPolygon,\r\n this.hoveredPolygon,\r\n polygon._id,\r\n polygon,\r\n this.config,\r\n );\r\n\r\n drawPolygon({\r\n polygonCtx: this.polygonCtx,\r\n polygonCanvas: this.polygonCanvas,\r\n polygon,\r\n strokeColor: polygon.closed\r\n ? this.config.closedRoofColor\r\n : this.config.openRoofColor,\r\n fillColor,\r\n pixelInMeters: this.pixelInMeters,\r\n shiftKeyPressed: this.shiftKeyPressed,\r\n mousePoint: this.mousePoint,\r\n highlightColor: this.config.highlightColor,\r\n highlightedEdge: this.highlightedEdge,\r\n });\r\n\r\n const solarPanels = this.roofPolygonsSolarPanels[polygon._id];\r\n const convertedSolarPanel: SolarPanelType = {\r\n ...this.solarPanel,\r\n widthMeters: this.solarPanel.widthMeters / this.pixelInMeters,\r\n heightMeters: this.solarPanel.heightMeters / this.pixelInMeters,\r\n };\r\n if (solarPanels) {\r\n for (const panel of solarPanels.positionedPanels) {\r\n renderSolarPanel(\r\n panel,\r\n this.polygonCtx,\r\n convertedSolarPanel.widthMeters,\r\n convertedSolarPanel.heightMeters,\r\n polygon.details?.azimuth,\r\n polygon.details?.pitch,\r\n );\r\n }\r\n }\r\n }\r\n\r\n // draw obstruction polygons\r\n for (const polygon of Object.values(this.obstructionPolygons)) {\r\n const fillColor = getFillColor(\r\n this.selectedPolygon,\r\n this.hoveredPolygon,\r\n polygon._id,\r\n polygon,\r\n this.config,\r\n );\r\n\r\n drawPolygon({\r\n polygonCtx: this.polygonCtx,\r\n polygonCanvas: this.polygonCanvas,\r\n polygon,\r\n pixelInMeters: this.pixelInMeters,\r\n shiftKeyPressed: this.shiftKeyPressed,\r\n mousePoint: this.mousePoint,\r\n strokeColor: polygon.closed\r\n ? this.config.closedObstructionColor\r\n : this.config.openObstructionColor,\r\n fillColor,\r\n highlightColor: this.config.highlightColor,\r\n });\r\n }\r\n }\r\n\r\n private deletePolygon(_id: string) {\r\n if (this.selectedPolygon?._id === _id) {\r\n this.selectedPolygon = null;\r\n }\r\n if (this.roofPolygons[_id]) {\r\n delete this.roofPolygons[_id];\r\n delete this.roofPolygonsSolarPanels[_id];\r\n }\r\n if (this.obstructionPolygons[_id]) {\r\n delete this.obstructionPolygons[_id];\r\n }\r\n }\r\n\r\n @Listen(\"keydown\", { target: \"document\" })\r\n handleKeyDown(event: KeyboardEvent) {\r\n if (event.target instanceof HTMLInputElement) {\r\n return;\r\n }\r\n // Handle shift key for perpendicular points\r\n if (event.shiftKey && !this.shiftKeyPressed) {\r\n this.shiftKeyPressed = true;\r\n this.drawPolygons();\r\n return;\r\n }\r\n if (event.altKey && !this.altKeyPressed) {\r\n this.altKeyPressed = true;\r\n return;\r\n }\r\n if (\r\n (event.key === \"Delete\" || event.key === \"Backspace\") &&\r\n this.selectedPolygon\r\n ) {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (currentPolygon.closed) {\r\n this.deletePolygon(currentPolygon._id);\r\n this.drawPolygons();\r\n return;\r\n }\r\n currentPolygon.points.pop();\r\n this.drawPolygons();\r\n return;\r\n }\r\n\r\n // Handle tool selection shortcuts\r\n const pressedKey = event.key.toLowerCase();\r\n const tool = tools.find((t) =>\r\n t.keyboardShortcut?.toLowerCase() === pressedKey\r\n );\r\n if (tool) {\r\n this.currentTool = tool;\r\n }\r\n }\r\n\r\n @Listen(\"keyup\", { target: \"document\" })\r\n handleKeyUp(event: KeyboardEvent) {\r\n if (!event.shiftKey && this.shiftKeyPressed) {\r\n this.shiftKeyPressed = false;\r\n this.drawPolygons();\r\n }\r\n if (!event.altKey && this.altKeyPressed) {\r\n this.altKeyPressed = false;\r\n }\r\n }\r\n\r\n private undo() {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (!currentPolygon) {\r\n return;\r\n }\r\n if (currentPolygon.closed) {\r\n currentPolygon.closed = false;\r\n if (currentPolygon.type === \"roof\") {\r\n delete this.roofPolygonsSolarPanels[currentPolygon._id];\r\n this.currentTool = roofTool;\r\n this.highlightedEdge = null;\r\n } else if (currentPolygon.type === \"obstruction\") {\r\n this.currentTool = obstructionTool;\r\n }\r\n } else {\r\n currentPolygon.points.pop();\r\n }\r\n this.drawPolygons();\r\n }\r\n\r\n @Listen(\"mousedown\", { target: \"document\" })\r\n handleMouseDown(event: MouseEvent) {\r\n if (this.currentTool.name === \"undo\") {\r\n return;\r\n }\r\n if (state.isMobile) return; // Prevent interactions on mobile\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n if (!this.polygonCanvas.contains(event.target as Node)) return;\r\n\r\n let { x, y } = this.convertToCanvasCoordinates(event);\r\n\r\n if (this.currentTool.name === \"markRoofEdge\") {\r\n if (!this.highlightedEdge) {\r\n return;\r\n }\r\n const x = this.highlightedEdge.pointA.x -\r\n this.highlightedEdge.pointB.x;\r\n const y = this.highlightedEdge.pointA.y -\r\n this.highlightedEdge.pointB.y;\r\n const azimuth = Math.atan2(-x, y) * (180 / Math.PI);\r\n this.calculateSolarPanels();\r\n this.handleAzimuthChange({\r\n target: {\r\n value: azimuth,\r\n },\r\n } as unknown as Event);\r\n return;\r\n }\r\n if (this.currentTool.name === \"delete\") {\r\n if (!this.hoveredPolygon) {\r\n return;\r\n }\r\n const { _id, type } = this.hoveredPolygon;\r\n if (type === \"roof\") {\r\n delete this.roofPolygons[_id];\r\n delete this.roofPolygonsSolarPanels[_id];\r\n } else if (type === \"obstruction\") {\r\n delete this.obstructionPolygons[_id];\r\n }\r\n this.hoveredPolygon = null;\r\n if (this.selectedPolygon?._id === _id) {\r\n this.selectedPolygon = null;\r\n }\r\n this.drawPolygons();\r\n return;\r\n }\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (this.currentTool.name === \"move\") {\r\n // Check if we're clicking on a point of the selected polygon\r\n if (this.selectedPolygon) {\r\n const pointIndex = currentPolygon?.points.findIndex((point) => {\r\n const distance = Math.sqrt(\r\n Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2),\r\n );\r\n return distance < 10;\r\n });\r\n if (pointIndex !== undefined && pointIndex !== -1) {\r\n this.draggedPointIndex = pointIndex;\r\n return;\r\n }\r\n\r\n if (this.hoveredPolygon) {\r\n this.selectedPolygon = this.hoveredPolygon;\r\n return;\r\n }\r\n }\r\n this.selectedPolygon = null;\r\n this.drawPolygons();\r\n return;\r\n }\r\n if (\r\n !this.selectedPolygon || currentPolygon?.closed ||\r\n this.currentTool.name !== this.selectedPolygon?.type\r\n ) {\r\n // no polygon is active, create a new one\r\n const newPolygon: Polygon = {\r\n _id: uuidv4(),\r\n points: [{ x, y }],\r\n type: this.currentTool.name,\r\n closed: false,\r\n };\r\n let _id;\r\n if (this.currentTool.name === \"roof\") {\r\n this.roofPolygons = {\r\n ...this.roofPolygons,\r\n [newPolygon._id]: newPolygon,\r\n };\r\n _id = newPolygon._id;\r\n } else if (this.currentTool.name === \"obstruction\") {\r\n this.obstructionPolygons = {\r\n ...this.obstructionPolygons,\r\n [newPolygon._id]: newPolygon,\r\n };\r\n _id = newPolygon._id;\r\n }\r\n this.selectedPolygon = { _id, type: this.currentTool.name };\r\n this.drawPolygons();\r\n return;\r\n }\r\n\r\n if (currentPolygon.closed) {\r\n return;\r\n }\r\n\r\n // If we have at least one point, check if we're clicking near the first point\r\n if (currentPolygon.points.length > 2) {\r\n const firstPoint = currentPolygon.points[0];\r\n const distance = Math.sqrt(\r\n Math.pow(x - firstPoint.x, 2) + Math.pow(y - firstPoint.y, 2),\r\n );\r\n\r\n if (distance < 10) {\r\n this.closePolygon();\r\n return;\r\n }\r\n }\r\n\r\n // Handle shift key for perpendicular points\r\n if (event.shiftKey && currentPolygon?.points.length >= 2) {\r\n const projectedPoint = projectPointPerpendicularToLine({\r\n x,\r\n y,\r\n lastPoint:\r\n currentPolygon.points[currentPolygon.points.length - 1],\r\n secondLastPoint:\r\n currentPolygon.points[currentPolygon.points.length - 2],\r\n });\r\n x = projectedPoint.x;\r\n y = projectedPoint.y;\r\n }\r\n\r\n currentPolygon.points = [...currentPolygon.points, { x, y }];\r\n this.drawPolygons();\r\n }\r\n\r\n @Listen(\"mouseup\", { target: \"document\" })\r\n handleMouseUp() {\r\n this.draggedPointIndex = null;\r\n }\r\n\r\n private closePolygon() {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (\r\n currentPolygon.points.length >= 3 &&\r\n (this.currentTool.name === \"roof\" ||\r\n this.currentTool.name === \"obstruction\")\r\n ) {\r\n currentPolygon.closed = true;\r\n }\r\n\r\n if (currentPolygon.type === \"roof\") {\r\n // Calculate basic polygon details\r\n const metersInPixels = 1 / this.pixelInMeters;\r\n const area = calculatePolygonArea(currentPolygon.points) /\r\n (metersInPixels * metersInPixels);\r\n const bestMatch = getBestFittingRoofSegment(\r\n currentPolygon,\r\n this.buildingInsights?.solarPotential.roofSegmentStats,\r\n this.rgbTiff.bounds,\r\n this.canvasElement,\r\n );\r\n\r\n if (bestMatch) {\r\n currentPolygon.details = {\r\n area,\r\n azimuth: bestMatch.azimuthDegrees,\r\n pitch: bestMatch.pitchDegrees,\r\n };\r\n } else {\r\n currentPolygon.details = {\r\n area,\r\n azimuth: 0,\r\n pitch: 0,\r\n };\r\n }\r\n\r\n this.scrollToCanvas();\r\n }\r\n\r\n this.drawPolygons();\r\n this.currentTool = moveTool;\r\n }\r\n\r\n private calculateSolarPanels({ redraw = true }: { redraw?: boolean } = {}) {\r\n const currentPolygon = this.getCurrentPolygon();\r\n\r\n if (!currentPolygon.details) {\r\n return;\r\n }\r\n\r\n if (this.roofPolygonsSolarPanels[currentPolygon._id]) {\r\n delete this.roofPolygonsSolarPanels[currentPolygon._id];\r\n }\r\n\r\n const convertedSolarPanel: SolarPanelType = {\r\n ...this.solarPanel,\r\n widthMeters: this.solarPanel.widthMeters / this.pixelInMeters,\r\n heightMeters: this.solarPanel.heightMeters / this.pixelInMeters,\r\n };\r\n const inset = BORDER_INSET / this.pixelInMeters;\r\n const solarPanels = getOptimalSolarPositionFully(\r\n currentPolygon,\r\n Object.values(this.obstructionPolygons),\r\n convertedSolarPanel,\r\n currentPolygon.details?.azimuth,\r\n inset,\r\n currentPolygon.details?.pitch,\r\n );\r\n this.roofPolygonsSolarPanels = {\r\n ...this.roofPolygonsSolarPanels,\r\n [currentPolygon._id]: {\r\n positionedPanels: solarPanels,\r\n sunniness: currentPolygon.details?.assignedRoofStats?.stats\r\n .sunshineQuantiles[5] ??\r\n this.buildingInsights.solarPotential.buildingStats\r\n .sunshineQuantiles[5] ??\r\n DEFAULT_SUNNINESS,\r\n },\r\n };\r\n if (redraw) {\r\n this.drawPolygons();\r\n }\r\n }\r\n\r\n private handlePitchChange(event: Event) {\r\n const target = event.target as HTMLInputElement;\r\n const pitch = parseFloat(target.value);\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (currentPolygon) {\r\n this.roofPolygons[currentPolygon._id].details.pitch = pitch;\r\n }\r\n if (\r\n currentPolygon.type === \"roof\" &&\r\n this.roofPolygonsSolarPanels[currentPolygon._id]\r\n ) {\r\n this.calculateSolarPanels();\r\n return;\r\n }\r\n }\r\n\r\n private handleAzimuthChange(event: Event) {\r\n const target = event.target as HTMLInputElement;\r\n const azimuth = parseFloat(target.value);\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (currentPolygon) {\r\n this.roofPolygons[currentPolygon._id].details.azimuth = azimuth;\r\n }\r\n if (\r\n currentPolygon.type === \"roof\" &&\r\n this.roofPolygonsSolarPanels[currentPolygon._id]\r\n ) {\r\n this.calculateSolarPanels();\r\n return;\r\n }\r\n }\r\n\r\n private handleToolSelect(tool: Tool) {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (\r\n currentPolygon && !currentPolygon.closed &&\r\n currentPolygon.points.length > 0\r\n ) {\r\n alert(\"Please close the polygon before selecting a tool\");\r\n // TODO translate\r\n return;\r\n }\r\n this.currentTool = tool;\r\n }\r\n\r\n private scrollToCanvas() {\r\n const canvasElement = this.el.querySelector(\"#map-draw-canvas\");\r\n if (canvasElement) {\r\n canvasElement.scrollIntoView({ behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n private handleSettingsClick = () => {\r\n this.showSettings = true;\r\n };\r\n\r\n private handleSettingsClose = () => {\r\n this.showSettings = false;\r\n };\r\n\r\n private handleSettingsSave = (event: CustomEvent<Settings>) => {\r\n state.settings = event.detail;\r\n state.settingsVersion++;\r\n };\r\n\r\n render() {\r\n const t = getLanguageStrings(state.settings.language);\r\n const currentPolygon = this.getCurrentPolygon();\r\n return (\r\n <div\r\n class=\"flex flex-col justify-center items-center w-full h-full gap-4 bg-primary\"\r\n id=\"map-draw\"\r\n >\r\n {this.showInstructions && !state.isMobile && (\r\n <div class=\"w-full rounded-4xl p-4 bg-muted text-muted-foreground\">\r\n {t.mapDraw.instructions.parts.roof}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() => this.handleToolSelect(roofTool)}\r\n >\r\n <icon-selector name=\"house\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.obstruction}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() =>\r\n this.handleToolSelect(obstructionTool)}\r\n >\r\n <icon-selector name=\"octagon-minus\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.delete}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() => this.handleToolSelect(deleteTool)}\r\n >\r\n <icon-selector name=\"eraser\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.move}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() => this.handleToolSelect(moveTool)}\r\n >\r\n <icon-selector name=\"move\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.end}\r\n </div>\r\n )}\r\n <div class=\"w-full flex flex-row justify-between items-center\">\r\n {!state.isMobile && (this.showInstructions\r\n ? (\r\n <button\r\n class=\"px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground\"\r\n onClick={() => this.showInstructions = false}\r\n >\r\n {t.mapDraw.instructions.hide}\r\n </button>\r\n )\r\n : (\r\n <button\r\n class=\"px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground\"\r\n onClick={() => this.showInstructions = true}\r\n >\r\n {t.mapDraw.instructions.show}\r\n </button>\r\n ))}\r\n <button\r\n class=\"flex items-center gap-2 bg-muted p-2 rounded-4xl hover:bg-surface-hover text-muted-foreground\"\r\n onClick={this.handleSettingsClick}\r\n >\r\n <settings-icon />\r\n </button>\r\n </div>\r\n <div class=\"w-full\">\r\n {!state.isMobile && (\r\n <tool-box\r\n currentTool={this.currentTool}\r\n onToolSelect={(tool) => this.handleToolSelect(tool)}\r\n undoCallback={() => this.undo()}\r\n />\r\n )}\r\n </div>\r\n {this.loadingState === \"empty\" && (\r\n <div class=\"w-full\">\r\n <p class=\"text-muted text-center flex items-center justify-center rounded-4xl p-4 w-full bg-text-secondary\">\r\n {t.mapDraw.noAddressSelected} {state.isIOS}\r\n </p>\r\n </div>\r\n )}\r\n {(state.latitude && state.longitude &&\r\n this.loadingState === \"loading\") && (\r\n <div class=\"flex items-center justify-center w-full bg-opacity-75 z-20 pt-7 rounded-4xl\">\r\n <div class=\"animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-secondary\">\r\n </div>\r\n </div>\r\n )}\r\n <div class=\"flex items-start justify-center h-full w-full bg-primary rounded-4xl\">\r\n <div\r\n class=\"relative h-full flex items-center justify-center w-full rounded-4xl bg-secondary\"\r\n style={{\r\n aspectRatio: this.rgbTiff\r\n ? `${this.rgbTiff.width}/${this.rgbTiff.height}`\r\n : \"1/1\",\r\n }}\r\n >\r\n <canvas\r\n ref={(el) => this.canvasElement = el}\r\n class=\"absolute top-0 left-0 w-full h-full rounded-4xl\"\r\n id=\"map-draw-canvas\"\r\n style={{\r\n cursor: this.currentTool.cursor,\r\n }}\r\n >\r\n </canvas>\r\n <canvas\r\n ref={(el) => this.polygonCanvas = el}\r\n class=\"absolute top-0 left-0 w-full h-full rounded-4xl\"\r\n style={{\r\n cursor: this.currentTool.cursor,\r\n }}\r\n >\r\n </canvas>\r\n </div>\r\n </div>\r\n {currentPolygon?.closed && (\r\n <div class=\"w-full\">\r\n <polygon-buttons\r\n currentTool={this.currentTool.name}\r\n calculateSolarPanels={() =>\r\n this.calculateSolarPanels()}\r\n selectEdgeTool={() =>\r\n this.handleToolSelect(markRoofEdgeTool)}\r\n />\r\n </div>\r\n )}\r\n {!state.isMobile && (\r\n <div class=\"w-full\">\r\n <polygon-information\r\n currentPolygon={currentPolygon}\r\n positionedPanels={currentPolygon\r\n ? this\r\n .roofPolygonsSolarPanels[currentPolygon._id]\r\n ?.positionedPanels\r\n : undefined}\r\n handleAzimuthChange={(event) =>\r\n this.handleAzimuthChange(event)}\r\n handlePitchChange={(event) =>\r\n this.handlePitchChange(event)}\r\n calculateSolarPanels={() =>\r\n this.calculateSolarPanels()}\r\n />\r\n </div>\r\n )}\r\n <div class=\"w-full\">\r\n <solar-system-form\r\n systemConfigs={this.roofPolygonsSolarPanels}\r\n roofPolygons={this.roofPolygons}\r\n obstructionPolygons={this.obstructionPolygons}\r\n />\r\n </div>\r\n {this.showSettings && (\r\n <settings-modal\r\n settings={state.settings}\r\n onClose={this.handleSettingsClose}\r\n onSave={this.handleSettingsSave}\r\n />\r\n )}\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"map-draw.js","sourceRoot":"","sources":["../../../src/components/map-draw/map-draw.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\r\n Component,\r\n Element,\r\n h,\r\n Listen,\r\n Prop,\r\n State,\r\n Watch,\r\n} from \"@stencil/core\";\r\n\r\nimport {\r\n renderCombinedWithZoom,\r\n renderSolarPanel,\r\n} from \"../../utils/visualize\";\r\nimport {\r\n BuildingInsightsResponse,\r\n GeoTiff,\r\n SolarPanelType,\r\n} from \"../../utils/solar\";\r\nimport { fetchSolarData, getBuildingImages } from \"../../utils/api\";\r\nimport { drawPolygon, isPointInPolygon } from \"../../utils/render/polygon\";\r\nimport { projectPointPerpendicularToLine } from \"../../utils/render/projection\";\r\nimport { Point, Polygon, SelectedPolygon } from \"../../types/shapes\";\r\nimport {\r\n deleteTool,\r\n markRoofEdgeTool,\r\n moveTool,\r\n obstructionTool,\r\n roofTool,\r\n Tool,\r\n tools,\r\n} from \"../../utils/render/tools\";\r\nimport {\r\n DEFAULT_SOLAR_EXPERT_CONFIG,\r\n DEFAULT_SOLAR_PANEL_TYPE,\r\n SolarExpertConfig,\r\n} from \"../../config\";\r\nimport { getFillColor } from \"../../utils/render/color\";\r\nimport { v4 as uuidv4 } from \"uuid\";\r\nimport { calculatePolygonArea, getPixelInMeters } from \"../../utils/utils\";\r\nimport {\r\n getBestFittingRoofSegment,\r\n SolarPanelSystemPart,\r\n} from \"../../utils/geometry/fitting\";\r\nimport { getOptimalSolarPositionFully } from \"../../utils/geometry/gridMatch\";\r\nimport { BORDER_INSET, DEFAULT_SUNNINESS } from \"../../constants\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\nimport { onChange, Settings, state } from \"../../store\";\r\n\r\n@Component({\r\n tag: \"map-draw\",\r\n styleUrl: \"../../output.css\",\r\n shadow: false,\r\n})\r\nexport class MapDraw {\r\n @Prop()\r\n apiKey: string = \"\";\r\n @Prop()\r\n config: SolarExpertConfig = DEFAULT_SOLAR_EXPERT_CONFIG;\r\n @Prop()\r\n solarPanel: SolarPanelType = DEFAULT_SOLAR_PANEL_TYPE;\r\n\r\n @State()\r\n showInstructions: boolean = true;\r\n @State()\r\n showSettings: boolean = false;\r\n @State()\r\n zoom: number = 1;\r\n @State()\r\n loadingState: \"empty\" | \"loading\" | \"loaded\" = \"empty\";\r\n @State()\r\n rgbTiff: GeoTiff | null = null;\r\n @State()\r\n draggedPointIndex: number | null = null;\r\n @State()\r\n hoveredPointIndex: number | null = null;\r\n @State()\r\n hoveredPolygon: SelectedPolygon | null = null;\r\n @State()\r\n shiftKeyPressed: boolean = false;\r\n @State()\r\n altKeyPressed: boolean = false;\r\n @State()\r\n mousePoint: Point | null = null;\r\n @State()\r\n currentTool: Tool = roofTool;\r\n @State()\r\n roofPolygons: { [id: string]: Polygon } = {};\r\n @State()\r\n roofPolygonsSolarPanels: { [id: string]: SolarPanelSystemPart } = {};\r\n @State()\r\n obstructionPolygons: { [id: string]: Polygon } = {};\r\n @State()\r\n selectedPolygon: SelectedPolygon | null = null;\r\n @State()\r\n buildingInsights: BuildingInsightsResponse | null = null;\r\n @State()\r\n pixelInMeters: number = 0.2;\r\n @State()\r\n isMobile: boolean = false;\r\n @State()\r\n highlightedEdge: { pointA: Point; pointB: Point } | null = null;\r\n\r\n @Element()\r\n el: HTMLElement;\r\n private canvasElement?: HTMLCanvasElement;\r\n private polygonCanvas?: HTMLCanvasElement;\r\n private polygonCtx?: CanvasRenderingContext2D;\r\n\r\n private getCurrentPolygon(): Polygon | null {\r\n if (!this.selectedPolygon) {\r\n return null;\r\n }\r\n const { _id, type } = this.selectedPolygon;\r\n return type === \"roof\"\r\n ? this.roofPolygons[_id]\r\n : this.obstructionPolygons[_id];\r\n }\r\n\r\n componentWillLoad() {\r\n onChange(\"latitude\", () => {\r\n this.getBuildingImages();\r\n this.getBuildingInsights();\r\n });\r\n onChange(\"longitude\", () => {\r\n this.getBuildingImages();\r\n this.getBuildingInsights();\r\n });\r\n }\r\n\r\n componentDidLoad() {\r\n if (state.latitude && state.longitude) {\r\n this.loadingState = \"loading\";\r\n this.getBuildingInsights();\r\n this.getBuildingImages();\r\n }\r\n\r\n requestAnimationFrame(() => {\r\n if (this.canvasElement) {\r\n const rect = this.canvasElement.getBoundingClientRect();\r\n this.canvasElement.width = rect.width;\r\n this.canvasElement.height = rect.height;\r\n this.drawMap();\r\n }\r\n });\r\n }\r\n\r\n private sizeCanvas(width: number, height: number) {\r\n if (this.canvasElement) {\r\n this.canvasElement.width = width;\r\n this.canvasElement.height = height;\r\n }\r\n if (this.polygonCanvas) {\r\n this.polygonCanvas.width = width;\r\n this.polygonCanvas.height = height;\r\n this.polygonCtx = this.polygonCanvas.getContext(\"2d\");\r\n }\r\n }\r\n\r\n async getBuildingInsights() {\r\n if (!state.latitude || !state.longitude) {\r\n return;\r\n }\r\n this.loadingState = \"loading\";\r\n\r\n if (this.buildingInsights) {\r\n const sameLocation =\r\n this.buildingInsights.center.latitude === state.latitude &&\r\n this.buildingInsights.center.longitude === state.longitude;\r\n if (sameLocation) {\r\n return;\r\n }\r\n this.obstructionPolygons = {};\r\n this.roofPolygons = {};\r\n this.selectedPolygon = null;\r\n this.hoveredPolygon = null;\r\n this.canvasElement.getContext(\"2d\")?.clearRect(\r\n 0,\r\n 0,\r\n this.canvasElement.width,\r\n this.canvasElement.height,\r\n );\r\n this.polygonCtx?.clearRect(\r\n 0,\r\n 0,\r\n this.polygonCanvas.width,\r\n this.polygonCanvas.height,\r\n );\r\n this.rgbTiff = null;\r\n }\r\n this.buildingInsights = await fetchSolarData(\r\n state.latitude,\r\n state.longitude,\r\n this.apiKey,\r\n );\r\n if (!this.buildingInsights) {\r\n alert(\"No building insights found. Please enter them manually.\");\r\n }\r\n\r\n // If on mobile, automatically calculate panels using Google API data\r\n if (state.isMobile && this.buildingInsights) {\r\n const maxPanels =\r\n this.buildingInsights.solarPotential.maxArrayPanelsCount;\r\n const approximatedPanels = Math.floor(maxPanels * 3 / 4); // Use two thirds of max panels\r\n\r\n const positionedPanels = Array(approximatedPanels).fill(null)\r\n .map((_, __) => ({\r\n panel: this.solarPanel,\r\n pixelPosition: {\r\n x: -1,\r\n y: -1,\r\n },\r\n horizontal: true,\r\n rotation: 0,\r\n }));\r\n\r\n this.roofPolygonsSolarPanels = {\r\n ...this.roofPolygonsSolarPanels,\r\n [\"mobile-panels\"]: {\r\n positionedPanels,\r\n sunniness:\r\n this.buildingInsights.solarPotential.buildingStats\r\n .sunshineQuantiles[5] ?? DEFAULT_SUNNINESS,\r\n },\r\n };\r\n }\r\n }\r\n\r\n async getBuildingImages() {\r\n if (!state.latitude || !state.longitude) {\r\n return;\r\n }\r\n if (this.buildingInsights) {\r\n const sameLocation =\r\n this.buildingInsights.center.latitude === state.latitude &&\r\n this.buildingInsights.center.longitude === state.longitude;\r\n if (sameLocation) {\r\n return;\r\n }\r\n }\r\n this.rgbTiff = await getBuildingImages(\r\n state.latitude,\r\n state.longitude,\r\n this.apiKey,\r\n state.radiusMeters,\r\n );\r\n this.pixelInMeters = getPixelInMeters(this.rgbTiff);\r\n this.loadingState = \"loaded\";\r\n }\r\n\r\n private convertToCanvasCoordinates(event: MouseEvent): Point {\r\n const rect = this.polygonCanvas.getBoundingClientRect();\r\n const siteX = event.clientX - rect.left;\r\n const siteY = event.clientY - rect.top;\r\n return {\r\n x: siteX / (rect.right - rect.left) * this.canvasElement.width,\r\n y: siteY / (rect.bottom - rect.top) * this.canvasElement.height,\r\n };\r\n }\r\n\r\n @Watch(\"rgbTiff\")\r\n @Watch(\"buildingInsights\")\r\n @Watch(\"canvasElement\")\r\n async drawMap() {\r\n if (\r\n !this.canvasElement || !this.rgbTiff || !this.buildingInsights\r\n ) return;\r\n\r\n this.sizeCanvas(this.rgbTiff.width, this.rgbTiff.height);\r\n\r\n renderCombinedWithZoom({\r\n rgb: this.rgbTiff,\r\n zoom: this.zoom,\r\n canvas: this.canvasElement,\r\n });\r\n }\r\n\r\n @Listen(\"mousemove\", { target: \"document\" })\r\n handleMouseMove(event: MouseEvent) {\r\n if (state.isMobile) return; // Prevent interactions on mobile\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n\r\n // translate the website pixel coordinates to the canvas coordinates\r\n const { x, y } = this.convertToCanvasCoordinates(event);\r\n this.mousePoint = { x, y };\r\n\r\n const currentPolygon = this.getCurrentPolygon();\r\n let redraw = false;\r\n\r\n if (this.currentTool.name === \"markRoofEdge\") {\r\n let distances = [];\r\n for (let i = 0; i < currentPolygon?.points.length; i++) {\r\n const pointA = currentPolygon?.points[i];\r\n const pointB = currentPolygon\r\n ?.points[(i + 1) % currentPolygon?.points.length];\r\n const distanceA = Math.sqrt(\r\n Math.pow(x - pointA.x, 2) + Math.pow(y - pointA.y, 2),\r\n );\r\n const distanceB = Math.sqrt(\r\n Math.pow(x - pointB.x, 2) + Math.pow(y - pointB.y, 2),\r\n );\r\n const edgeLength = Math.sqrt(\r\n Math.pow(pointA.x - pointB.x, 2) +\r\n Math.pow(pointA.y - pointB.y, 2),\r\n );\r\n distances.push({\r\n dist: distanceA + distanceB - edgeLength,\r\n edge: { pointA, pointB },\r\n });\r\n }\r\n const closestEdge = distances.sort((a, b) => a.dist - b.dist)[0];\r\n if (closestEdge && (closestEdge.dist < 10)) {\r\n this.highlightedEdge = closestEdge.edge;\r\n redraw = true;\r\n } else if (this.highlightedEdge) {\r\n this.highlightedEdge = null;\r\n redraw = true;\r\n }\r\n }\r\n\r\n // Check for point hover\r\n const newHoveredPointIndex = currentPolygon?.points.findIndex(\r\n (point) => {\r\n const distance = Math.sqrt(\r\n Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2),\r\n );\r\n return distance < 10;\r\n },\r\n );\r\n\r\n // Check for polygon hover\r\n let newHoveredPolygon = null;\r\n for (const polygon of Object.values(this.obstructionPolygons)) {\r\n if (isPointInPolygon({ x, y }, polygon)) {\r\n newHoveredPolygon = { _id: polygon._id, type: \"obstruction\" };\r\n break;\r\n }\r\n }\r\n // obstruction polygons get priority\r\n if (!newHoveredPolygon) {\r\n for (const polygon of Object.values(this.roofPolygons)) {\r\n if (isPointInPolygon({ x, y }, polygon)) {\r\n newHoveredPolygon = { _id: polygon._id, type: \"roof\" };\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // Only redraw if hover state changed\r\n if (\r\n this.hoveredPolygon ||\r\n newHoveredPointIndex !== this.hoveredPointIndex ||\r\n JSON.stringify(newHoveredPolygon) !==\r\n JSON.stringify(this.hoveredPolygon)\r\n ) {\r\n this.hoveredPointIndex = newHoveredPointIndex;\r\n this.hoveredPolygon = newHoveredPolygon;\r\n redraw = true;\r\n }\r\n\r\n // Handle dragging\r\n if (\r\n this.draggedPointIndex !== null && currentPolygon &&\r\n this.currentTool.name === \"move\"\r\n ) {\r\n currentPolygon.points[this.draggedPointIndex] = { x, y };\r\n // Recalculate area if this is a roof polygon\r\n if (currentPolygon.type === \"roof\" && currentPolygon.closed) {\r\n const metersInPixels = 1 / this.pixelInMeters;\r\n const area = calculatePolygonArea(currentPolygon.points) /\r\n (metersInPixels * metersInPixels);\r\n currentPolygon.details.area = area;\r\n }\r\n redraw = true;\r\n }\r\n\r\n if (this.shiftKeyPressed) {\r\n redraw = true;\r\n }\r\n\r\n if (redraw) {\r\n this.drawPolygons();\r\n }\r\n }\r\n\r\n private drawPolygons() {\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n\r\n // Clear the canvas and redraw the map\r\n this.polygonCtx.clearRect(\r\n 0,\r\n 0,\r\n this.polygonCanvas.width,\r\n this.polygonCanvas.height,\r\n );\r\n\r\n // draw roof polygons\r\n for (const polygon of Object.values(this.roofPolygons)) {\r\n const fillColor = getFillColor(\r\n this.selectedPolygon,\r\n this.hoveredPolygon,\r\n polygon._id,\r\n polygon,\r\n this.config,\r\n );\r\n\r\n drawPolygon({\r\n polygonCtx: this.polygonCtx,\r\n polygonCanvas: this.polygonCanvas,\r\n polygon,\r\n strokeColor: polygon.closed\r\n ? this.config.closedRoofColor\r\n : this.config.openRoofColor,\r\n fillColor,\r\n pixelInMeters: this.pixelInMeters,\r\n shiftKeyPressed: this.shiftKeyPressed,\r\n mousePoint: this.mousePoint,\r\n highlightColor: this.config.highlightColor,\r\n highlightedEdge: this.highlightedEdge,\r\n });\r\n\r\n const solarPanels = this.roofPolygonsSolarPanels[polygon._id];\r\n const convertedSolarPanel: SolarPanelType = {\r\n ...this.solarPanel,\r\n widthMeters: this.solarPanel.widthMeters / this.pixelInMeters,\r\n heightMeters: this.solarPanel.heightMeters / this.pixelInMeters,\r\n };\r\n if (solarPanels) {\r\n for (const panel of solarPanels.positionedPanels) {\r\n renderSolarPanel(\r\n panel,\r\n this.polygonCtx,\r\n convertedSolarPanel.widthMeters,\r\n convertedSolarPanel.heightMeters,\r\n polygon.details?.azimuth,\r\n polygon.details?.pitch,\r\n );\r\n }\r\n }\r\n }\r\n\r\n // draw obstruction polygons\r\n for (const polygon of Object.values(this.obstructionPolygons)) {\r\n const fillColor = getFillColor(\r\n this.selectedPolygon,\r\n this.hoveredPolygon,\r\n polygon._id,\r\n polygon,\r\n this.config,\r\n );\r\n\r\n drawPolygon({\r\n polygonCtx: this.polygonCtx,\r\n polygonCanvas: this.polygonCanvas,\r\n polygon,\r\n pixelInMeters: this.pixelInMeters,\r\n shiftKeyPressed: this.shiftKeyPressed,\r\n mousePoint: this.mousePoint,\r\n strokeColor: polygon.closed\r\n ? this.config.closedObstructionColor\r\n : this.config.openObstructionColor,\r\n fillColor,\r\n highlightColor: this.config.highlightColor,\r\n });\r\n }\r\n }\r\n\r\n private deletePolygon(_id: string) {\r\n if (this.selectedPolygon?._id === _id) {\r\n this.selectedPolygon = null;\r\n }\r\n if (this.roofPolygons[_id]) {\r\n delete this.roofPolygons[_id];\r\n delete this.roofPolygonsSolarPanels[_id];\r\n }\r\n if (this.obstructionPolygons[_id]) {\r\n delete this.obstructionPolygons[_id];\r\n }\r\n }\r\n\r\n @Listen(\"keydown\", { target: \"document\" })\r\n handleKeyDown(event: KeyboardEvent) {\r\n if (event.target instanceof HTMLInputElement) {\r\n return;\r\n }\r\n // Handle shift key for perpendicular points\r\n if (event.shiftKey && !this.shiftKeyPressed) {\r\n this.shiftKeyPressed = true;\r\n this.drawPolygons();\r\n return;\r\n }\r\n if (event.altKey && !this.altKeyPressed) {\r\n this.altKeyPressed = true;\r\n return;\r\n }\r\n if (\r\n (event.key === \"Delete\" || event.key === \"Backspace\") &&\r\n this.selectedPolygon\r\n ) {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (currentPolygon.closed) {\r\n this.deletePolygon(currentPolygon._id);\r\n this.drawPolygons();\r\n return;\r\n }\r\n currentPolygon.points.pop();\r\n this.drawPolygons();\r\n return;\r\n }\r\n\r\n // Handle tool selection shortcuts\r\n const pressedKey = event.key.toLowerCase();\r\n const tool = tools.find((t) =>\r\n t.keyboardShortcut?.toLowerCase() === pressedKey\r\n );\r\n if (tool) {\r\n this.currentTool = tool;\r\n }\r\n }\r\n\r\n @Listen(\"keyup\", { target: \"document\" })\r\n handleKeyUp(event: KeyboardEvent) {\r\n if (!event.shiftKey && this.shiftKeyPressed) {\r\n this.shiftKeyPressed = false;\r\n this.drawPolygons();\r\n }\r\n if (!event.altKey && this.altKeyPressed) {\r\n this.altKeyPressed = false;\r\n }\r\n }\r\n\r\n private undo() {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (!currentPolygon) {\r\n return;\r\n }\r\n if (currentPolygon.closed) {\r\n currentPolygon.closed = false;\r\n if (currentPolygon.type === \"roof\") {\r\n delete this.roofPolygonsSolarPanels[currentPolygon._id];\r\n this.currentTool = roofTool;\r\n this.highlightedEdge = null;\r\n } else if (currentPolygon.type === \"obstruction\") {\r\n this.currentTool = obstructionTool;\r\n }\r\n } else {\r\n currentPolygon.points.pop();\r\n }\r\n this.drawPolygons();\r\n }\r\n\r\n @Listen(\"mousedown\", { target: \"document\" })\r\n handleMouseDown(event: MouseEvent) {\r\n if (this.currentTool.name === \"undo\") {\r\n return;\r\n }\r\n if (state.isMobile) return; // Prevent interactions on mobile\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n if (!this.polygonCanvas.contains(event.target as Node)) return;\r\n\r\n let { x, y } = this.convertToCanvasCoordinates(event);\r\n\r\n if (this.currentTool.name === \"markRoofEdge\") {\r\n if (!this.highlightedEdge) {\r\n return;\r\n }\r\n const x = this.highlightedEdge.pointA.x -\r\n this.highlightedEdge.pointB.x;\r\n const y = this.highlightedEdge.pointA.y -\r\n this.highlightedEdge.pointB.y;\r\n const azimuth = Math.atan2(-x, y) * (180 / Math.PI);\r\n this.calculateSolarPanels();\r\n this.handleAzimuthChange({\r\n target: {\r\n value: azimuth,\r\n },\r\n } as unknown as Event);\r\n return;\r\n }\r\n if (this.currentTool.name === \"delete\") {\r\n if (!this.hoveredPolygon) {\r\n return;\r\n }\r\n const { _id, type } = this.hoveredPolygon;\r\n if (type === \"roof\") {\r\n delete this.roofPolygons[_id];\r\n delete this.roofPolygonsSolarPanels[_id];\r\n } else if (type === \"obstruction\") {\r\n delete this.obstructionPolygons[_id];\r\n }\r\n this.hoveredPolygon = null;\r\n if (this.selectedPolygon?._id === _id) {\r\n this.selectedPolygon = null;\r\n }\r\n this.drawPolygons();\r\n return;\r\n }\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (this.currentTool.name === \"move\") {\r\n // Check if we're clicking on a point of the selected polygon\r\n if (this.selectedPolygon) {\r\n const pointIndex = currentPolygon?.points.findIndex((point) => {\r\n const distance = Math.sqrt(\r\n Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2),\r\n );\r\n return distance < 10;\r\n });\r\n if (pointIndex !== undefined && pointIndex !== -1) {\r\n this.draggedPointIndex = pointIndex;\r\n return;\r\n }\r\n\r\n if (this.hoveredPolygon) {\r\n this.selectedPolygon = this.hoveredPolygon;\r\n return;\r\n }\r\n }\r\n this.selectedPolygon = null;\r\n this.drawPolygons();\r\n return;\r\n }\r\n if (\r\n !this.selectedPolygon || currentPolygon?.closed ||\r\n this.currentTool.name !== this.selectedPolygon?.type\r\n ) {\r\n // no polygon is active, create a new one\r\n const newPolygon: Polygon = {\r\n _id: uuidv4(),\r\n points: [{ x, y }],\r\n type: this.currentTool.name,\r\n closed: false,\r\n };\r\n let _id;\r\n if (this.currentTool.name === \"roof\") {\r\n this.roofPolygons = {\r\n ...this.roofPolygons,\r\n [newPolygon._id]: newPolygon,\r\n };\r\n _id = newPolygon._id;\r\n } else if (this.currentTool.name === \"obstruction\") {\r\n this.obstructionPolygons = {\r\n ...this.obstructionPolygons,\r\n [newPolygon._id]: newPolygon,\r\n };\r\n _id = newPolygon._id;\r\n }\r\n this.selectedPolygon = { _id, type: this.currentTool.name };\r\n this.drawPolygons();\r\n return;\r\n }\r\n\r\n if (currentPolygon.closed) {\r\n return;\r\n }\r\n\r\n // If we have at least one point, check if we're clicking near the first point\r\n if (currentPolygon.points.length > 2) {\r\n const firstPoint = currentPolygon.points[0];\r\n const distance = Math.sqrt(\r\n Math.pow(x - firstPoint.x, 2) + Math.pow(y - firstPoint.y, 2),\r\n );\r\n\r\n if (distance < 10) {\r\n this.closePolygon();\r\n return;\r\n }\r\n }\r\n\r\n // Handle shift key for perpendicular points\r\n if (event.shiftKey && currentPolygon?.points.length >= 2) {\r\n const projectedPoint = projectPointPerpendicularToLine({\r\n x,\r\n y,\r\n lastPoint:\r\n currentPolygon.points[currentPolygon.points.length - 1],\r\n secondLastPoint:\r\n currentPolygon.points[currentPolygon.points.length - 2],\r\n });\r\n x = projectedPoint.x;\r\n y = projectedPoint.y;\r\n }\r\n\r\n currentPolygon.points = [...currentPolygon.points, { x, y }];\r\n this.drawPolygons();\r\n }\r\n\r\n @Listen(\"mouseup\", { target: \"document\" })\r\n handleMouseUp() {\r\n this.draggedPointIndex = null;\r\n }\r\n\r\n private closePolygon() {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (\r\n currentPolygon.points.length >= 3 &&\r\n (this.currentTool.name === \"roof\" ||\r\n this.currentTool.name === \"obstruction\")\r\n ) {\r\n currentPolygon.closed = true;\r\n }\r\n\r\n if (currentPolygon.type === \"roof\") {\r\n // Calculate basic polygon details\r\n const metersInPixels = 1 / this.pixelInMeters;\r\n const area = calculatePolygonArea(currentPolygon.points) /\r\n (metersInPixels * metersInPixels);\r\n const bestMatch = getBestFittingRoofSegment(\r\n currentPolygon,\r\n this.buildingInsights?.solarPotential.roofSegmentStats,\r\n this.rgbTiff.bounds,\r\n this.canvasElement,\r\n );\r\n\r\n if (bestMatch) {\r\n currentPolygon.details = {\r\n area,\r\n azimuth: bestMatch.azimuthDegrees,\r\n pitch: bestMatch.pitchDegrees,\r\n };\r\n } else {\r\n currentPolygon.details = {\r\n area,\r\n azimuth: 0,\r\n pitch: 0,\r\n };\r\n }\r\n\r\n this.scrollToCanvas();\r\n }\r\n\r\n this.drawPolygons();\r\n this.currentTool = moveTool;\r\n }\r\n\r\n private calculateSolarPanels({ redraw = true }: { redraw?: boolean } = {}) {\r\n const currentPolygon = this.getCurrentPolygon();\r\n\r\n if (!currentPolygon.details) {\r\n return;\r\n }\r\n\r\n if (this.roofPolygonsSolarPanels[currentPolygon._id]) {\r\n delete this.roofPolygonsSolarPanels[currentPolygon._id];\r\n }\r\n\r\n const convertedSolarPanel: SolarPanelType = {\r\n ...this.solarPanel,\r\n widthMeters: this.solarPanel.widthMeters / this.pixelInMeters,\r\n heightMeters: this.solarPanel.heightMeters / this.pixelInMeters,\r\n };\r\n const inset = BORDER_INSET / this.pixelInMeters;\r\n const solarPanels = getOptimalSolarPositionFully(\r\n currentPolygon,\r\n Object.values(this.obstructionPolygons),\r\n convertedSolarPanel,\r\n currentPolygon.details?.azimuth,\r\n inset,\r\n currentPolygon.details?.pitch,\r\n );\r\n this.roofPolygonsSolarPanels = {\r\n ...this.roofPolygonsSolarPanels,\r\n [currentPolygon._id]: {\r\n positionedPanels: solarPanels,\r\n sunniness: currentPolygon.details?.assignedRoofStats?.stats\r\n .sunshineQuantiles[5] ??\r\n this.buildingInsights.solarPotential.buildingStats\r\n .sunshineQuantiles[5] ??\r\n DEFAULT_SUNNINESS,\r\n },\r\n };\r\n if (redraw) {\r\n this.drawPolygons();\r\n }\r\n }\r\n\r\n private handlePitchChange(event: Event) {\r\n const target = event.target as HTMLInputElement;\r\n const pitch = parseFloat(target.value);\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (currentPolygon) {\r\n this.roofPolygons[currentPolygon._id].details.pitch = pitch;\r\n }\r\n if (\r\n currentPolygon.type === \"roof\" &&\r\n this.roofPolygonsSolarPanels[currentPolygon._id]\r\n ) {\r\n this.calculateSolarPanels();\r\n return;\r\n }\r\n }\r\n\r\n private handleAzimuthChange(event: Event) {\r\n const target = event.target as HTMLInputElement;\r\n const azimuth = parseFloat(target.value);\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (currentPolygon) {\r\n this.roofPolygons[currentPolygon._id].details.azimuth = azimuth;\r\n }\r\n if (\r\n currentPolygon.type === \"roof\" &&\r\n this.roofPolygonsSolarPanels[currentPolygon._id]\r\n ) {\r\n this.calculateSolarPanels();\r\n return;\r\n }\r\n }\r\n\r\n private handleToolSelect(tool: Tool) {\r\n const currentPolygon = this.getCurrentPolygon();\r\n if (\r\n currentPolygon && !currentPolygon.closed &&\r\n currentPolygon.points.length > 0\r\n ) {\r\n alert(\"Please close the polygon before selecting a tool\");\r\n // TODO translate\r\n return;\r\n }\r\n this.currentTool = tool;\r\n }\r\n\r\n private scrollToCanvas() {\r\n const canvasElement = this.el.querySelector(\"#map-draw-canvas\");\r\n if (canvasElement) {\r\n canvasElement.scrollIntoView({ behavior: \"smooth\" });\r\n }\r\n }\r\n\r\n private handleSettingsClick = () => {\r\n this.showSettings = true;\r\n };\r\n\r\n private handleSettingsClose = () => {\r\n this.showSettings = false;\r\n };\r\n\r\n private handleSettingsSave = (event: CustomEvent<Settings>) => {\r\n state.settings = event.detail;\r\n state.settingsVersion++;\r\n };\r\n\r\n render() {\r\n const t = getLanguageStrings(state.settings.language);\r\n const currentPolygon = this.getCurrentPolygon();\r\n return (\r\n <div\r\n class=\"flex flex-col justify-center items-center w-full h-full gap-4 bg-primary\"\r\n id=\"map-draw\"\r\n >\r\n {this.showInstructions && !state.isMobile && (\r\n <div class=\"w-full rounded-4xl p-4 bg-muted text-muted-foreground\">\r\n {t.mapDraw.instructions.parts.roof}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() => this.handleToolSelect(roofTool)}\r\n >\r\n <icon-selector name=\"house\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.obstruction}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() =>\r\n this.handleToolSelect(obstructionTool)}\r\n >\r\n <icon-selector name=\"octagon-minus\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.delete}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() => this.handleToolSelect(deleteTool)}\r\n >\r\n <icon-selector name=\"eraser\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.move}{\" \"}\r\n <button\r\n class=\"inline-flex items-center justify-center p-1 rounded-full hover:bg-surface-hover transition-colors\"\r\n onClick={() => this.handleToolSelect(moveTool)}\r\n >\r\n <icon-selector name=\"move\" inline={true} />\r\n </button>{\" \"}\r\n {t.mapDraw.instructions.parts.end}\r\n </div>\r\n )}\r\n <div class=\"w-full flex flex-row justify-between items-center\">\r\n {!state.isMobile && (this.showInstructions\r\n ? (\r\n <button\r\n class=\"px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground\"\r\n onClick={() => this.showInstructions = false}\r\n >\r\n {t.mapDraw.instructions.hide}\r\n </button>\r\n )\r\n : (\r\n <button\r\n class=\"px-4 py-2 rounded-4xl hover:bg-surface-hover transition-colors duration-200 bg-muted p-4 text-muted-foreground\"\r\n onClick={() => this.showInstructions = true}\r\n >\r\n {t.mapDraw.instructions.show}\r\n </button>\r\n ))}\r\n <button\r\n class=\"flex items-center gap-2 bg-muted p-2 rounded-4xl hover:bg-surface-hover text-muted-foreground\"\r\n onClick={this.handleSettingsClick}\r\n >\r\n <settings-icon />\r\n </button>\r\n </div>\r\n <div class=\"w-full\">\r\n {!state.isMobile && (\r\n <tool-box\r\n currentTool={this.currentTool}\r\n onToolSelect={(tool) => this.handleToolSelect(tool)}\r\n undoCallback={() => this.undo()}\r\n />\r\n )}\r\n </div>\r\n {this.loadingState === \"empty\" && (\r\n <div class=\"w-full\">\r\n <p class=\"text-muted text-center flex items-center justify-center rounded-4xl p-4 w-full bg-text-secondary\">\r\n {t.mapDraw.noAddressSelected}\r\n </p>\r\n </div>\r\n )}\r\n {(state.latitude && state.longitude &&\r\n this.loadingState === \"loading\") && (\r\n <div class=\"flex items-center justify-center w-full bg-opacity-75 z-20 pt-7 rounded-4xl\">\r\n <div class=\"animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-secondary\">\r\n </div>\r\n </div>\r\n )}\r\n <div class=\"flex items-start justify-center h-full w-full bg-primary rounded-4xl\">\r\n <div\r\n class=\"relative h-full flex items-center justify-center w-full rounded-4xl bg-secondary\"\r\n style={{\r\n aspectRatio: this.rgbTiff\r\n ? `${this.rgbTiff.width}/${this.rgbTiff.height}`\r\n : \"1/1\",\r\n }}\r\n >\r\n <canvas\r\n ref={(el) => this.canvasElement = el}\r\n class=\"absolute top-0 left-0 w-full h-full rounded-4xl\"\r\n id=\"map-draw-canvas\"\r\n style={{\r\n cursor: this.currentTool.cursor,\r\n }}\r\n >\r\n </canvas>\r\n <canvas\r\n ref={(el) => this.polygonCanvas = el}\r\n class=\"absolute top-0 left-0 w-full h-full rounded-4xl\"\r\n style={{\r\n cursor: this.currentTool.cursor,\r\n }}\r\n >\r\n </canvas>\r\n </div>\r\n </div>\r\n {currentPolygon?.closed && (\r\n <div class=\"w-full\">\r\n <polygon-buttons\r\n currentTool={this.currentTool.name}\r\n calculateSolarPanels={() =>\r\n this.calculateSolarPanels()}\r\n selectEdgeTool={() =>\r\n this.handleToolSelect(markRoofEdgeTool)}\r\n />\r\n </div>\r\n )}\r\n {!state.isMobile && (\r\n <div class=\"w-full\">\r\n <polygon-information\r\n currentPolygon={currentPolygon}\r\n positionedPanels={currentPolygon\r\n ? this\r\n .roofPolygonsSolarPanels[currentPolygon._id]\r\n ?.positionedPanels\r\n : undefined}\r\n handleAzimuthChange={(event) =>\r\n this.handleAzimuthChange(event)}\r\n handlePitchChange={(event) =>\r\n this.handlePitchChange(event)}\r\n calculateSolarPanels={() =>\r\n this.calculateSolarPanels()}\r\n />\r\n </div>\r\n )}\r\n <div class=\"w-full\">\r\n <solar-system-form\r\n systemConfigs={this.roofPolygonsSolarPanels}\r\n roofPolygons={this.roofPolygons}\r\n obstructionPolygons={this.obstructionPolygons}\r\n />\r\n </div>\r\n {this.showSettings && (\r\n <settings-modal\r\n settings={state.settings}\r\n onClose={this.handleSettingsClose}\r\n onSave={this.handleSettingsSave}\r\n />\r\n )}\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
@@ -31,14 +31,14 @@ export class SettingsModal {
31
31
  };
32
32
  render() {
33
33
  const t = getLanguageStrings(state.settings.language);
34
- return (h("div", { key: '69815a7efeb8f52a5d3422b06dc212a50b9f405b', class: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" }, h("div", { key: 'ed368ae8d0d6d2946c5a4ecc559f018521e1bce8', class: "bg-primary rounded-4xl p-6 w-full max-w-md" }, h("div", { key: 'f51088beb4d8445503fa08c3dd2a2b8c886f79ce', class: "flex justify-between items-center mb-6" }, h("h2", { key: 'a9bcb7b893961bbf2032c1b8a110624ec3a95e65', class: "text-xl font-semibold" }, "Settings"), h("button", { key: '47d4dc1cc0789485da95218becfc921ae5db177c', class: "p-2 hover:bg-hover rounded-full transition-colors", onClick: this.handleClose }, h("svg", { key: '42923fdd6d5c96ceee98bdddca2e7e6bda42dcfa', xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { key: '751c5243b5b785a21131b02a3142c6d46e0cffeb', x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { key: 'e26bd2a1b20aa718ced6183130e962c9dbd159b9', x1: "6", y1: "6", x2: "18", y2: "18" })))), h("div", { key: '560be61d72a1a98eea4d2788d49eee7a3107470d', class: "space-y-4" }, h("div", { key: '2e6422d175602e7a53eb3d629c37c47980c08da1' }, h("label", { key: '56a2f53ae26c3e7d90519b85f3466604ea46b469', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.language), h("select", { key: 'ab444c024a2dfefd46ba6fb09878e75d52db9478', class: "w-full bg-muted rounded-4xl p-2", onInput: (e) => this.handleInputChange("language", e.target
35
- .value) }, h("option", { key: 'eb6b88689002c9f379af1c157f19fc123dbe7b4f', value: "en", selected: this.tempSettings.language ===
36
- "en" }, "English"), h("option", { key: '2203e1615212fdf96463185e9a06df2f65898dc4', value: "es", selected: this.tempSettings.language ===
37
- "es" }, "Espa\u00F1ol"), h("option", { key: 'ec91327e0070e0045079f63476aab7ea90da43ee', value: "de", selected: this.tempSettings.language ===
38
- "de" }, "Deutsch"))), h("div", { key: 'ff8d7f227f166862303f666bea321d13b50e79c8' }, h("label", { key: '778fefd538acc3601d8733e8b10e08c7f749cfb2', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.rowSpacing), h("input", { key: 'ebd39dcc7fbb5bb6e806b6482fe5a22730dcc31d', type: "number", class: "w-full bg-muted rounded-4xl p-2", value: this.tempSettings.rowSpacing, onInput: (e) => this.handleInputChange("rowSpacing", parseFloat(e.target
39
- .value)) })), h("div", { key: '0f770fa12c399fb1282a95cdaa873d3c4c4591f8' }, h("label", { key: 'bcfdb9dc84393770c93a982e34e38198f2cb59df', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.columnSpacing), h("input", { key: '574dc95db00f9c1725004e6c074e537f1ba51b60', type: "number", class: "w-full bg-muted rounded-4xl p-2", value: this.tempSettings.columnSpacing, onInput: (e) => this.handleInputChange("columnSpacing", parseFloat(e.target
40
- .value)) })), h("div", { key: '286a6121aace1b97724bf7c88975a172f0fe1a68' }, h("label", { key: '96b65a6ce1591e0188544db161e018ce90f151e2', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.borderInset), h("input", { key: '264728330a50df7b3ba02a568ff683dce895b2b3', type: "number", class: "w-full bg-muted rounded-4xl p-2", value: this.tempSettings.borderInset, onInput: (e) => this.handleInputChange("borderInset", parseFloat(e.target
41
- .value)) }))), h("div", { key: 'd73a232b24082a9c0bef75612184c71f52c59139', class: "flex justify-end gap-4 mt-6" }, h("button", { key: '981039537b08be95b180cc6672725f6b2a5c9281', class: "px-4 py-2 bg-surface rounded-4xl hover:bg-surface-hover transition-colors", onClick: this.handleClose }, "Cancel"), h("button", { key: '7f30b8e87d03e4ab2afe77c0579052993b57d3d3', class: "px-4 py-2 bg-secondary text-muted rounded-4xl hover:bg-text-secondary transition-colors", onClick: this.handleSave }, "Save Changes")))));
34
+ return (h("div", { key: '69815a7efeb8f52a5d3422b06dc212a50b9f405b', class: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" }, h("div", { key: 'ed368ae8d0d6d2946c5a4ecc559f018521e1bce8', class: "bg-primary rounded-4xl p-6 w-full max-w-md" }, h("div", { key: 'f51088beb4d8445503fa08c3dd2a2b8c886f79ce', class: "flex justify-between items-center mb-6" }, h("h2", { key: 'a9bcb7b893961bbf2032c1b8a110624ec3a95e65', class: "text-xl font-semibold" }, "Settings"), h("button", { key: '47d4dc1cc0789485da95218becfc921ae5db177c', class: "p-2 hover:bg-hover rounded-full transition-colors", onClick: this.handleClose }, h("svg", { key: '42923fdd6d5c96ceee98bdddca2e7e6bda42dcfa', xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("line", { key: '751c5243b5b785a21131b02a3142c6d46e0cffeb', x1: "18", y1: "6", x2: "6", y2: "18" }), h("line", { key: 'e26bd2a1b20aa718ced6183130e962c9dbd159b9', x1: "6", y1: "6", x2: "18", y2: "18" })))), h("div", { key: '560be61d72a1a98eea4d2788d49eee7a3107470d', class: "space-y-4" }, h("div", { key: '2e6422d175602e7a53eb3d629c37c47980c08da1' }, h("h3", { key: '0d043e5ddbfb9de4a8c198d748bd5ae39fd3b4b4', class: "text-sm font-medium text-text-muted mb-1" }, "Debug Information"), h("p", { key: '547de97a72e386222c53a5d890ad0df8fdb4d01e', class: "text-sm text-text-muted mb-1" }, "state: ", JSON.stringify(state, null, 2))), h("div", { key: 'ef75d4b5a52412cf3490488c6136e2e6e565139c' }, h("label", { key: '07b471590c8a3e5e9650139ef0a0dd7fde2e7dbc', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.language), h("select", { key: 'fa4402fa2619d420196a141bf73639b174da9d15', class: "w-full bg-muted rounded-4xl p-2", onInput: (e) => this.handleInputChange("language", e.target
35
+ .value) }, h("option", { key: '602d2bdcfb44578db38430faef981b228b43c2f0', value: "en", selected: this.tempSettings.language ===
36
+ "en" }, "English"), h("option", { key: '091eaf99b5fd7210af3b2acad5707c33b4a197ce', value: "es", selected: this.tempSettings.language ===
37
+ "es" }, "Espa\u00F1ol"), h("option", { key: '1b9a34ea61afda6b020defb0dfb6f4cb43a20d0d', value: "de", selected: this.tempSettings.language ===
38
+ "de" }, "Deutsch"))), h("div", { key: 'ab28aa21b7e895a3cfb4c8fa180996a26a94e93a' }, h("label", { key: '1f51a61d67360211c6698c9a23128f7ca643f1cd', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.rowSpacing), h("input", { key: 'e0f529022a81952601e66acb5084285b5fae69fb', type: "number", class: "w-full bg-muted rounded-4xl p-2", value: this.tempSettings.rowSpacing, onInput: (e) => this.handleInputChange("rowSpacing", parseFloat(e.target
39
+ .value)) })), h("div", { key: '1c3f2de5b42a589f18a7872a399e0811a78eba62' }, h("label", { key: '2f7f314c1810ece168d2e6aa08e7969c34bf3ca2', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.columnSpacing), h("input", { key: 'f10daa9396938f2964da36b2f7401605b60e8aa4', type: "number", class: "w-full bg-muted rounded-4xl p-2", value: this.tempSettings.columnSpacing, onInput: (e) => this.handleInputChange("columnSpacing", parseFloat(e.target
40
+ .value)) })), h("div", { key: '859da9b989acfc209c82cca20eb9e3e5b1f0ec4b' }, h("label", { key: '538172b3bc9e87f32f0537896bade833877001cf', class: "block text-sm font-medium text-text-muted mb-1" }, t.settings.borderInset), h("input", { key: '88704965fcdd31638e32eaff2ac7127b62cf2412', type: "number", class: "w-full bg-muted rounded-4xl p-2", value: this.tempSettings.borderInset, onInput: (e) => this.handleInputChange("borderInset", parseFloat(e.target
41
+ .value)) }))), h("div", { key: '2f9d2010c149deb338bd4fca212b12bca2d4a980', class: "flex justify-end gap-4 mt-6" }, h("button", { key: 'f0202cd088004bb88c8d52aafd2c3ce747d67bf0', class: "px-4 py-2 bg-surface rounded-4xl hover:bg-surface-hover transition-colors", onClick: this.handleClose }, "Cancel"), h("button", { key: '90b164b09bc096d4ae735449f8c4576008679985', class: "px-4 py-2 bg-secondary text-muted rounded-4xl hover:bg-text-secondary transition-colors", onClick: this.handleSave }, "Save Changes")))));
42
42
  }
43
43
  static get is() { return "settings-modal"; }
44
44
  static get originalStyleUrls() {
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/components/settings/settings.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Event, EventEmitter, h, Prop, State } from \"@stencil/core\";\r\nimport { Settings, state } from \"../../store\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\nimport { Language } from \"../../types/lang\";\r\n\r\n@Component({\r\n tag: \"settings-modal\",\r\n styleUrl: \"../../output.css\",\r\n shadow: false,\r\n})\r\nexport class SettingsModal {\r\n @Prop()\r\n settings: Settings;\r\n\r\n @State()\r\n private tempSettings: Settings;\r\n\r\n @Event()\r\n close: EventEmitter<void>;\r\n\r\n @Event()\r\n save: EventEmitter<Settings>;\r\n\r\n componentWillLoad() {\r\n this.tempSettings = { ...this.settings };\r\n }\r\n\r\n private handleClose = () => {\r\n if (\r\n JSON.stringify(this.tempSettings) !== JSON.stringify(this.settings)\r\n ) {\r\n if (\r\n confirm(\r\n \"Are you sure you want to close without saving your changes?\",\r\n )\r\n ) {\r\n this.close.emit();\r\n }\r\n } else {\r\n this.close.emit();\r\n }\r\n };\r\n\r\n private handleSave = () => {\r\n this.save.emit(this.tempSettings);\r\n this.close.emit();\r\n };\r\n\r\n private handleInputChange = (\r\n key: keyof Settings,\r\n value: number | Language,\r\n ) => {\r\n this.tempSettings = {\r\n ...this.tempSettings,\r\n [key]: value,\r\n };\r\n };\r\n\r\n render() {\r\n const t = getLanguageStrings(state.settings.language);\r\n return (\r\n <div class=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\r\n <div class=\"bg-primary rounded-4xl p-6 w-full max-w-md\">\r\n <div class=\"flex justify-between items-center mb-6\">\r\n <h2 class=\"text-xl font-semibold\">Settings</h2>\r\n <button\r\n class=\"p-2 hover:bg-hover rounded-full transition-colors\"\r\n onClick={this.handleClose}\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"space-y-4\">\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.language}\r\n </label>\r\n <select\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"language\",\r\n (e.target as HTMLSelectElement)\r\n .value as Language,\r\n )}\r\n >\r\n <option\r\n value=\"en\"\r\n selected={this.tempSettings.language ===\r\n \"en\"}\r\n >\r\n English\r\n </option>\r\n <option\r\n value=\"es\"\r\n selected={this.tempSettings.language ===\r\n \"es\"}\r\n >\r\n Español\r\n </option>\r\n <option\r\n value=\"de\"\r\n selected={this.tempSettings.language ===\r\n \"de\"}\r\n >\r\n Deutsch\r\n </option>\r\n </select>\r\n </div>\r\n\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.rowSpacing}\r\n </label>\r\n <input\r\n type=\"number\"\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n value={this.tempSettings.rowSpacing}\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"rowSpacing\",\r\n parseFloat(\r\n (e.target as HTMLInputElement)\r\n .value,\r\n ),\r\n )}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.columnSpacing}\r\n </label>\r\n <input\r\n type=\"number\"\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n value={this.tempSettings.columnSpacing}\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"columnSpacing\",\r\n parseFloat(\r\n (e.target as HTMLInputElement)\r\n .value,\r\n ),\r\n )}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.borderInset}\r\n </label>\r\n <input\r\n type=\"number\"\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n value={this.tempSettings.borderInset}\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"borderInset\",\r\n parseFloat(\r\n (e.target as HTMLInputElement)\r\n .value,\r\n ),\r\n )}\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"flex justify-end gap-4 mt-6\">\r\n <button\r\n class=\"px-4 py-2 bg-surface rounded-4xl hover:bg-surface-hover transition-colors\"\r\n onClick={this.handleClose}\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"px-4 py-2 bg-secondary text-muted rounded-4xl hover:bg-text-secondary transition-colors\"\r\n onClick={this.handleSave}\r\n >\r\n Save Changes\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/components/settings/settings.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Event, EventEmitter, h, Prop, State } from \"@stencil/core\";\r\nimport { Settings, state } from \"../../store\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\nimport { Language } from \"../../types/lang\";\r\n\r\n@Component({\r\n tag: \"settings-modal\",\r\n styleUrl: \"../../output.css\",\r\n shadow: false,\r\n})\r\nexport class SettingsModal {\r\n @Prop()\r\n settings: Settings;\r\n\r\n @State()\r\n private tempSettings: Settings;\r\n\r\n @Event()\r\n close: EventEmitter<void>;\r\n\r\n @Event()\r\n save: EventEmitter<Settings>;\r\n\r\n componentWillLoad() {\r\n this.tempSettings = { ...this.settings };\r\n }\r\n\r\n private handleClose = () => {\r\n if (\r\n JSON.stringify(this.tempSettings) !== JSON.stringify(this.settings)\r\n ) {\r\n if (\r\n confirm(\r\n \"Are you sure you want to close without saving your changes?\",\r\n )\r\n ) {\r\n this.close.emit();\r\n }\r\n } else {\r\n this.close.emit();\r\n }\r\n };\r\n\r\n private handleSave = () => {\r\n this.save.emit(this.tempSettings);\r\n this.close.emit();\r\n };\r\n\r\n private handleInputChange = (\r\n key: keyof Settings,\r\n value: number | Language,\r\n ) => {\r\n this.tempSettings = {\r\n ...this.tempSettings,\r\n [key]: value,\r\n };\r\n };\r\n\r\n render() {\r\n const t = getLanguageStrings(state.settings.language);\r\n return (\r\n <div class=\"fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50\">\r\n <div class=\"bg-primary rounded-4xl p-6 w-full max-w-md\">\r\n <div class=\"flex justify-between items-center mb-6\">\r\n <h2 class=\"text-xl font-semibold\">Settings</h2>\r\n <button\r\n class=\"p-2 hover:bg-hover rounded-full transition-colors\"\r\n onClick={this.handleClose}\r\n >\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"space-y-4\">\r\n <div>\r\n <h3 class=\"text-sm font-medium text-text-muted mb-1\">\r\n Debug Information\r\n </h3>\r\n <p class=\"text-sm text-text-muted mb-1\">\r\n state: {JSON.stringify(state, null, 2)}\r\n </p>\r\n </div>\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.language}\r\n </label>\r\n <select\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"language\",\r\n (e.target as HTMLSelectElement)\r\n .value as Language,\r\n )}\r\n >\r\n <option\r\n value=\"en\"\r\n selected={this.tempSettings.language ===\r\n \"en\"}\r\n >\r\n English\r\n </option>\r\n <option\r\n value=\"es\"\r\n selected={this.tempSettings.language ===\r\n \"es\"}\r\n >\r\n Español\r\n </option>\r\n <option\r\n value=\"de\"\r\n selected={this.tempSettings.language ===\r\n \"de\"}\r\n >\r\n Deutsch\r\n </option>\r\n </select>\r\n </div>\r\n\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.rowSpacing}\r\n </label>\r\n <input\r\n type=\"number\"\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n value={this.tempSettings.rowSpacing}\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"rowSpacing\",\r\n parseFloat(\r\n (e.target as HTMLInputElement)\r\n .value,\r\n ),\r\n )}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.columnSpacing}\r\n </label>\r\n <input\r\n type=\"number\"\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n value={this.tempSettings.columnSpacing}\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"columnSpacing\",\r\n parseFloat(\r\n (e.target as HTMLInputElement)\r\n .value,\r\n ),\r\n )}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label class=\"block text-sm font-medium text-text-muted mb-1\">\r\n {t.settings.borderInset}\r\n </label>\r\n <input\r\n type=\"number\"\r\n class=\"w-full bg-muted rounded-4xl p-2\"\r\n value={this.tempSettings.borderInset}\r\n onInput={(e) =>\r\n this.handleInputChange(\r\n \"borderInset\",\r\n parseFloat(\r\n (e.target as HTMLInputElement)\r\n .value,\r\n ),\r\n )}\r\n />\r\n </div>\r\n </div>\r\n\r\n <div class=\"flex justify-end gap-4 mt-6\">\r\n <button\r\n class=\"px-4 py-2 bg-surface rounded-4xl hover:bg-surface-hover transition-colors\"\r\n onClick={this.handleClose}\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n class=\"px-4 py-2 bg-secondary text-muted rounded-4xl hover:bg-text-secondary transition-colors\"\r\n onClick={this.handleSave}\r\n >\r\n Save Changes\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
@@ -54,7 +54,7 @@ export class SolarCalculator {
54
54
  });
55
55
  }
56
56
  render() {
57
- return (h("div", { key: 'caa09baccc8825a26b3917be5123d0d25d4e55b0', class: "flex flex-col w-full h-full p-3" }, h("div", { key: '770f517caa0a3e92d4233b1d5e3d29a84b4674be', class: "pb-3" }, h("div", { key: '1e35a2da7b80bd678eaffb81f01baa18ca7a72cf', class: "relative" }, h("i", { key: 'e5cc8ff44508ace9147e90041fe3e817da9eff5d', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-text-placeholder " }), h("input", { key: '568e1e0dbdb207ca496062302bee33d4c3e726d6', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-border rounded-4xl focus:outline-none focus:ring-2 focus:ring-info bg-muted" }))), this.buildingInsights && (h("div", { key: 'f3669e7ef307e641867f18cdb07523a7ee4c5838' }, "buildingInsights", h("div", { key: '6fc1aa4732666fcb25c61c41871c0769897317d8' }, JSON.stringify(this.buildingInsights))))));
57
+ return (h("div", { key: 'b7e6c360cd1b155c37eb41c91724d2dc61034b15', class: "flex flex-col w-full h-full p-3" }, h("div", { key: 'e4db04c2ae45a3371013496ad656ce862f0b1b2a', class: "pb-3" }, h("div", { key: '56cc5e5db9c6c1a6edc3b4751e7f5187b6abf571', class: "relative" }, h("i", { key: '636aa61ed640439d9263f3a53041dc9a9e34a671', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-text-placeholder " }), h("input", { key: 'a502ea7fcf871e1e8a3eba531a7a4bd117bb6b03', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-border rounded-4xl focus:outline-none focus:ring-2 focus:ring-info bg-muted" }))), this.buildingInsights && (h("div", { key: 'd2b113dc19f6d42df8a2698aa870f6c3b2343168' }, "buildingInsights", h("div", { key: '7e3e814e8c001d63ac0c260e9d7aec64f801ca45' }, JSON.stringify(this.buildingInsights))))));
58
58
  }
59
59
  static get is() { return "solar-calculator"; }
60
60
  static get originalStyleUrls() {
@@ -118,7 +118,7 @@ export class SolarExpert {
118
118
  }
119
119
  render() {
120
120
  const t = getLanguageStrings(this.language);
121
- return (h("div", { key: '871984aabe069426250bc1118fa55a74f928144f', class: "flex flex-col w-full h-full p-3 m-auto", id: "solar-calculator" }, this.showMapSelector
121
+ return (h("div", { key: 'd231a61b226c9f69c9feefc756449dd894778d78', class: "flex flex-col w-full h-full p-3 m-auto", id: "solar-calculator" }, this.showMapSelector
122
122
  ? (h("map-selector", { "api-key": this.apiKey, language: this.language }))
123
123
  : (h(h.Fragment, null, h("div", { class: "pb-3 flex flex-row gap-4 items-stretch w-full bg-primary" }, h("div", { class: "relative flex-3" }, h("div", { class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground" }, h("search-icon", null)), h("input", { ref: (el) => this.inputElement = el, type: "text", placeholder: t.solarExpert
124
124
  .searchPlaceholder, class: "w-full pl-10 pr-4 py-2 border border-border rounded-4xl focus:ring-secondary bg-muted text-muted-foreground h-full" })), h("button", { onClick: () => this.handleChooseOnMap(), class: "flex-1 pl-4 pr-4 py-2 border border-border bg-muted rounded-4xl focus:ring-secondary hover:bg-secondary hover:text-muted" }, t.mapSelector.chooseOnMap)), h("map-draw", { apiKey: this.apiKey })))));