blue-chestnut-solar-expert 0.0.2 → 0.0.3

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 (61) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/map-draw.solar-expert.solar-system-form.entry.cjs.js.map +1 -1
  3. package/dist/cjs/map-draw_3.cjs.entry.js +254 -34
  4. package/dist/cjs/map-draw_3.cjs.entry.js.map +1 -1
  5. package/dist/cjs/solar-calculator.cjs.entry.js +2 -2
  6. package/dist/cjs/solar-calculator.cjs.entry.js.map +1 -1
  7. package/dist/cjs/solar-calculator.entry.cjs.js.map +1 -1
  8. package/dist/cjs/stencil-library.cjs.js +1 -1
  9. package/dist/collection/components/map-draw/map-draw.js +9 -7
  10. package/dist/collection/components/map-draw/map-draw.js.map +1 -1
  11. package/dist/collection/components/solar-calculator/solar-calculator.js +1 -1
  12. package/dist/collection/components/solar-expert/solar-expert.js +3 -1
  13. package/dist/collection/components/solar-expert/solar-expert.js.map +1 -1
  14. package/dist/collection/components/solar-system-form/solar-system-form.js +106 -23
  15. package/dist/collection/components/solar-system-form/solar-system-form.js.map +1 -1
  16. package/dist/collection/output.css +12 -0
  17. package/dist/collection/types/lang.js.map +1 -1
  18. package/dist/collection/utils/lang/english.js +40 -0
  19. package/dist/collection/utils/lang/english.js.map +1 -1
  20. package/dist/collection/utils/lang/general.js +23 -3
  21. package/dist/collection/utils/lang/general.js.map +1 -1
  22. package/dist/collection/utils/lang/german.js +74 -0
  23. package/dist/collection/utils/lang/german.js.map +1 -1
  24. package/dist/collection/utils/lang/spanish.js +75 -0
  25. package/dist/collection/utils/lang/spanish.js.map +1 -0
  26. package/dist/components/map-draw.js +1 -1
  27. package/dist/components/{p-DuF8Bxfn.js → p-C6zdkCkY.js} +288 -27
  28. package/dist/components/p-C6zdkCkY.js.map +1 -0
  29. package/dist/components/{p-C2Mo0x2g.js → p-CXGY4i5A.js} +13 -55
  30. package/dist/components/p-CXGY4i5A.js.map +1 -0
  31. package/dist/components/solar-calculator.js +2 -2
  32. package/dist/components/solar-calculator.js.map +1 -1
  33. package/dist/components/solar-expert.js +5 -4
  34. package/dist/components/solar-expert.js.map +1 -1
  35. package/dist/components/solar-system-form.js +1 -1
  36. package/dist/esm/loader.js +1 -1
  37. package/dist/esm/map-draw.solar-expert.solar-system-form.entry.js.map +1 -1
  38. package/dist/esm/map-draw_3.entry.js +254 -34
  39. package/dist/esm/map-draw_3.entry.js.map +1 -1
  40. package/dist/esm/solar-calculator.entry.js +2 -2
  41. package/dist/esm/solar-calculator.entry.js.map +1 -1
  42. package/dist/esm/stencil-library.js +1 -1
  43. package/dist/stencil-library/map-draw.solar-expert.solar-system-form.entry.esm.js.map +1 -1
  44. package/dist/stencil-library/p-dc4824e6.entry.js +44 -0
  45. package/dist/stencil-library/p-dc4824e6.entry.js.map +1 -0
  46. package/dist/stencil-library/p-de9a8d56.entry.js +2 -0
  47. package/dist/stencil-library/p-de9a8d56.entry.js.map +1 -0
  48. package/dist/stencil-library/solar-calculator.entry.esm.js.map +1 -1
  49. package/dist/stencil-library/stencil-library.esm.js +1 -1
  50. package/dist/types/components/solar-system-form/solar-system-form.d.ts +9 -3
  51. package/dist/types/components.d.ts +8 -0
  52. package/dist/types/types/lang.d.ts +40 -0
  53. package/dist/types/utils/lang/german.d.ts +2 -0
  54. package/dist/types/utils/lang/spanish.d.ts +2 -0
  55. package/package.json +1 -1
  56. package/dist/components/p-C2Mo0x2g.js.map +0 -1
  57. package/dist/components/p-DuF8Bxfn.js.map +0 -1
  58. package/dist/stencil-library/p-319691e6.entry.js +0 -2
  59. package/dist/stencil-library/p-319691e6.entry.js.map +0 -1
  60. package/dist/stencil-library/p-642688b2.entry.js +0 -44
  61. package/dist/stencil-library/p-642688b2.entry.js.map +0 -1
@@ -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 { moveTool, roofTool, Tool, tools } 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 {\r\n azimuthToCardinal,\r\n calculatePolygonArea,\r\n getPixelInMeters,\r\n} 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 { Language } from \"../../types/lang\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\nconst FACTOR = 1;\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 language: Language = \"en\";\r\n @Prop()\r\n apiKey: string = \"\";\r\n @Prop()\r\n latitude: number | null = null;\r\n @Prop()\r\n longitude: number | null = null;\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 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 showAzimuth: boolean = true; // TODO: make this false\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 componentDidLoad() {\r\n if (this.latitude && this.longitude) {\r\n this.loadingState = \"loading\";\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 @Watch(\"latitude\")\r\n @Watch(\"longitude\")\r\n async getBuildingInsights() {\r\n if (!this.latitude || !this.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 === this.latitude &&\r\n this.buildingInsights.center.longitude === this.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 this.latitude,\r\n this.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\r\n @Watch(\"latitude\")\r\n @Watch(\"longitude\")\r\n async getBuildingImages() {\r\n if (!this.latitude || !this.longitude) {\r\n return;\r\n }\r\n if (this.buildingInsights) {\r\n const sameLocation =\r\n this.buildingInsights.center.latitude === this.latitude &&\r\n this.buildingInsights.center.longitude === this.longitude;\r\n if (sameLocation) {\r\n return;\r\n }\r\n }\r\n this.rgbTiff = await getBuildingImages(\r\n this.latitude,\r\n this.longitude,\r\n this.apiKey,\r\n );\r\n this.pixelInMeters = getPixelInMeters(this.rgbTiff);\r\n this.loadingState = \"loaded\";\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 this.sizeCanvas(this.rgbTiff.width, this.rgbTiff.height);\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 (!this.polygonCanvas || !this.polygonCtx) return;\r\n\r\n const rect = this.polygonCanvas.getBoundingClientRect();\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n this.mousePoint = { x, y };\r\n\r\n const currentPolygon = this.getCurrentPolygon();\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 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 this.drawPolygons();\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 this.drawPolygons();\r\n }\r\n\r\n if (this.shiftKeyPressed) {\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 });\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 });\r\n }\r\n\r\n // if (this.showAzimuth && this.selectedPolygon) {\r\n // const currentPolygon = this.getCurrentPolygon();\r\n // renderAzimuth(currentPolygon.details?.azimuth, this.polygonCtx);\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 @Listen(\"mousedown\", { target: \"document\" })\r\n handleMouseDown(event: MouseEvent) {\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n if (!this.polygonCanvas.contains(event.target as Node)) return;\r\n\r\n // get the mouse position in the polygon canvas\r\n const rect = this.polygonCanvas.getBoundingClientRect();\r\n let x = event.clientX - rect.left;\r\n let y = event.clientY - rect.top;\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 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 currentPolygon = this.getCurrentPolygon();\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\r\n if (!this.selectedPolygon || this.getCurrentPolygon()?.closed) {\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 return;\r\n }\r\n\r\n const { _id, type } = this.selectedPolygon;\r\n const currentPolygon = type === \"roof\"\r\n ? this.roofPolygons[_id]\r\n : this.obstructionPolygons[_id];\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\r\n this.drawPolygons();\r\n this.currentTool = moveTool;\r\n }\r\n\r\n private calculateSolarPanels() {\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 this.drawPolygons();\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 this.currentTool = tool;\r\n }\r\n\r\n render() {\r\n const t = getLanguageStrings(this.language);\r\n const currentPolygon = this.getCurrentPolygon();\r\n return (\r\n <div class=\"flex flex-col justify-center items-center w-full h-full gap-4\">\r\n {this.loadingState === \"empty\" && (\r\n <p class=\"text-gray-500 text-center\">\r\n {t.mapDraw.noAddressSelected}\r\n </p>\r\n )}\r\n {(this.latitude && this.longitude &&\r\n this.loadingState !== \"loaded\") && (\r\n <div class=\"absolute w-full flex items-center justify-center bg-white 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-[#271200]\">\r\n </div>\r\n </div>\r\n )}\r\n <div class=\"flex gap-4 rounded-4xl bg-[#f3ebda] p-4\">\r\n {tools.map((tool) => {\r\n const toolStrings = t.mapDraw.tools[tool.name];\r\n return (\r\n <button\r\n class={`px-4 py-2 rounded-4xl transition-colors duration-200 hover:bg-[#964500] ${\r\n this.currentTool.name === tool.name\r\n ? \"bg-[#271200] text-white hover:bg-[#964500]\"\r\n : \"bg-[#f3ebda] hover:bg-[#964500]\"\r\n }`}\r\n aria-label={toolStrings.ariaLabel}\r\n title={toolStrings.explanation}\r\n onClick={() => this.handleToolSelect(tool)}\r\n >\r\n <div class=\"flex items-center gap-1 flex-col\">\r\n <i data-lucide={tool.icon} />\r\n <span>{toolStrings.name}</span>\r\n </div>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n <div class=\"flex gap-4 items-start justify-center h-full\">\r\n <div\r\n class=\"relative flex-1 w-full h-full rounded-4xl flex items-center justify-center\"\r\n style={{\r\n width: `${this.rgbTiff?.width * FACTOR || 0}px`,\r\n height: `${this.rgbTiff?.height * FACTOR || 0}px`,\r\n }}\r\n >\r\n <canvas\r\n ref={(el) => this.canvasElement = el}\r\n class={`absolute top-0 left-0 z-1 rounded-4xl m-auto`}\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 z-10 rounded-4xl m-auto`}\r\n style={{\r\n cursor: this.currentTool.cursor,\r\n }}\r\n >\r\n </canvas>\r\n </div>\r\n </div>\r\n <div class=\"flex gap-4 flex-row justify-center items-center\">\r\n <div class=\"w-52 bg-[#f3ebda] rounded-4xl p-4\">\r\n <h3 class=\"text-lg font-semibold mb-4 text-center\">\r\n {t.mapDraw.information}\r\n </h3>\r\n {currentPolygon?.details\r\n ? (\r\n <div class=\"space-y-4\">\r\n <div class=\"flex flex-col gap-2\">\r\n <button\r\n class=\"px-4 py-2 bg-[#271200] text-white rounded-4xl hover:bg-[#964500] transition-colors duration-200\"\r\n onClick={() =>\r\n this.calculateSolarPanels()}\r\n >\r\n {t.mapDraw.calculateSolarPanels}\r\n </button>\r\n {this\r\n .roofPolygonsSolarPanels[\r\n currentPolygon._id\r\n ] && (\r\n <p class=\"text-lg text-center\">\r\n {this\r\n .roofPolygonsSolarPanels[\r\n currentPolygon._id\r\n ].positionedPanels\r\n .length} {t.mapDraw.panels}\r\n </p>\r\n )}\r\n </div>\r\n <div>\r\n <h4 class=\"text-sm font-medium text-gray-600\">\r\n {t.mapDraw.area}\r\n </h4>\r\n <p class=\"text-lg\">\r\n {currentPolygon.details?.area\r\n .toFixed(2)} m²\r\n </p>\r\n </div>\r\n <div>\r\n <h4 class=\"text-sm font-medium text-gray-600\">\r\n Orientation\r\n </h4>\r\n <div class=\"flex gap-2 flex-row justify-start\">\r\n <input\r\n class=\"text-lg w-full\"\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\") {\r\n this.handleAzimuthChange(\r\n e,\r\n );\r\n (e.target as HTMLInputElement)\r\n .blur();\r\n }\r\n }}\r\n value={currentPolygon\r\n .details\r\n ?.azimuth}\r\n />\r\n ({azimuthToCardinal(\r\n currentPolygon.details\r\n ?.azimuth,\r\n )})\r\n </div>\r\n </div>\r\n <div>\r\n <h4 class=\"text-sm font-medium text-gray-600\">\r\n {t.mapDraw.pitch}\r\n </h4>\r\n <div class=\"flex gap-2 flex-row justify-start\">\r\n <input\r\n class=\"text-lg w-full\"\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\") {\r\n this.handlePitchChange(\r\n e,\r\n );\r\n (e.target as HTMLInputElement)\r\n .blur();\r\n }\r\n }}\r\n value={currentPolygon\r\n .details\r\n ?.pitch}\r\n />\r\n °\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n : (\r\n <p class=\"text-gray-500 text-center\">\r\n {t.mapDraw.noPolygonSelected}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n <solar-system-form\r\n systemConfigs={this.roofPolygonsSolarPanels}\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 { moveTool, roofTool, Tool, tools } 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 {\r\n azimuthToCardinal,\r\n calculatePolygonArea,\r\n getPixelInMeters,\r\n} 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 { Language } from \"../../types/lang\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\nconst FACTOR = 1;\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 language: Language = \"en\";\r\n @Prop()\r\n apiKey: string = \"\";\r\n @Prop()\r\n latitude: number | null = null;\r\n @Prop()\r\n longitude: number | null = null;\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 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 showAzimuth: boolean = true; // TODO: make this false\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 componentDidLoad() {\r\n if (this.latitude && this.longitude) {\r\n this.loadingState = \"loading\";\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 @Watch(\"latitude\")\r\n @Watch(\"longitude\")\r\n async getBuildingInsights() {\r\n if (!this.latitude || !this.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 === this.latitude &&\r\n this.buildingInsights.center.longitude === this.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 this.latitude,\r\n this.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\r\n @Watch(\"latitude\")\r\n @Watch(\"longitude\")\r\n async getBuildingImages() {\r\n if (!this.latitude || !this.longitude) {\r\n return;\r\n }\r\n if (this.buildingInsights) {\r\n const sameLocation =\r\n this.buildingInsights.center.latitude === this.latitude &&\r\n this.buildingInsights.center.longitude === this.longitude;\r\n if (sameLocation) {\r\n return;\r\n }\r\n }\r\n this.rgbTiff = await getBuildingImages(\r\n this.latitude,\r\n this.longitude,\r\n this.apiKey,\r\n );\r\n this.pixelInMeters = getPixelInMeters(this.rgbTiff);\r\n this.loadingState = \"loaded\";\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 this.sizeCanvas(this.rgbTiff.width, this.rgbTiff.height);\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 (!this.polygonCanvas || !this.polygonCtx) return;\r\n\r\n const rect = this.polygonCanvas.getBoundingClientRect();\r\n const x = event.clientX - rect.left;\r\n const y = event.clientY - rect.top;\r\n this.mousePoint = { x, y };\r\n\r\n const currentPolygon = this.getCurrentPolygon();\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 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 this.drawPolygons();\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 this.drawPolygons();\r\n }\r\n\r\n if (this.shiftKeyPressed) {\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 });\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 });\r\n }\r\n\r\n // if (this.showAzimuth && this.selectedPolygon) {\r\n // const currentPolygon = this.getCurrentPolygon();\r\n // renderAzimuth(currentPolygon.details?.azimuth, this.polygonCtx);\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 @Listen(\"mousedown\", { target: \"document\" })\r\n handleMouseDown(event: MouseEvent) {\r\n if (!this.polygonCanvas || !this.polygonCtx) return;\r\n if (!this.polygonCanvas.contains(event.target as Node)) return;\r\n\r\n // get the mouse position in the polygon canvas\r\n const rect = this.polygonCanvas.getBoundingClientRect();\r\n let x = event.clientX - rect.left;\r\n let y = event.clientY - rect.top;\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 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 currentPolygon = this.getCurrentPolygon();\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\r\n if (!this.selectedPolygon || this.getCurrentPolygon()?.closed) {\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 return;\r\n }\r\n\r\n const { _id, type } = this.selectedPolygon;\r\n const currentPolygon = type === \"roof\"\r\n ? this.roofPolygons[_id]\r\n : this.obstructionPolygons[_id];\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\r\n this.drawPolygons();\r\n this.currentTool = moveTool;\r\n }\r\n\r\n private calculateSolarPanels() {\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 this.drawPolygons();\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 this.currentTool = tool;\r\n }\r\n\r\n render() {\r\n const t = getLanguageStrings(this.language);\r\n const currentPolygon = this.getCurrentPolygon();\r\n return (\r\n <div class=\"flex flex-col justify-center items-center w-full h-full gap-4\">\r\n {this.loadingState === \"empty\" && (\r\n <div class=\"absolute h-32 w-full\">\r\n <p\r\n class=\"text-gray-500 text-center w-full h-full flex items-center justify-center\"\r\n style={{\r\n backgroundColor: \"rgba(255, 255, 255, 0.9)\",\r\n }}\r\n >\r\n {t.mapDraw.noAddressSelected}\r\n </p>\r\n </div>\r\n )}\r\n {(this.latitude && this.longitude &&\r\n this.loadingState !== \"loaded\") && (\r\n <div class=\"absolute w-full flex items-center justify-center bg-white 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-[#271200]\">\r\n </div>\r\n </div>\r\n )}\r\n <div class=\"flex gap-4 rounded-4xl bg-[#f3ebda] p-4\">\r\n {tools.map((tool) => {\r\n const toolStrings = t.mapDraw.tools[tool.name];\r\n return (\r\n <button\r\n class={`px-4 py-2 rounded-4xl transition-colors duration-200 hover:bg-[#964500] ${\r\n this.currentTool.name === tool.name\r\n ? \"bg-[#271200] text-white hover:bg-[#964500]\"\r\n : \"bg-[#f3ebda] hover:bg-[#964500]\"\r\n }`}\r\n aria-label={toolStrings.ariaLabel}\r\n title={toolStrings.explanation}\r\n onClick={() => this.handleToolSelect(tool)}\r\n >\r\n <div class=\"flex items-center gap-1 flex-col\">\r\n <i data-lucide={tool.icon} />\r\n <span>{toolStrings.name}</span>\r\n </div>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n <div class=\"flex gap-4 items-start justify-center h-full\">\r\n <div\r\n class=\"relative flex-1 w-full h-full rounded-4xl flex items-center justify-center\"\r\n style={{\r\n width: `${this.rgbTiff?.width * FACTOR || 0}px`,\r\n height: `${this.rgbTiff?.height * FACTOR || 0}px`,\r\n }}\r\n >\r\n <canvas\r\n ref={(el) => this.canvasElement = el}\r\n class={`absolute top-0 left-0 z-1 rounded-4xl m-auto`}\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 z-10 rounded-4xl m-auto`}\r\n style={{\r\n cursor: this.currentTool.cursor,\r\n }}\r\n >\r\n </canvas>\r\n </div>\r\n </div>\r\n <div class=\"flex gap-4 flex-row justify-center items-center\">\r\n <div class=\"w-52 bg-[#f3ebda] rounded-4xl p-4\">\r\n <h3 class=\"text-lg font-semibold mb-4 text-center\">\r\n {t.mapDraw.information}\r\n </h3>\r\n {currentPolygon?.details\r\n ? (\r\n <div class=\"space-y-4\">\r\n <div class=\"flex flex-col gap-2\">\r\n <button\r\n class=\"px-4 py-2 bg-[#271200] text-white rounded-4xl hover:bg-[#964500] transition-colors duration-200\"\r\n onClick={() =>\r\n this.calculateSolarPanels()}\r\n >\r\n {t.mapDraw.calculateSolarPanels}\r\n </button>\r\n {this\r\n .roofPolygonsSolarPanels[\r\n currentPolygon._id\r\n ] && (\r\n <p class=\"text-lg text-center\">\r\n {this\r\n .roofPolygonsSolarPanels[\r\n currentPolygon._id\r\n ].positionedPanels\r\n .length} {t.mapDraw.panels}\r\n </p>\r\n )}\r\n </div>\r\n <div>\r\n <h4 class=\"text-sm font-medium text-gray-600\">\r\n {t.mapDraw.area}\r\n </h4>\r\n <p class=\"text-lg\">\r\n {currentPolygon.details?.area\r\n .toFixed(2)} m²\r\n </p>\r\n </div>\r\n <div>\r\n <h4 class=\"text-sm font-medium text-gray-600\">\r\n Orientation\r\n </h4>\r\n <div class=\"flex gap-2 flex-row justify-start\">\r\n <input\r\n class=\"text-lg w-full\"\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\") {\r\n this.handleAzimuthChange(\r\n e,\r\n );\r\n (e.target as HTMLInputElement)\r\n .blur();\r\n }\r\n }}\r\n value={currentPolygon\r\n .details\r\n ?.azimuth}\r\n />\r\n ({azimuthToCardinal(\r\n currentPolygon.details\r\n ?.azimuth,\r\n )})\r\n </div>\r\n </div>\r\n <div>\r\n <h4 class=\"text-sm font-medium text-gray-600\">\r\n {t.mapDraw.pitch}\r\n </h4>\r\n <div class=\"flex gap-2 flex-row justify-start\">\r\n <input\r\n class=\"text-lg w-full\"\r\n onKeyDown={(e) => {\r\n if (e.key === \"Enter\") {\r\n this.handlePitchChange(\r\n e,\r\n );\r\n (e.target as HTMLInputElement)\r\n .blur();\r\n }\r\n }}\r\n value={currentPolygon\r\n .details\r\n ?.pitch}\r\n />\r\n °\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n : (\r\n <p class=\"text-gray-500 text-center\">\r\n {t.mapDraw.noPolygonSelected}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n <solar-system-form\r\n systemConfigs={this.roofPolygonsSolarPanels}\r\n language={this.language}\r\n roofPolygons={this.roofPolygons}\r\n obstructionPolygons={this.obstructionPolygons}\r\n />\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: 'cacb257f179c1c7b4b950cfa8c2ef5cc89717d84', class: "flex flex-col w-full h-full p-3" }, h("div", { key: '7d35df722f9a4ddd498badaa617d40380ae7e67c', class: "pb-3" }, h("div", { key: 'cf795bc1456e5a3c1c2805394b4eddb7fd07bb23', class: "relative" }, h("i", { key: '4dc91b06dae3a7fe1c98c92a2005337d4d7d2d0a', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 " }), h("input", { key: '8b146d339b89df2d65341f0aa86587061a47757e', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-gray-300 rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white" }))), this.buildingInsights && (h("div", { key: '972fa20f23f13c8339844d2d272dff90f09c7737' }, "buildingInsights", h("div", { key: '9f61dbe82e15d2e03c150b16ed15a05aa24de2d9' }, JSON.stringify(this.buildingInsights))))));
57
+ return (h("div", { key: '910981334c177ed4b9aa5777e6621a5153e09919', class: "flex flex-col w-full h-full p-3" }, h("div", { key: '12009ce3d96418ec8372ff2a5909c5f51ac6aff9', class: "pb-3" }, h("div", { key: 'e14ddecbd4be2fcd8c31b04b3542ab67eac8e47e', class: "relative" }, h("i", { key: 'f546cf4b4347c83263d5491f4205ba4ef57f6f81', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 " }), h("input", { key: 'd024d3336d2cdb2a5dc80d59e62d67f087753e89', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-gray-300 rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white" }))), this.buildingInsights && (h("div", { key: '6cd8226654053e401424143427f801082017c97a' }, "buildingInsights", h("div", { key: 'b4a204a57b94267020dcddc41c6e44b921febabc' }, JSON.stringify(this.buildingInsights))))));
58
58
  }
59
59
  static get is() { return "solar-calculator"; }
60
60
  static get originalStyleUrls() {
@@ -1,6 +1,7 @@
1
1
  import { Env, h } from "@stencil/core";
2
2
  import { Loader } from "@googlemaps/js-api-loader";
3
3
  import { createIcons, Eraser, House, Move, OctagonMinus, Search } from "lucide";
4
+ import { getLanguageStrings } from "../../utils/lang/general";
4
5
  export class SolarExpert {
5
6
  el;
6
7
  apiKey = Env.GOOGLE_MAPS_API_KEY;
@@ -51,7 +52,8 @@ export class SolarExpert {
51
52
  });
52
53
  }
53
54
  render() {
54
- return (h("div", { key: '5162353e7237490872cb354e1d0e2cb46e3f6959', class: "flex flex-col w-full h-full p-3" }, h("div", { key: '5dd50770b71ecc7f079060fc4395206b0c53e871', class: "pb-3" }, h("div", { key: 'eaaa2ad3975af5790a0d7a86b35148a88f33f36b', class: "relative" }, h("i", { key: 'abed3e3eddbc5801e6643662d3c84e3a656d5801', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 " }), h("input", { key: '5f98818e56fcd28087f5167a8f04e63bb19b66aa', ref: (el) => this.inputElement = el, type: "text", placeholder: "Search for a location", class: "w-full pl-10 pr-4 py-2 border border-gray-300 rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white" }))), h("map-draw", { key: '706b3bd8c50e72d87f8bd84e7721c4760842a0c9', latitude: this.latitude, longitude: this.longitude, apiKey: this.apiKey })));
55
+ const t = getLanguageStrings(this.language);
56
+ return (h("div", { key: 'e2de3d567dad880d370e72a6e17e6a06c47bada0', class: "flex flex-col w-full h-full p-3" }, h("div", { key: 'fa914b7a5ff06d8c698285ecc95b2c93ea73ae91', class: "pb-3" }, h("div", { key: 'e3741c0e309fb7d8df547a41c22e951742e9939e', class: "relative" }, h("i", { key: '274a95550c1b2a0f6f8ca254160523ee8f93a53d', "data-lucide": "search", class: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 " }), h("input", { key: 'bb95fded65cf789d7a989458dcd7927cc3bd81cd', ref: (el) => this.inputElement = el, type: "text", placeholder: t.solarExpert.searchPlaceholder, class: "w-full pl-10 pr-4 py-2 border border-gray-300 rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white" }))), h("map-draw", { key: 'd3cfe674285a135f17a641665c3d09a1b969e607', latitude: this.latitude, longitude: this.longitude, apiKey: this.apiKey, language: this.language })));
55
57
  }
56
58
  static get is() { return "solar-expert"; }
57
59
  static get originalStyleUrls() {
@@ -1 +1 @@
1
- {"version":3,"file":"solar-expert.js","sourceRoot":"","sources":["../../../src/components/solar-expert/solar-expert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAQhF,MAAM,OAAO,WAAW;IAEpB,EAAE,CAAe;IAGjB,MAAM,GAAW,GAAG,CAAC,mBAAmB,CAAC;IAEzC,QAAQ,GAAa,IAAI,CAAC;IAG1B,QAAQ,GAAkB,IAAI,CAAC;IAE/B,SAAS,GAAkB,IAAI,CAAC;IAEhC,QAAQ,GAAY,KAAK,CAAC;IAE1B,YAAY,GAA2C,IAAI,CAAC;IAE5D,KAAK,GAA0C,IAAI,CAAC;IAE5C,YAAY,CAAoB;IAExC,iBAAiB;QACb,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAChC,CAAC;IAEO,KAAK,CAAC,oBAAoB;QAC9B,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;gBACtB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,CAAC,QAAQ,CAAC;aACxB,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACpD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC;IACL,CAAC;IAEO,sBAAsB,CAC1B,MAAiC;QAEjC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACjD,IAAI,CAAC,YAAY,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE/D,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,eAAe,EAAE,GAAG,EAAE;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC;YAC5C,IAAI,CAAC,QAAQ,GAAG,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,CAAC,SAAS,GAAG,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;IACP,CAAC;IAED,gBAAgB;QACZ,WAAW,CAAC;YACR,KAAK,EAAE;gBACH,MAAM;gBACN,YAAY;gBACZ,MAAM;gBACN,KAAK;gBACL,IAAI;aACP;YACD,QAAQ,EAAE,aAAa;SAC1B,CAAC,CAAC;IACP,CAAC;IAED,MAAM;QACF,OAAO,CACH,4DAAK,KAAK,EAAC,iCAAiC;YACxC,4DAAK,KAAK,EAAC,MAAM;gBACb,4DAAK,KAAK,EAAC,UAAU;oBACjB,yEACgB,QAAQ,EACpB,KAAK,EAAC,mEAAmE,GAC3E;oBACF,8DACI,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,EACnC,IAAI,EAAC,MAAM,EACX,WAAW,EAAC,uBAAuB,EACnC,KAAK,EAAC,wHAAwH,GAChI,CACA,CACJ;YACN,iEACI,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,SAAS,EAAE,IAAI,CAAC,SAAS,EACzB,MAAM,EAAE,IAAI,CAAC,MAAM,GACrB,CACA,CACT,CAAC;IACN,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CACJ","sourcesContent":["import { Component, Element, Env, h, Prop, State } from \"@stencil/core\";\r\nimport { Loader } from \"@googlemaps/js-api-loader\";\r\nimport { createIcons, Eraser, House, Move, OctagonMinus, Search } from \"lucide\";\r\nimport { Language } from \"../../types/lang\";\r\n\r\n@Component({\r\n tag: \"solar-expert\",\r\n shadow: false,\r\n styleUrl: \"../../output.css\",\r\n})\r\nexport class SolarExpert {\r\n @Element()\r\n el!: HTMLElement;\r\n\r\n @Prop()\r\n apiKey: string = Env.GOOGLE_MAPS_API_KEY;\r\n @Prop()\r\n language: Language = \"en\";\r\n\r\n @State()\r\n latitude: number | null = null;\r\n @State()\r\n longitude: number | null = null;\r\n @State()\r\n isLoaded: boolean = false;\r\n @State()\r\n autocomplete: google.maps.places.Autocomplete | null = null;\r\n @State()\r\n place: google.maps.places.PlaceResult | null = null;\r\n\r\n private inputElement?: HTMLInputElement;\r\n\r\n componentWillLoad() {\r\n this.loadGoogleMapsScript();\r\n }\r\n\r\n private async loadGoogleMapsScript() {\r\n try {\r\n const loader = new Loader({\r\n apiKey: this.apiKey,\r\n libraries: [\"places\"],\r\n });\r\n\r\n const places = await loader.importLibrary(\"places\");\r\n this.isLoaded = true;\r\n this.initializeAutocomplete(places);\r\n } catch (error) {\r\n console.error(\"Error loading Google Maps: \", error);\r\n }\r\n }\r\n\r\n private initializeAutocomplete(\r\n places: google.maps.PlacesLibrary,\r\n ) {\r\n if (!this.inputElement || !this.isLoaded) return;\r\n this.autocomplete = new places.Autocomplete(this.inputElement);\r\n\r\n this.autocomplete.addListener(\"place_changed\", () => {\r\n const place = this.autocomplete?.getPlace();\r\n this.latitude = place?.geometry?.location?.lat() ?? 0;\r\n this.longitude = place?.geometry?.location?.lng() ?? 0;\r\n });\r\n }\r\n\r\n componentDidLoad() {\r\n createIcons({\r\n icons: {\r\n Search,\r\n OctagonMinus,\r\n Eraser,\r\n House,\r\n Move,\r\n },\r\n nameAttr: \"data-lucide\",\r\n });\r\n }\r\n\r\n render() {\r\n return (\r\n <div class=\"flex flex-col w-full h-full p-3\">\r\n <div class=\"pb-3\">\r\n <div class=\"relative\">\r\n <i\r\n data-lucide=\"search\"\r\n class=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 \"\r\n />\r\n <input\r\n ref={(el) => this.inputElement = el}\r\n type=\"text\"\r\n placeholder=\"Search for a location\"\r\n class=\"w-full pl-10 pr-4 py-2 border border-gray-300 rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white\"\r\n />\r\n </div>\r\n </div>\r\n <map-draw\r\n latitude={this.latitude}\r\n longitude={this.longitude}\r\n apiKey={this.apiKey}\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"solar-expert.js","sourceRoot":"","sources":["../../../src/components/solar-expert/solar-expert.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Element, Env, h, Prop, State } from \"@stencil/core\";\r\nimport { Loader } from \"@googlemaps/js-api-loader\";\r\nimport { createIcons, Eraser, House, Move, OctagonMinus, Search } from \"lucide\";\r\nimport { Language } from \"../../types/lang\";\r\nimport { getLanguageStrings } from \"../../utils/lang/general\";\r\n\r\n@Component({\r\n tag: \"solar-expert\",\r\n shadow: false,\r\n styleUrl: \"../../output.css\",\r\n})\r\nexport class SolarExpert {\r\n @Element()\r\n el!: HTMLElement;\r\n\r\n @Prop()\r\n apiKey: string = Env.GOOGLE_MAPS_API_KEY;\r\n @Prop()\r\n language: Language = \"en\";\r\n\r\n @State()\r\n latitude: number | null = null;\r\n @State()\r\n longitude: number | null = null;\r\n @State()\r\n isLoaded: boolean = false;\r\n @State()\r\n autocomplete: google.maps.places.Autocomplete | null = null;\r\n @State()\r\n place: google.maps.places.PlaceResult | null = null;\r\n\r\n private inputElement?: HTMLInputElement;\r\n\r\n componentWillLoad() {\r\n this.loadGoogleMapsScript();\r\n }\r\n\r\n private async loadGoogleMapsScript() {\r\n try {\r\n const loader = new Loader({\r\n apiKey: this.apiKey,\r\n libraries: [\"places\"],\r\n });\r\n\r\n const places = await loader.importLibrary(\"places\");\r\n this.isLoaded = true;\r\n this.initializeAutocomplete(places);\r\n } catch (error) {\r\n console.error(\"Error loading Google Maps: \", error);\r\n }\r\n }\r\n\r\n private initializeAutocomplete(\r\n places: google.maps.PlacesLibrary,\r\n ) {\r\n if (!this.inputElement || !this.isLoaded) return;\r\n this.autocomplete = new places.Autocomplete(this.inputElement);\r\n\r\n this.autocomplete.addListener(\"place_changed\", () => {\r\n const place = this.autocomplete?.getPlace();\r\n this.latitude = place?.geometry?.location?.lat() ?? 0;\r\n this.longitude = place?.geometry?.location?.lng() ?? 0;\r\n });\r\n }\r\n\r\n componentDidLoad() {\r\n createIcons({\r\n icons: {\r\n Search,\r\n OctagonMinus,\r\n Eraser,\r\n House,\r\n Move,\r\n },\r\n nameAttr: \"data-lucide\",\r\n });\r\n }\r\n\r\n render() {\r\n const t = getLanguageStrings(this.language);\r\n return (\r\n <div class=\"flex flex-col w-full h-full p-3\">\r\n <div class=\"pb-3\">\r\n <div class=\"relative\">\r\n <i\r\n data-lucide=\"search\"\r\n class=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 \"\r\n />\r\n <input\r\n ref={(el) => this.inputElement = el}\r\n type=\"text\"\r\n placeholder={t.solarExpert.searchPlaceholder}\r\n class=\"w-full pl-10 pr-4 py-2 border border-gray-300 rounded-4xl focus:outline-none focus:ring-2 focus:ring-blue-500 bg-white\"\r\n />\r\n </div>\r\n </div>\r\n <map-draw\r\n latitude={this.latitude}\r\n longitude={this.longitude}\r\n apiKey={this.apiKey}\r\n language={this.language}\r\n />\r\n </div>\r\n );\r\n }\r\n}\r\n"]}
@@ -1,6 +1,7 @@
1
1
  import { h } from "@stencil/core";
2
2
  import Chart from "chart.js/auto";
3
3
  import { DEFAULT_SOLAR_PANEL_TYPE } from "../../config";
4
+ import { getLanguageStrings } from "../../utils/lang/general";
4
5
  const SOLAR_RADIATION = [
5
6
  0,
6
7
  0,
@@ -83,11 +84,11 @@ const CONSUMPTION_PROFILES = {
83
84
  };
84
85
  export class SolarSystemForm {
85
86
  systemConfigs = {};
87
+ language = "en";
88
+ roofPolygons = {};
89
+ obstructionPolygons = {};
86
90
  householdConsumption = 3500;
87
91
  consumptionProfile = "mostly_at_home";
88
- hasHeatPump = false;
89
- hasElectricCar = false;
90
- electricCarConsumption = 7.6;
91
92
  electricityPrice = 0.3;
92
93
  compensationRate = 0.07;
93
94
  autonomy = 0;
@@ -204,9 +205,10 @@ export class SolarSystemForm {
204
205
  }
205
206
  validateForm() {
206
207
  let isValid = true;
208
+ const t = getLanguageStrings(this.language);
207
209
  // Validate name
208
210
  if (!this.name.trim()) {
209
- this.nameError = "Name is required";
211
+ this.nameError = t.solarSystemForm.nameError;
210
212
  isValid = false;
211
213
  }
212
214
  else {
@@ -215,11 +217,11 @@ export class SolarSystemForm {
215
217
  // Validate email
216
218
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
217
219
  if (!this.email.trim()) {
218
- this.emailError = "Email is required";
220
+ this.emailError = t.solarSystemForm.emailError;
219
221
  isValid = false;
220
222
  }
221
223
  else if (!emailRegex.test(this.email)) {
222
- this.emailError = "Please enter a valid email address";
224
+ this.emailError = t.solarSystemForm.validEmailError;
223
225
  isValid = false;
224
226
  }
225
227
  else {
@@ -239,53 +241,61 @@ export class SolarSystemForm {
239
241
  consumption: this.householdConsumption,
240
242
  autonomy: this.autonomy,
241
243
  costSavings: this.costSavings,
244
+ roofPolygons: this.roofPolygons,
245
+ obstructionPolygons: this.obstructionPolygons,
242
246
  });
243
247
  }
244
248
  render() {
245
- if (Object.keys(this.systemConfigs).length === 0) {
246
- return h("div", null);
247
- }
248
- return (h("div", { class: "flex flex-col justify-center items-center w-full h-full gap-4 p-4" }, h("h1", { class: "text-2xl font-bold text-[#271200] mb-4" }, "Solar System Configuration"), h("div", { class: "w-full max-w-2xl bg-[#f3ebda] rounded-4xl p-6 space-y-6" }, h("div", { class: "space-y-4" }, h("h2", { class: "text-lg font-semibold text-[#271200]" }, "System Information"), h("div", { class: "grid grid-cols-2 gap-4" }, h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Number of Solar Panels"), h("input", { type: "number", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.numberOfPanels, readOnly: true })), h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Panel Peak Power (kW)"), h("input", { type: "number", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.panelPeakPower, readonly: true }))), h("div", { class: "bg-white rounded-4xl p-4" }, h("div", { class: "flex items-center justify-between" }, h("span", { class: "text-gray-600" }, "Total System Peak Power"), h("span", { class: "text-xl font-bold text-[#271200]" }, (DEFAULT_SOLAR_PANEL_TYPE.kWattPeak *
249
- this.numberOfPanels).toFixed(1), " kW")))), h("div", { class: "space-y-4" }, h("h2", { class: "text-lg font-semibold text-[#271200]" }, "Household Electricity Consumption"), h("div", { class: "grid grid-cols-2 gap-4" }, h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Annual Consumption (kWh)"), h("input", { type: "number", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.householdConsumption, onInput: (e) => {
249
+ const t = getLanguageStrings(this.language);
250
+ return (h("div", { key: '21698e582f74c74a60f9edfcedb306b05f0222e7', class: "flex flex-col justify-center items-center w-full h-full gap-4 p-4", style: {
251
+ display: (Object.keys(this.systemConfigs).length === 0)
252
+ ? "none"
253
+ : "flex",
254
+ } }, h("h1", { key: 'ccdf1309b25a060c3490429c7c5e5c930d2f0e9e', class: "text-2xl font-bold text-[#271200] mb-4" }, t.solarSystemForm.title), h("div", { key: '36ca7d7fbfe09abd5c15bbdfa1d28e4ba121c338', class: "w-full max-w-2xl bg-[#f3ebda] rounded-4xl p-6 space-y-6" }, h("div", { key: '48b767da374ac53d3560a06966f707e9e6c78c3c', class: "space-y-4" }, h("h2", { key: '9b3195b8e9da8865f4b2943be5d409bb704c55a5', class: "text-lg font-semibold text-[#271200]" }, t.solarSystemForm.systemInformation), h("div", { key: 'b05ed4419f53cc7a2920018588156c199610c133', class: "grid grid-cols-2 gap-4" }, h("div", { key: 'e537be319834e51e0e67d77b04330c74a7383b0c' }, h("label", { key: '7cc9be6b154ba347fd480d842c9377bd474ac261', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.numberOfPanels), h("input", { key: 'ef905fa5d0e78556a04b30af18ce40f67c2afae3', type: "number", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.numberOfPanels, readOnly: true })), h("div", { key: '269b65bf3584504f66e0b5121ce34f7fd0bb2cef' }, h("label", { key: '0a8b4a4ab90dd9feb27dbfe0003d4e0546df605f', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.panelPeakPower), h("input", { key: 'f02985694ab0178aa4d5e0b2f38e721d31576e47', type: "number", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.panelPeakPower, readonly: true }))), h("div", { key: '2e56d50d9a4cb464328c6e737af3d6676fe52310', class: "bg-white rounded-4xl p-4" }, h("div", { key: '1f1b7d601a4e9fe7e39e981a52b5c9e5e62dcb14', class: "flex items-center justify-between" }, h("span", { key: '9a167077be59452754abbfeaba5c540fae5d9494', class: "text-gray-600" }, t.solarSystemForm.totalSystemPeakPower), h("span", { key: '83a0c5966f55806a035622112b553c3a607119b7', class: "text-xl font-bold text-[#271200]" }, (DEFAULT_SOLAR_PANEL_TYPE.kWattPeak *
255
+ this.numberOfPanels).toFixed(1), " kW")))), h("div", { key: 'f5cd032e9a2c5bb00f2f358c88da981c9362d5a5', class: "space-y-4" }, h("h2", { key: '8d1745e6aa800cc90626c76c56946f5767f41e27', class: "text-lg font-semibold text-[#271200]" }, t.solarSystemForm.householdConsumptionTitle), h("div", { key: '9ca7290838c235c81ffef96ffd447d1308afa7bc', class: "grid grid-cols-2 gap-4" }, h("div", { key: '41324b57994209ac6cc51d8d3a243daf6f533650' }, h("label", { key: '970eb8e5ca0e5dc5b1e7f04bb50f99852e949e52', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.annualConsumption), h("input", { key: '03c37fd6aa3f87d6b29a23b86a7addd6dbab0d44', type: "number", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.householdConsumption, onInput: (e) => {
250
256
  this.householdConsumption = parseInt(e.target
251
257
  .value);
252
258
  this.recalculate();
253
259
  this.updateChart();
254
- } })), h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Consumption Profile"), h("select", { class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", onChange: (e) => {
260
+ } })), h("div", { key: '001a1c49fab99814282803dcf9b46ca6828f26a3' }, h("label", { key: '010a9c24984eea9f42e676f8be8568243d8c0160', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.consumptionProfileTitle), h("select", { key: 'af984af3147b140f7a7e314ef5bb987babbff8ac', class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", onChange: (e) => {
255
261
  this.consumptionProfile =
256
262
  e.target
257
263
  .value;
258
264
  this.recalculate();
259
265
  this.updateChart();
260
- } }, h("option", { value: "mostly_at_home", selected: this.consumptionProfile ===
261
- "mostly_at_home" }, "Mostly at Home"), h("option", { value: "mostly_away", selected: this.consumptionProfile ===
262
- "mostly_away" }, "Mostly Away")))), h("div", { class: "mt-4" }, h("canvas", { ref: (el) => this.chartRef = el }))), h("div", { class: "space-y-4" }, h("h2", { class: "text-lg font-semibold text-[#271200]" }, "Electricity Costs"), h("div", { class: "grid grid-cols-2 gap-4" }, h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Electricity Price (\u20AC/kWh)"), h("input", { type: "number", step: "0.01", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.electricityPrice, onInput: (e) => {
266
+ } }, h("option", { key: '95c55aa19f025f657ee658295e0868239846b9a5', value: "mostly_at_home", selected: this.consumptionProfile ===
267
+ "mostly_at_home" }, t.solarSystemForm.consumptionProfiles
268
+ .mostlyAtHome), h("option", { key: 'b9f81266edee4503ae85f01b0c54a33ebadcb9c0', value: "mostly_away", selected: this.consumptionProfile ===
269
+ "mostly_away" }, t.solarSystemForm.consumptionProfiles
270
+ .mostlyAway)))), h("div", { key: '9c1d45bc979bf539cad031602762bd498f421ec0', class: "mt-4 h-48" }, h("canvas", { key: 'ce3dd39bb23c92a1dc13b8d001229fb062afced8', ref: (el) => this.chartRef = el }))), h("div", { key: 'fea64a12ca9057fdc0c82a158f036f89cddf741e', class: "space-y-4" }, h("h2", { key: '48a7bbaf7955b89764f58082481a6f1ef0c60405', class: "text-lg font-semibold text-[#271200]" }, t.solarSystemForm.electricityCostsTitle), h("div", { key: '70c75587b835d494e10710c913bdd40470cea41f', class: "grid grid-cols-2 gap-4" }, h("div", { key: '3fdbec26fb2172ebdd19253339bf008708ce0e90' }, h("label", { key: 'fad9ed8e86d81e5b9cb9feee37e43c03691cf5c9', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.electricityPrice), h("input", { key: 'd178167fa3c5523cb0f94f40d239f29027e29f1c', type: "number", step: "0.01", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.electricityPrice, onInput: (e) => {
263
271
  this.electricityPrice = parseFloat(e.target
264
272
  .value);
265
273
  this.recalculate();
266
274
  this.updateChart();
267
- } })), h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Compensation Rate (\u20AC/kWh)"), h("input", { type: "number", step: "0.01", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.compensationRate, onInput: (e) => {
275
+ } })), h("div", { key: '1ac29180a93b9482b484ff41a99ec98f0757d7ed' }, h("label", { key: '83fd31d99465b3bd1e8aea6d692a8338d87f9b7f', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.compensationRate), h("input", { key: 'ff05f9d22ebcba02577908f9a93ef4998c12c72a', type: "number", step: "0.01", class: "w-full px-4 py-2 rounded-4xl border border-gray-300 focus:ring-2 focus:ring-[#964500] focus:border-transparent", value: this.compensationRate, onInput: (e) => {
268
276
  this.compensationRate = parseFloat(e.target
269
277
  .value);
270
278
  this.recalculate();
271
279
  this.updateChart();
272
- } })))), h("div", { class: "space-y-4 pt-4 border-t border-gray-200" }, h("h2", { class: "text-lg font-semibold text-[#271200]" }, "Results"), h("div", { class: "bg-white rounded-4xl p-4" }, h("div", { class: "flex items-center justify-between" }, h("span", { class: "text-gray-600" }, "Autonomy"), h("span", { class: "text-xl font-bold text-[#271200]" }, this.autonomy.toFixed(1), "%")), h("div", { class: "flex items-center justify-between mt-4" }, h("div", { class: "flex items-center gap-2" }, h("span", { class: "text-gray-600" }, "Cost Savings"), h("div", { class: "relative group" }, h("svg", { xmlns: "http://www.w3.org/2000/svg", class: "h-5 w-5 text-gray-400 cursor-help", viewBox: "0 0 20 20", fill: "currentColor" }, h("path", { "fill-rule": "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z", "clip-rule": "evenodd" })), h("div", { class: "absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 w-64 p-2 bg-gray-800 text-white text-sm rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none" }, "Cost savings are calculated based on current electricity prices and compensation rates. The calculation includes both direct usage of solar energy and compensation for excess energy fed back into the grid."))), h("span", { class: "text-xl font-bold text-green-600" }, this.costSavings.toFixed(2), "\u20AC/year")))), h("div", { class: "space-y-4 pt-4 border-t border-gray-200" }, h("h2", { class: "text-lg font-semibold text-[#271200]" }, "Request an Offer"), h("div", { class: "grid grid-cols-2 gap-4" }, h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Name"), h("input", { type: "text", class: `w-full px-4 py-2 rounded-4xl border ${this.nameError
280
+ } })))), h("div", { key: '5ab652449205d9fb0c16e515db23b7dd585c5679', class: "space-y-4 pt-4 border-t border-gray-200" }, h("h2", { key: '871dc06b9618427f40a5c866b1d1ca32393ec79b', class: "text-lg font-semibold text-[#271200]" }, t.solarSystemForm.resultsTitle), h("div", { key: 'acbd1ba8328b4eed7a56318f1739d62d167e52d5', class: "bg-white rounded-4xl p-4" }, h("div", { key: '4848ebd3412765176693c39d02fbdc71f8a0be87', class: "flex items-center justify-between" }, h("span", { key: 'c1315ac70c2e06da992b96eea02b7f8c9dde407d', class: "text-gray-600" }, t.solarSystemForm.autonomy), h("span", { key: 'cd5d010aa10c6cca144d5c9285caac323cbea0f2', class: "text-xl font-bold text-[#271200]" }, this.autonomy.toFixed(1), "%")), h("div", { key: 'dcc273e531ae2f4783ff5683cbc49727ffd1f191', class: "flex items-center justify-between mt-4" }, h("div", { key: '8858087a40d0f449ae437b743bb0b9eb135ae051', class: "flex items-center gap-2" }, h("span", { key: '3480321e3d508f5c18826cb8586717abe153a832', class: "text-gray-600" }, t.solarSystemForm.costSavings), h("div", { key: '6a2c193fe5c7e97d9849db449601cbcd357c94fd', class: "relative group" }, h("svg", { key: '49e444dd8d17f589b4779e53ad9c22f7fd58b01b', xmlns: "http://www.w3.org/2000/svg", class: "h-5 w-5 text-gray-400 cursor-help", viewBox: "0 0 20 20", fill: "currentColor" }, h("path", { key: '42fe60afec56014b869b278a15e4023b53964b1a', "fill-rule": "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z", "clip-rule": "evenodd" })), h("div", { key: '17b7552a1d9bfa0e2ab6f5c40d7b5a424853f637', class: "absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 w-64 p-2 bg-gray-800 text-white text-sm rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none" }, t.solarSystemForm
281
+ .savingsDisclaimer))), h("span", { key: '94bee7ebb6901d9bc1a1030735947ad667c9a220', class: "text-xl font-bold text-green-600" }, this.costSavings.toFixed(2), "\u20AC/", t
282
+ .solarSystemForm.year)))), h("div", { key: 'e661d7502b61d49581c67b00868e5aa579338ef0', class: "space-y-4 pt-4 border-t border-gray-200" }, h("h2", { key: '8f2963a6511f04b8b222584ed846997163f7f59e', class: "text-lg font-semibold text-[#271200]" }, t.solarSystemForm.requestOffer), h("div", { key: '8f190545b0e957b588e0034f60a8925e67ad2835', class: "grid grid-cols-2 gap-4" }, h("div", { key: '439c96826a1addbb3dcbdd088bdb5b3a6ed544e8' }, h("label", { key: 'c5b0475135b8601032dc1e0bda014f7f9fbe7266', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.name), h("input", { key: '00839762b8291f610892b2340890284a426b25cc', type: "text", class: `w-full px-4 py-2 rounded-4xl border ${this.nameError
273
283
  ? "border-red-500"
274
284
  : "border-gray-300"} focus:ring-2 focus:ring-[#964500] focus:border-transparent`, value: this.name, onInput: (e) => {
275
285
  this.name =
276
286
  e.target
277
287
  .value;
278
288
  this.validateForm();
279
- }, placeholder: "Your name" }), this.nameError && (h("p", { class: "text-red-500 text-sm mt-1" }, this.nameError))), h("div", null, h("label", { class: "block text-sm font-medium text-gray-600 mb-1" }, "Email"), h("input", { type: "email", class: `w-full px-4 py-2 rounded-4xl border ${this.emailError
289
+ }, placeholder: "Your name" }), this.nameError && (h("p", { key: '5c6cc2d03812388526dc0cac792496ebde5019f5', class: "text-red-500 text-sm mt-1" }, this.nameError))), h("div", { key: 'b000645ab8d4c4a3f2135530f8e784419eb59603' }, h("label", { key: 'a18835b969e58fb2e6dccd5326c2a36c5123a6af', class: "block text-sm font-medium text-gray-600 mb-1" }, t.solarSystemForm.email), h("input", { key: 'd433805683a648853999ccef0548e1739666ffc8', type: "email", class: `w-full px-4 py-2 rounded-4xl border ${this.emailError
280
290
  ? "border-red-500"
281
291
  : "border-gray-300"} focus:ring-2 focus:ring-[#964500] focus:border-transparent`, value: this.email, onInput: (e) => {
282
292
  this.email =
283
293
  e.target
284
294
  .value;
285
295
  this.validateForm();
286
- }, placeholder: "your.email@example.com" }), this.emailError && (h("p", { class: "text-red-500 text-sm mt-1" }, this.emailError)))), h("div", { class: "flex justify-center" }, h("button", { onClick: () => this.handleRequestOffer(), disabled: !this.name.trim() ||
296
+ }, placeholder: "your.email@example.com" }), this.emailError && (h("p", { key: '4ee435fe7a8d6d2f7423a46bde1e212e5c9285f6', class: "text-red-500 text-sm mt-1" }, this.emailError)))), h("div", { key: 'a3bc14b28ebd58370acc012d839c40b546d22929', class: "flex justify-center" }, h("button", { key: '21edd03ed559beaa02891d8bce22f3f73f6357ca', onClick: () => this.handleRequestOffer(), disabled: !this.name.trim() ||
287
297
  !this.email.trim() || !!this.nameError ||
288
- !!this.emailError, class: "px-4 py-2 bg-[#271200] text-white rounded-4xl hover:bg-[#964500] transition-colors duration-200" }, "Request Offer"))))));
298
+ !!this.emailError, class: "px-4 py-2 bg-[#271200] text-white rounded-4xl hover:bg-[#964500] transition-colors duration-200" }, t.solarSystemForm.requestOfferButton))))));
289
299
  }
290
300
  static get is() { return "solar-system-form"; }
291
301
  static get encapsulation() { return "shadow"; }
@@ -325,6 +335,82 @@ export class SolarSystemForm {
325
335
  "getter": false,
326
336
  "setter": false,
327
337
  "defaultValue": "{}"
338
+ },
339
+ "language": {
340
+ "type": "string",
341
+ "attribute": "language",
342
+ "mutable": false,
343
+ "complexType": {
344
+ "original": "Language",
345
+ "resolved": "\"de\" | \"en\" | \"es\"",
346
+ "references": {
347
+ "Language": {
348
+ "location": "import",
349
+ "path": "../../types/lang",
350
+ "id": "src/types/lang.ts::Language"
351
+ }
352
+ }
353
+ },
354
+ "required": false,
355
+ "optional": false,
356
+ "docs": {
357
+ "tags": [],
358
+ "text": ""
359
+ },
360
+ "getter": false,
361
+ "setter": false,
362
+ "reflect": false,
363
+ "defaultValue": "\"en\""
364
+ },
365
+ "roofPolygons": {
366
+ "type": "unknown",
367
+ "attribute": "roof-polygons",
368
+ "mutable": false,
369
+ "complexType": {
370
+ "original": "{ [id: string]: Polygon }",
371
+ "resolved": "{ [id: string]: Polygon; }",
372
+ "references": {
373
+ "Polygon": {
374
+ "location": "import",
375
+ "path": "../../types/shapes",
376
+ "id": "src/types/shapes.ts::Polygon"
377
+ }
378
+ }
379
+ },
380
+ "required": false,
381
+ "optional": false,
382
+ "docs": {
383
+ "tags": [],
384
+ "text": ""
385
+ },
386
+ "getter": false,
387
+ "setter": false,
388
+ "defaultValue": "{}"
389
+ },
390
+ "obstructionPolygons": {
391
+ "type": "unknown",
392
+ "attribute": "obstruction-polygons",
393
+ "mutable": false,
394
+ "complexType": {
395
+ "original": "{ [id: string]: Polygon }",
396
+ "resolved": "{ [id: string]: Polygon; }",
397
+ "references": {
398
+ "Polygon": {
399
+ "location": "import",
400
+ "path": "../../types/shapes",
401
+ "id": "src/types/shapes.ts::Polygon"
402
+ }
403
+ }
404
+ },
405
+ "required": false,
406
+ "optional": false,
407
+ "docs": {
408
+ "tags": [],
409
+ "text": ""
410
+ },
411
+ "getter": false,
412
+ "setter": false,
413
+ "defaultValue": "{}"
328
414
  }
329
415
  };
330
416
  }
@@ -332,9 +418,6 @@ export class SolarSystemForm {
332
418
  return {
333
419
  "householdConsumption": {},
334
420
  "consumptionProfile": {},
335
- "hasHeatPump": {},
336
- "hasElectricCar": {},
337
- "electricCarConsumption": {},
338
421
  "electricityPrice": {},
339
422
  "compensationRate": {},
340
423
  "autonomy": {},