@qispace/vue3-player 0.0.14 → 0.0.15

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.
@@ -1,2331 +1,2329 @@
1
- import { resolveComponent as c, openBlock as l, createBlock as y, normalizeStyle as M, defineComponent as W, createElementBlock as m, createElementVNode as o, createVNode as u, toDisplayString as _, withCtx as h, createTextVNode as L, withDirectives as x, Fragment as U, renderList as D, normalizeClass as E, vShow as B, createCommentVNode as f, renderSlot as A, ref as ge, mergeProps as F, resolveDynamicComponent as ve, createSlots as Be, normalizeProps as fe, guardReactiveProps as be, toHandlers as ye, Transition as $, pushScopeId as ee, popScopeId as te, vModelText as Fe, createStaticVNode as we } from "vue";
2
- import ke from "axios";
3
- import { PlayerV2 as G } from "@qispace/player-core";
1
+ import fe from "axios";
2
+ import { openBlock as l, createElementBlock as m, resolveComponent as c, withDirectives as x, createElementVNode as o, normalizeStyle as M, vShow as B, createVNode as u, Fragment as R, renderList as D, createCommentVNode as f, withCtx as h, toDisplayString as _, createTextVNode as L, normalizeClass as E, createBlock as y, renderSlot as A, resolveDynamicComponent as be, normalizeProps as ye, guardReactiveProps as we, defineComponent as W, ref as ke, mergeProps as F, createSlots as De, toHandlers as Ce, Transition as $, pushScopeId as ae, popScopeId as le, vModelText as Oe, createStaticVNode as _e } from "vue";
3
+ import { PlayerV2 as K } from "@qispace/player-core";
4
4
  import * as T from "three";
5
- const Ee = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABsCAYAAACPZlfNAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAA6ySURBVHgB7Z3Nb1TVG8efQstLActbIBAI8wsJBgLxZ+KeaVy5EVgZo4klceOKstCdYdQ/gLLSjQESjEvBjTs7Ju40AQMBIQEvgUAgvLRCWlpax/O9c56b09N7Z87bPTNT+SSHTqftMHO+93nO955Xolf0FH3UwzQajYr4wmVIlPUFvzohyqQoCR739fVdoh6lJwQTwkCI/4vyhihV+bhCfkC0RH79BV+FkBPU5XStYEKkKjXFOSi/xqBOTQEvCPHq1IV0lWBSpEOijFBxeotFQk0BT/VyCg0O0p0ox0QZb3QvF0X5iLqAjkVYo9kujYpyjDofTaYkopwV5YyIuoQ6QHTBelQonYSawo31glFxRog1KsrTxtLhr0bkVBklwsSHgg0/SfHcXmwSUYZjpMllVDJCrJr4cpGWrligIspf8rOWSmkR1mj2QpympS1UHgmVGG2lCCbEOkxNsUozFXNzczQ7O0vT09M0MzOTlpSbN2nT99+nDx+//z7R7t3p45UrV6ZlxYoVtHr1aurv76cSSUQ5LkQ7T4EJ/q5lWjhBgYEgExMTNDU1Rc+fP0/FymPVgwf02u+/p4+n3n6bXmzYkPt7EA3irV+/ntatW5eKGZCKKD+IuvhCiFajgAQVTLzBMWra9SBApMePH6dCIZJagQpfvnw5rRwczJ4bFKIMCDEgbhaBErweyuTkZPo9BIRwW7ZsCSneCVEnQ0K04xSIIII1mvdWP1Cg9goCPRCRgkjSQWWuXbuWBoUwHCVqBb8Uf/O3fLxj504a2LMn+9n8/HwaoRDq2bNnWToFLODDhw/T19+0aRNt3ryZAjAq2/OjIe7ZvAWTYo1TswfdGbRJqCwUVKwKrnykrqGhIa+rHxGI1+JIAog+iIdIxleACwXl/v37tG3bthDCoU2viLoa9hXNS7BQYj169CitHLVdgilApaKgossCEYpoQmHx8F4Qefj+9u3boYRDHY37iuYbYafJQyykpzt37ixIfXz1I6Jio4qHiMsTbo9IsR5RjrpC0zFMjjgLJg3GYXLk3r17aQUwqIQdO3Z0RKg8ioS7cuVKGm3bt28nR6qi7k66GhEnwaR1d3KD+OBJkmRRFSv1ucLCQTRcZACPIaRHtMGITLpYfuuuKXlT7HSfhfbh2rVrmVhIf3v37k2v2G4USwXv8cCBA5lAiLYbN25kRsWBE7IurbASTNrTk+QAbDo+IDvArVu3plco2o2QzMsoAHPyBjoUeK/79+/P0iGLhs/myGlZp8ZYdU1hOIEcJr+o7RVS4K5du0prq56+8w79I0VbJip2w08/URngXhGpnS9Aj3atLlKjsQkxjjDZblXIElUspBOkwLLEevnbb5lYAI9fBo4yBp9h3759WYpU2zhLYEKMmxgjwWTYWrdbulhlpECVmR9/XPTci3PnqCzwWVTj4SFaTY4ZtsU0wsbJEuT1mGKh7coTDBHWcDcGbckTzbFNM/IGbQUTyo+QZSqEc7p79276OIZYAOkwD4j14rvvqEx00fDZHdwjUuNou19qKZjserJKhXyfBWAwYogFpr/5pvBnMz//TGXDovHtyU0xLqePEBhwQtZ5Ie0iDIpXyALYXO4ThBuMIZZuNnTmr18vzXyo4LNWKpXm/yncI7qzLIFYLTskCgWTRsNqRhAaXBYLFjdWN1Ne26VTpvlQwWfmkQCkRQcTMtoqylpF2AhZRBfCXzUZuC+JQZHZ0CnbfKjsFONw6MUBqBN0clvQMspaCWYVXUiFzB5l0LBsisyGTgzzoYLUyO0ZGzALCqMsVzBbZ4jxLDUVxmi3mFZmQyeG+WBQB2pqRB1ZALFyA6Yowqx64juRCkE7s6ETy3ww6C9V78/0kfQ25HYMLxJM3nEbD0qq0RVTLGDSdunEMh8AKRFjfAB1ZHlDjfuyqv5kXoQ5RxfGjWJhajZ0YpoPwNPoAOarWHJIfyJPsCoZ0snoMjUbOrHNB+C2DCkRvfwWjOhPLBBMhmCFDMGoK4gdXcDGbOjENB8AUcaO0TLK1utpUY+wQ2QI7rt45LgT0fWPW694SmzzAVTHaNlldVD9RhfM2GyoVwrn6Fi4tF2LXuPCBYoJHCPDmcmQqvpNJpi8UauSIdwbDbFi3ne5mg2d2fHxqOaDJ7ECnh5uSFW9iVYjzDi6ENI81z122+VqNnRS8xE5yjBzGaCryjItZtqogh0kQ9Sxntjp0Mds6Lwctx6X9ULtDLd0i2/wA6cI45Dm9Vax8DUbi15PGI+Y5kOtr3arcTSq/EAVrEKGcDhj9UhMQrRdOrORLT5nJMsR6dyUaBRhuPnjqwPLcmIRymzo4DVjmg++yNHhYNG3WOEHqWCmM3aAOrYzqCyeK5s8s9EnrlbMPUTpK2hL1d/J+73Y5kOtMxvjITTaha8cYcZDw+qSoJiC5ZmNFcPD6URRlI2//kr9r7++6HfwHP8OCv5GJ6b5UNt8y3asgn+Wqd+YoF4VsebDm5qNdWNjhZHW8vUjmg918YSlta/gHxZsyPSvOMJiukPTtgspb/CTT8iF2ciDm+n/WbCwvoA0C1qnRCbwqvtCbM3Gqg8+oP633iJbYpoPx8y0QDBjHObaeeHSs7Huq6+sU2NM88GCWUZYSulbF/ni0rPhmhpj93y40NWC2fZszCoV7pIaY/d8uNDVgtneKE+fO7egwl1SY+yeD1usBWOzYTkDyBrXno3nn3+emQekxtWWqTGm+XBx2iyY9b4R2AilTFyHUZBCp77+Ovs+72a6FTHMh4vZIKkRC2Y8ouZ4D2GNz0QZ/O2sh4Eo23w43ssuECwx/COfO3Vj5q5fT+dd+KCmRlvKNB9qU2J5L5vgH2vB1CGVsqIsxGRPiPVstO36uELKMh9q57llhKVZMBXMZvdM9aqwXJVhBCp6NlBKQpRMO4pflvlwHe3gww5Ul5iY/CHu0h1HTY3AnEHTisLvwWRwyQM33nN//pn9js1rl2E+eGogxLLoospOpujXnqyQARg1VberC4mN2UAktotGVPzke++RCzAfqz/8kELCEWaZDhN+oEZYnQxRR01DGo8QZiMkoc0HbzAGLFenZhGmCvYHGeIx+6clMVeWmBLSfHjMNqvzA1WwS2QIjAdHmeWkyEJCmo2QhDQfPOMX7ZdlSsyCKRNM7pJZJ0M4ynDVhOimsjEbMQllPtS1CJaTl+rqDqZ6X2KdDFFn/HrsZpYRewmQDSF6PtR0qM6zN2BB5tMF+4UMQVr0WKi2gG4zGzohzAcvfHRYi3Be/WaBYPIYQWMX4bFQbQHdaDZ0fMyHuvDRci1CIjRZEER5wytnyBCPhWoZoc3GcmXPQtue+lb4mA+PZcV1/Yk8waxaWHWhmkuUhTAbA2JkefDTT9O5iWu+/DJ7fvCzz9K5iGvFQKbLxBwVV/Phuaz4lP7Eok2akRYbjUadDNeKoQF98uRJ6oKwpTlytM2sIFezAZEGhodp1aFDLUeVMYi58t1308IbXqLiXbaXden58IiuS3mHpRbtqo2GrkoGQBxcOdjBjbc2MN1KFaPKNmbDVKQifMVj8zFgGK3q3lsO0TWW92SRYDjfsUaG8xV5f3ekRbRl+N5krGdaGRkuwlekIlzFg/kwEUzfe8vBbJzN+0GuYLhRkwcJ1MgQbCCCLc552zmT/aaKrHJZIhVhIx7MB6bQtXtfnntvnSn6QauDBtDgYQTQKMrQ3YKwx1WFSEN7hl3NikCFqEMisUUqop14bD5atWX6NoQOPfNni35YKJhLlOHNofuFUyOfSpQHrtRuEamIIvFamY+nT5/67r3V8ozolvvWy9Xr2KveajnS1atX09QIQ4Jtz/PaM1ypZYiE2VZ/f/xx+vi1b781Ngg2QLxlOcYK7RY3C457HSeivNnq9KOW8xLlH35BFuAN7pbnTuKNI5fnjZl1Y0SZUiSWevKF4/a5tXZHVbWdSCpeAGmxThYgFXL7xcddxF5EERMWi9stdUdSCwqdoYrpzF/ro5PQA6KfUbIURdPFwmfm3h9LjI7zMBJM3nHXyBL1PJKlKFqeWI77btVMZ64Zz60XL4i2rE6W6KKhUQ45raBTwA3iswQQK5F1a4TtYoij5DAPHx+E2zQ0ytiE3/GMkq4A95i3bt3KDAY+m6tYZHm8opVgMmyPkgPI6/oZJZcvX+6pFIn3el30ffJQEp984dhmgeM2k3iB9XIjeVx7jRyAc1JF4zMluz3asFIH7zHvdEGPvbZqLkffO52BiZwrb6qtJ6/zKXd5Z0oGOjM5KGirsO+8uo7Ao71ixmzaLRXnU2ZxSqrcQadKDuADowebnWPgM5O9yTutne8vPffYOu9z1L3vOc5HyOPgbY62ojOTIRwqKdYWE0WntXOfYIC9IXF75OQBGC/BZAcxXI7XaemtDrsGmMeHn5chHv4vRBOKGk0g8JHFEKuzR9sDRTScmn6YPFCFUxdboCK5MhGVSEkQD0M6eIyKNYEvBCxIQMFr5q1xK+G09rooR3zFAt6CAflGjuAEcHIwIjosHE85QMXyqg88h6JPEYeQKAPCIPA+THfF/dK0EBXprd3iQ4gPgTZu3Bg6ijFc4pUGVYIIxkgjAvFqFAAIoHYi88wsjhIVFnKVeJ4Fm5qephcFa9ggClIthMJevCW1kzVXN1hEUMGAtPyYvI9oq1AgIB5HHkDUQDRe8pRF0Nat2ZS2NSKtrZG/j7/nRRz4WvJOdLhoj7rcZ7XD6uBtG+QJfzAjFfpvUaemWAmVQGk74eANi/I/CpQeewSkwOGyxAKlRZjKfyDa6tTsFzReY+dKlL2mlGiDW0po6YC2alRGVeligSgRpiL7IHFG2Qj1bsRBKEydOBXi3sqG6IIxyrHDI9Q7wnVMqK4Ch6SKcrHRvYyLcqzR5hTzGHQswvJoNHv/kS6r1PmoQwSdoWbvuvHK1LLpKsFUhHg4vAd9k85DOA7UuXSTSCpdK5iKTEU44adKTQEr5DE6IEmo2YNel1//6IV2qScEK0KmUHQdVqg5nbyojZmQJaHmLKXb9IpXxOBfKqW3YKRX2kIAAAAASUVORK5CYII=", C = (e, t) => {
5
+ class H {
6
+ async loadJson(t) {
7
+ return (await fe.get(t)).data;
8
+ }
9
+ async loadImage(t) {
10
+ return new Promise((i, r) => {
11
+ const n = new Image();
12
+ n.crossOrigin = "anonymous", n.onload = () => {
13
+ i(n);
14
+ }, n.onerror = r, n.src = t;
15
+ });
16
+ }
17
+ async loadImageData(t) {
18
+ const i = await this.loadImage(t), r = document.createElement("canvas");
19
+ try {
20
+ const n = r.getContext("2d");
21
+ return r.width = i.width, r.height = i.height, n.drawImage(i, 0, 0), r.toDataURL("image/png");
22
+ } finally {
23
+ r.remove();
24
+ }
25
+ }
26
+ }
27
+ const C = (e, t) => {
6
28
  const i = e.__vccOpts || e;
7
29
  for (const [r, n] of t)
8
30
  i[r] = n;
9
31
  return i;
10
- }, De = {
11
- name: "QiNorthDirection",
12
- props: {
13
- longitude: { type: Number, default: () => 0 }
14
- },
15
- data() {
16
- return {
17
- compassNeedle: Ee
18
- };
19
- },
32
+ }, Re = {
33
+ name: "QiHoverProbe",
20
34
  computed: {
21
- needleRotation() {
22
- return {
23
- transform: `rotate(${90 - this.longitude}deg)`,
24
- transition: " transform 0.5s ease-in"
25
- };
35
+ isHoverEnabled() {
36
+ return window.getComputedStyle(this.$refs.hoverCheck).display === "none";
26
37
  }
27
38
  }
39
+ }, Ue = {
40
+ ref: "hoverCheck",
41
+ class: "hover-check"
28
42
  };
29
- function Oe(e, t, i, r, n, s) {
30
- const a = c("v-img");
31
- return l(), y(a, {
32
- src: n.compassNeedle,
33
- style: M(s.needleRotation)
34
- }, null, 8, ["src", "style"]);
35
- }
36
- const ie = /* @__PURE__ */ C(De, [["render", Oe]]);
37
- function X(e) {
38
- return e.toLocaleString("en-no", {
39
- month: "short",
40
- day: "numeric"
41
- });
43
+ function Te(e, t, i, r, n, s) {
44
+ return l(), m("div", Ue, null, 512);
42
45
  }
43
- const Ue = W({
44
- setup() {
45
- },
46
- name: "QiBuildingChooserSunSimControl",
46
+ const N = /* @__PURE__ */ C(Re, [["render", Te], ["__scopeId", "data-v-e4729353"]]), Ie = {
47
+ methods: {
48
+ throttle(e, t) {
49
+ let i = !0;
50
+ return function(...r) {
51
+ i && (i = !1, e.apply(this, r), setTimeout(() => i = !0, t));
52
+ };
53
+ }
54
+ }
55
+ }, Ve = {
56
+ name: "QiApartmentChooserRaster",
57
+ components: { QiHoverProbe: N },
58
+ mixins: [Ie],
47
59
  props: {
48
- modelValue: { type: Number, required: !0 },
49
- dateSelector: { type: Object, required: !0 },
50
- isLoading: { type: Boolean, default: !1 }
60
+ cdnFileResolver: { type: Function, required: !0 },
61
+ viewModel: { type: Object, required: !0 },
62
+ selectedUnitId: { type: String, default: null },
63
+ unitCallback: { type: Function, default: (e) => e },
64
+ canGoToUnitCallback: { type: Function, default: () => !0 },
65
+ sceneData: { type: Array, default: [] },
66
+ colorCallback: {
67
+ type: Function,
68
+ default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
69
+ },
70
+ drawObserver: {
71
+ type: [Object, Array, String, Number, Boolean],
72
+ default: null
73
+ }
51
74
  },
52
- emits: ["update:modelValue"],
75
+ emits: ["select-unit", "go-to-unit", "hover-over", "hover-out"],
53
76
  data() {
54
77
  return {
55
- currentValue: this.modelValue,
56
- currentDate: null
78
+ pos: { x: 0, y: 0, width: 0, height: 0 },
79
+ canvas: null,
80
+ canvasBg: null,
81
+ canvasWidth: 0,
82
+ canvasHeight: 0,
83
+ context: null,
84
+ contextBg: null,
85
+ image: null,
86
+ imageData: null,
87
+ originalImageData: null,
88
+ hoverApartmentIndex: -1,
89
+ showApartmentCard: !1,
90
+ cursorX: null,
91
+ cursorY: null,
92
+ rasterImages: {},
93
+ vueCanvasCursor: "auto",
94
+ timeout: null,
95
+ windowListener: void 0,
96
+ resourceLoader: new H(),
97
+ apartmentIndexRasterMap: {}
57
98
  };
58
99
  },
59
100
  computed: {
60
- currentValueString() {
61
- const e = Math.floor(this.currentValue / 2).toString().padStart(2, "0"), t = this.currentValue % 2 === 0 ? "00" : "30";
62
- return `${e}:${t}`;
101
+ isHoverable() {
102
+ return this.$refs.hoverProbe.isHoverEnabled;
63
103
  },
64
- dates() {
65
- return this.dateSelector.dates.map(X);
104
+ rasterUrl() {
105
+ return this.cdnFileResolver(
106
+ `/scenedata${this.viewModel.currentScene}.png`
107
+ );
66
108
  },
67
- selectedDate: {
68
- get() {
69
- return X(this.dateSelector.selectedDate);
70
- },
71
- set(e) {
72
- this.dateSelector.selectIndex(this.dates.indexOf(e));
73
- }
109
+ rasterImage() {
110
+ return this.rasterUrl in this.rasterImages ? this.rasterImages[this.rasterUrl] : null;
111
+ },
112
+ hoverApartment() {
113
+ if (this.hoverApartmentIndex < 0)
114
+ return !1;
115
+ const e = this.sceneData.find(
116
+ (t) => t.index === this.hoverApartmentIndex
117
+ );
118
+ return e ? this.unitCallback ? this.unitCallback(e.apartmentId) : e.apartmentId : !1;
119
+ },
120
+ canvasStyle() {
121
+ return {
122
+ width: this.canvasWidth + "px",
123
+ height: this.canvasHeight + "px",
124
+ cursor: this.vueCanvasCursor
125
+ };
126
+ },
127
+ hoverBehaviourIdentifier() {
128
+ return `hover-${this.showApartmentCard ? "over" : "out"}-${this.hoverApartment ? typeof this.hoverApartment == "object" && "unitId" in this.hoverApartment ? this.hoverApartment.unitId : this.hoverApartment : ""}`;
74
129
  }
75
130
  },
76
131
  watch: {
77
- currentValue(e) {
78
- this.$emit("update:modelValue", e);
132
+ rasterUrl: {
133
+ handler() {
134
+ this.rasterImages[this.rasterUrl] || this.resourceLoader.loadImageData(this.rasterUrl).then((e) => {
135
+ this.rasterImages = {
136
+ ...this.rasterImages,
137
+ [this.rasterUrl]: e
138
+ };
139
+ });
140
+ },
141
+ immediate: !0
79
142
  },
80
- modelValue(e) {
81
- this.currentValue = Math.floor(e);
143
+ rasterImage() {
144
+ this.rasterImage && this.init();
82
145
  },
83
- dates: {
84
- handler(e) {
85
- this.currentDate = X(this.dateSelector.selectedDate);
146
+ "viewModel.currentScene": {
147
+ handler() {
148
+ this.draw();
86
149
  },
87
150
  immediate: !0
88
151
  },
89
- currentDate(e) {
90
- this.dateSelector.selectIndex(this.dates.indexOf(e));
152
+ "viewModel.isRotating"() {
153
+ this.draw();
154
+ },
155
+ drawObserver() {
156
+ this.draw();
157
+ },
158
+ selectedUnitId() {
159
+ this.draw();
160
+ },
161
+ hoverApartment() {
162
+ this.draw(), this.hoverApartment ? this.vueCanvasCursor = "pointer" : this.vueCanvasCursor = "auto";
163
+ },
164
+ hoverBehaviourIdentifier() {
165
+ this.$emit(this.showApartmentCard ? "hover-over" : "hover-out", {
166
+ hoverApartment: this.hoverApartment,
167
+ closeHandler: () => this.closeDialog()
168
+ });
169
+ },
170
+ pos() {
171
+ this.$emit("pos", this.pos);
91
172
  }
92
173
  },
93
- methods: {}
94
- }), Re = { class: "sunsim-bar-wrapper" }, Te = { class: "sunsim-date d-flex align-center pl-5 pr-5" }, Ve = {
95
- key: 1,
96
- class: "text-center text-body-1"
97
- }, He = { class: "sunsim-wrapper d-flex align-center px-3" }, Ne = { class: "sunsim-time-label text-body-1 font-weight-normal ml-2" };
98
- function je(e, t, i, r, n, s) {
99
- const a = c("v-icon"), d = c("v-select"), p = c("v-progress-linear"), v = c("v-slider");
100
- return l(), m("div", Re, [
101
- o("div", Te, [
102
- u(a, {
103
- color: "black",
104
- class: "mr-2",
105
- icon: "mdi-calendar-blank-outline"
106
- }),
107
- e.dateSelector.hasMultipleDates ? (l(), y(d, {
108
- key: 0,
109
- modelValue: e.currentDate,
110
- "onUpdate:modelValue": t[0] || (t[0] = (w) => e.currentDate = w),
111
- items: e.dates,
112
- density: "compact",
113
- variant: "underlined",
114
- "hide-details": "",
115
- class: "day-selector"
116
- }, null, 8, ["modelValue", "items"])) : (l(), m("span", Ve, _(e.selectedDate), 1))
117
- ]),
118
- o("div", He, [
119
- o("span", Ne, _(e.currentValueString), 1),
120
- u(a, {
121
- medium: "",
122
- class: "ml-2 mr-2 icon"
123
- }, {
124
- default: h(() => [
125
- L("mdi-white-balance-sunny")
126
- ]),
127
- _: 1
128
- }),
129
- e.isLoading ? (l(), y(p, {
130
- key: 0,
131
- indeterminate: "",
132
- rounded: "",
133
- height: "6",
134
- color: "grey lighten-1",
135
- class: "mr-2"
136
- })) : (l(), y(v, {
137
- key: 1,
138
- modelValue: e.currentValue,
139
- "onUpdate:modelValue": t[1] || (t[1] = (w) => e.currentValue = w),
140
- min: 0,
141
- max: 47,
142
- step: 1,
143
- "thumb-label": !1,
144
- "hide-details": !0,
145
- "thumb-color": "white",
146
- "thumb-size": "25",
147
- "track-size": "7",
148
- "track-fill-color": "transparent",
149
- class: "sunsim-slider mr-1"
150
- }, null, 8, ["modelValue"]))
151
- ])
152
- ]);
153
- }
154
- const Ce = /* @__PURE__ */ C(Ue, [["render", je], ["__scopeId", "data-v-1fba3edd"]]);
155
- class K {
156
- constructor(t) {
157
- this._numParts = t, this._loadedCount = 0, this._isError = !1, this._finishedAction = () => {
158
- }, this._errorAction = () => {
159
- }, this._loadProgressAction = () => {
160
- };
161
- }
162
- onLoadFinished(t) {
163
- return this._finishedAction = t, this;
164
- }
165
- onLoadError(t) {
166
- return this._errorAction = t, this;
167
- }
168
- onLoadProgress(t) {
169
- return this._loadProgressAction = t, this;
170
- }
171
- partLoaded() {
172
- this.isFinished || (this._loadedCount++, this._loadProgressAction(this.percentLoaded), this.isFinished && this._finishedAction());
173
- }
174
- errorDetected() {
175
- this._isError || (this._isError = !0, this._errorAction());
176
- }
177
- get isFinished() {
178
- return this._loadedCount >= this._numParts;
179
- }
180
- get isError() {
181
- return this._isError;
182
- }
183
- get percentLoaded() {
184
- return Math.round(this._loadedCount * 100 / this._numParts);
174
+ mounted() {
175
+ this.windowListener = () => {
176
+ clearTimeout(this.timeout), this.updateCanvasSize(), this.timeout = setTimeout(() => {
177
+ this.updateCanvasSize();
178
+ }, 50);
179
+ }, window.addEventListener("resize", this.windowListener), this.updateCanvasSize();
180
+ },
181
+ beforeUnmount() {
182
+ window.removeEventListener("resize", this.windowListener);
183
+ for (const e in this.rasterImages)
184
+ URL.revokeObjectURL(this.rasterImages[e]);
185
+ },
186
+ methods: {
187
+ init() {
188
+ this.canvas = this.$refs.canvasMask, this.context = this.canvas.getContext("2d", { willReadFrequently: !0 }), this.image = new Image(), this.image.onload = () => {
189
+ this.setupDraw(), this.canvas.addEventListener(
190
+ "mousemove",
191
+ this.throttle(this.handleMouseMove, 50)
192
+ );
193
+ }, this.image.src = this.rasterImage;
194
+ },
195
+ handleMouseMove(e) {
196
+ const t = this.getApartmentIndexByCursorPosition(
197
+ e.offsetX,
198
+ e.offsetY
199
+ );
200
+ this.showApartmentCard = t >= 0, this.hoverApartmentIndex = t, this.pos = {
201
+ x: e.offsetX,
202
+ y: e.offsetY,
203
+ width: this.canvasWidth,
204
+ height: this.canvasHeight
205
+ };
206
+ },
207
+ clickCanvas(e) {
208
+ const t = this.getApartmentIndexByCursorPosition(
209
+ e.offsetX,
210
+ e.offsetY
211
+ );
212
+ t < 0 || this.isHoverable && this.goToApartmentByIndex(t);
213
+ },
214
+ setImageData() {
215
+ if (this.image && this.image.width) {
216
+ this.canvas.width = this.image.width, this.canvas.height = this.image.height, this.context.drawImage(
217
+ this.image,
218
+ 0,
219
+ 0,
220
+ this.image.width,
221
+ this.image.height
222
+ ), this.originalImageData = this.context.getImageData(
223
+ 0,
224
+ 0,
225
+ this.canvas.width,
226
+ this.canvas.height
227
+ ), this.imageData = this.context.getImageData(
228
+ 0,
229
+ 0,
230
+ this.canvas.width,
231
+ this.canvas.height
232
+ );
233
+ const e = this.originalImageData.data;
234
+ this.apartmentIndexRasterMap = {};
235
+ for (let t = 0; t < e.length; t += 4)
236
+ this.apartmentIndexRasterMap[e[t]] = [];
237
+ for (let t = 3; t < e.length; t += 4)
238
+ e[t] === 255 && e[t - 3] in this.apartmentIndexRasterMap && this.apartmentIndexRasterMap[e[t - 3]].push(t - 3);
239
+ }
240
+ },
241
+ getApartmentIndexByCursorPosition(e, t) {
242
+ this.cursorX = e, this.cursorY = t;
243
+ const i = this.canvas.offsetWidth / this.canvas.width, r = this.canvas.offsetHeight / this.canvas.height, n = (e / i).toFixed(), a = (t / r).toFixed() * (this.canvas.width * 4) + n * 4, d = this.originalImageData.data[a];
244
+ return this.originalImageData.data[a + 3] > 0 ? d : -1;
245
+ },
246
+ getApartmentIndexById(e) {
247
+ const t = this.sceneData.find((i) => i.apartmentId === e);
248
+ return t ? t.index : -1;
249
+ },
250
+ highlightApartments() {
251
+ this.getApartmentsInRaster().forEach((t) => {
252
+ if (t.index >= 0) {
253
+ const i = this.getApartmentPixelsByIndex(t.index), r = this.getApartmentIdByIndex(t.index);
254
+ let n = "idle";
255
+ !this.hoverApartment && this.selectedUnitId && r === this.selectedUnitId ? n = "selected" : this.hoverApartment && this.hoverApartmentIndex === t.index && (n = "hover");
256
+ const s = this.unitCallback ? this.unitCallback(r) : r;
257
+ if (s) {
258
+ const a = this.colorCallback(s, n);
259
+ if (a)
260
+ for (let d = 0; d < i.length; d++)
261
+ this.imageData.data[i[d]] = a.r, this.imageData.data[i[d] + 1] = a.g, this.imageData.data[i[d] + 2] = a.b, this.imageData.data[i[d] + 3] = a.a;
262
+ }
263
+ }
264
+ });
265
+ },
266
+ // GETTING APARTMENT DATA
267
+ // Returns the index of each RGBA value of a given apartment
268
+ getApartmentPixelsByIndex(e) {
269
+ return this.originalImageData ? this.apartmentIndexRasterMap[e] : !1;
270
+ },
271
+ getApartmentIdByIndex(e) {
272
+ const t = this.sceneData.find((i) => i.index === e);
273
+ return t && t.apartmentId;
274
+ },
275
+ getApartmentsInRaster() {
276
+ if (this.originalImageData) {
277
+ const e = Object.keys(this.apartmentIndexRasterMap).map(
278
+ (i) => parseInt(i)
279
+ );
280
+ return this.sceneData.filter(
281
+ (i) => e.includes(i.index)
282
+ );
283
+ } else
284
+ return [];
285
+ },
286
+ goToApartmentByIndex(e) {
287
+ const t = this.getApartmentIdByIndex(e);
288
+ this.goToApartmentById(t);
289
+ },
290
+ goToApartmentById(e) {
291
+ const t = this.unitCallback ? this.unitCallback(e) : e;
292
+ this.$emit("select-unit", t), t && this.canGoToUnitCallback(t) && this.$emit("go-to-unit", t);
293
+ },
294
+ setAlpha(e = 0) {
295
+ if (!this.imageData)
296
+ return;
297
+ const t = this.imageData.data;
298
+ for (let i = 3; i < t.length; i += 4)
299
+ t[i] = e;
300
+ },
301
+ updateCanvasSize() {
302
+ if (!this.$el)
303
+ return !1;
304
+ this.canvasWidth = this.$el.offsetWidth, this.canvasHeight = this.$el.offsetHeight;
305
+ },
306
+ setupDraw() {
307
+ this.setImageData(), this.draw();
308
+ },
309
+ draw() {
310
+ this.setAlpha(), this.highlightApartments(), this.context && this.imageData && this.context.putImageData(this.imageData, 0, 0);
311
+ },
312
+ closeDialog() {
313
+ this.showApartmentCard = !1;
314
+ }
185
315
  }
316
+ }, He = { id: "canvas" };
317
+ function Ne(e, t, i, r, n, s) {
318
+ const a = c("qi-hover-probe");
319
+ return l(), m("div", He, [
320
+ x(o("canvas", {
321
+ id: "canvas-mask",
322
+ ref: "canvasMask",
323
+ style: M(s.canvasStyle),
324
+ onClick: t[0] || (t[0] = (...d) => s.clickCanvas && s.clickCanvas(...d))
325
+ }, null, 4), [
326
+ [B, !i.viewModel.isRotating]
327
+ ]),
328
+ u(a, { ref: "hoverProbe" }, null, 512)
329
+ ]);
186
330
  }
187
- const qe = W({
188
- setup() {
189
- },
190
- name: "QiBuildingChooserSceneImageStack",
331
+ const ie = /* @__PURE__ */ C(Ve, [["render", Ne], ["__scopeId", "data-v-3bbbc77b"]]), je = {
332
+ name: "QiApartmentChooserSvg",
333
+ components: { QiHoverProbe: N },
334
+ mixins: [Ie],
191
335
  props: {
192
- imageUrls: { type: Array, required: !0 },
193
- activeIndex: { type: Number, required: !0 }
336
+ cdnFileResolver: { type: Function, required: !0 },
337
+ viewModel: { type: Object, required: !0 },
338
+ selectedUnitId: { type: String, default: null },
339
+ unitCallback: { type: Function, default: (e) => e },
340
+ canGoToUnitCallback: { type: Function, default: () => !0 },
341
+ sceneData: { type: Array, default: [] },
342
+ colorCallback: {
343
+ type: Function,
344
+ default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
345
+ },
346
+ drawObserver: {
347
+ type: [Object, Array, String, Number, Boolean],
348
+ default: null
349
+ }
194
350
  },
195
- emits: ["resize", "ready", "preloaded", "reset"],
351
+ emits: ["select-unit", "go-to-unit", "hover-over", "hover-out"],
196
352
  data() {
197
353
  return {
198
- state: "init",
199
- activeStates: ["preloaded", "loaded"],
200
- loadTracker: new K(0)
354
+ pos: { x: 0, y: 0, width: 0, height: 0 },
355
+ hoverApartmentIndex: -1,
356
+ svgImages: {},
357
+ currentSvgImage: null,
358
+ resourceLoader: new H()
201
359
  };
202
360
  },
361
+ computed: {
362
+ isHoverable() {
363
+ return this.$refs.hoverProbe.isHoverEnabled;
364
+ }
365
+ },
203
366
  watch: {
204
- imageUrls(e) {
205
- this.$emit("reset"), this.loadImages(e);
367
+ "viewModel.currentScene": {
368
+ handler() {
369
+ this.viewModel.currentScene in this.svgImages && (this.currentSvgImage = this.svgImages[this.viewModel.currentScene]);
370
+ },
371
+ immediate: !0
372
+ },
373
+ svgImages: {
374
+ handler() {
375
+ this.viewModel.currentScene in this.svgImages && (this.currentSvgImage = this.svgImages[this.viewModel.currentScene]);
376
+ },
377
+ immediate: !0
378
+ },
379
+ pos() {
380
+ this.$emit("pos", this.pos);
381
+ },
382
+ hoverApartmentIndex(e, t) {
383
+ if (e >= 0) {
384
+ const i = this.getApartmentByIndex(e);
385
+ this.$emit("hover-over", {
386
+ hoverApartment: i,
387
+ closeHandler: () => {
388
+ this.hoverApartmentIndex = -1;
389
+ }
390
+ });
391
+ } else {
392
+ const i = this.getApartmentByIndex(t);
393
+ this.$emit("hover-out", {
394
+ hoverApartment: i,
395
+ closeHandler: () => {
396
+ this.hoverApartmentIndex = -1;
397
+ }
398
+ });
399
+ }
206
400
  }
207
401
  },
208
402
  mounted() {
209
- this.loadImages(this.imageUrls), new ResizeObserver((e) => {
210
- window.requestAnimationFrame(() => {
211
- const t = e[0].contentRect.width, i = e[0].contentRect.height;
212
- this.$emit("resize", { width: t, height: i });
403
+ for (let e = 1; e <= 4; e++) {
404
+ const t = this.cdnFileResolver(`/scenedata${e}.svg`), i = {};
405
+ this.resourceLoader.loadJson(t).then((r) => {
406
+ i.markup = r;
407
+ const s = new DOMParser().parseFromString(r, "image/svg+xml").getElementsByTagName("svg")[0];
408
+ i.viewBox = s.getAttribute("viewBox"), i.svgObjects = Array.from(
409
+ s.querySelectorAll("*[data-index]")
410
+ ).map((a) => ({
411
+ index: parseInt(a.getAttribute("data-index")),
412
+ svg: a.innerHTML
413
+ })), this.svgImages = { ...this.svgImages, [e]: i };
213
414
  });
214
- }).observe(this.$refs.baseImage);
415
+ }
416
+ this.$refs.container.addEventListener(
417
+ "mousemove",
418
+ this.throttle(this.handleMouseMove, 50)
419
+ );
215
420
  },
216
421
  methods: {
217
- onPreloaded() {
218
- this.state = "preloaded", this.$emit("preloaded");
219
- },
220
- loadImages(e) {
221
- this.state = "init", this.$refs.baseImage.src = e[0], this.loadTracker = new K(e.length).onLoadFinished(
222
- () => {
223
- this.state = "loaded", this.$emit("ready");
224
- }
225
- );
422
+ handleMouseMove(e) {
423
+ this.pos = {
424
+ x: e.offsetX,
425
+ y: e.offsetY,
426
+ width: this.$el.offsetWidth,
427
+ height: this.$el.offsetHeight
428
+ };
429
+ },
430
+ getApartmentIdByIndex(e) {
431
+ var t;
432
+ return (t = this.sceneData.find((i) => i.index === parseInt(e))) == null ? void 0 : t.apartmentId;
433
+ },
434
+ getApartmentByIndex(e) {
435
+ const t = this.getApartmentIdByIndex(e);
436
+ return this.unitCallback ? this.unitCallback(t) : t;
437
+ },
438
+ mouseEnter(e) {
439
+ this.isHoverable && (this.hoverApartmentIndex = e);
440
+ },
441
+ mouseLeave() {
442
+ this.isHoverable && (this.hoverApartmentIndex = -1);
443
+ },
444
+ click(e) {
445
+ const t = this.getApartmentByIndex(e);
446
+ this.$emit("select-unit", t), this.isHoverable && t && this.canGoToUnitCallback(t) ? this.$emit("go-to-unit", t) : this.hoverApartmentIndex = e;
447
+ },
448
+ getGClass(e) {
449
+ const t = this.getApartmentIdByIndex(e), i = this.getApartmentByIndex(e);
450
+ let r = "idle";
451
+ this.hoverApartmentIndex < 0 && this.selectedUnitId && t === this.selectedUnitId ? r = "selected" : this.hoverApartmentIndex >= 0 && this.hoverApartmentIndex === e && (r = "hover");
452
+ const n = this.colorCallback(i, r);
453
+ if (n) {
454
+ const { r: s, g: a, b: d, a: p, s: v } = n;
455
+ return {
456
+ strokeWidth: v !== void 0 ? v : 2,
457
+ stroke: `rgb(${s}, ${a}, ${d})`,
458
+ strokeOpacity: 1,
459
+ fill: `rgb(${s}, ${a}, ${d})`,
460
+ fillOpacity: p / 255,
461
+ cursor: `${this.canGoToUnitCallback(i) ? "cursor" : "default"} !important`
462
+ };
463
+ } else
464
+ return {
465
+ strokeWidth: 0,
466
+ stroke: "white",
467
+ strokeOpacity: 0,
468
+ fill: "white",
469
+ fillOpacity: 0,
470
+ cursor: "default !important"
471
+ };
226
472
  }
227
473
  }
228
- }), Pe = { key: 0 }, Ye = ["src"];
474
+ }, qe = {
475
+ id: "container",
476
+ ref: "container"
477
+ }, Pe = ["viewBox"], Ye = ["innerHTML", "onMouseenter", "onMouseleave", "onClick"];
229
478
  function Qe(e, t, i, r, n, s) {
230
- return l(), m("div", null, [
231
- o("img", {
232
- ref: "baseImage",
233
- class: "image-instance zero",
234
- style: { opacity: 1, borderRadius: 50 },
235
- onLoad: t[0] || (t[0] = (...a) => e.onPreloaded && e.onPreloaded(...a))
236
- }, null, 544),
237
- e.state === "preloaded" || e.state === "loaded" ? x((l(), m("div", Pe, [
238
- (l(!0), m(U, null, D(e.imageUrls, (a, d) => (l(), m("img", {
239
- key: d,
240
- class: E({ "image-instance": !0, active: d === e.activeIndex }),
241
- src: a,
242
- onLoad: t[1] || (t[1] = (p) => e.loadTracker.partLoaded())
243
- }, null, 42, Ye))), 128)),
244
- L(" Here ")
245
- ], 512)), [
246
- [B, e.state === "loaded"]
247
- ]) : f("", !0)
248
- ]);
249
- }
250
- const _e = /* @__PURE__ */ C(qe, [["render", Qe], ["__scopeId", "data-v-fad48118"]]), ze = {
251
- name: "FloatingCard",
252
- props: {
253
- pos: { type: Object, required: !0 },
254
- isHoverable: Boolean
255
- },
256
- computed: {
257
- q() {
258
- const e = this.pos.x <= this.pos.width / 2 ? "left" : "right";
259
- return `${this.pos.y <= this.pos.height / 2 ? "top" : "bottom"}-${e}`;
260
- }
261
- }
262
- };
263
- function $e(e, t, i, r, n, s) {
264
- const a = c("v-dialog"), d = c("v-fade-transition");
265
- return l(), y(d, {
266
- origin: s.q.replace("-", " ") + " " + i.pos.x + " " + i.pos.y
267
- }, {
268
- default: h(() => [
269
- i.isHoverable ? (l(), m("div", {
479
+ const a = c("qi-hover-probe");
480
+ return l(), m("div", qe, [
481
+ x(o("div", {
482
+ class: "svg-container",
483
+ style: M({
484
+ opacity: !n.currentSvgImage || !n.currentSvgImage.svgObjects ? 0 : 1
485
+ })
486
+ }, [
487
+ n.currentSvgImage && n.currentSvgImage.svgObjects ? (l(), m("svg", {
270
488
  key: 0,
271
- class: E(["floating-card", s.q]),
272
- style: M({ left: `${i.pos.x}px`, top: `${i.pos.y}px`, pointerEvents: "none" })
489
+ viewBox: n.currentSvgImage.viewBox
273
490
  }, [
274
- A(e.$slots, "default", { isHoverable: i.isHoverable }, void 0, !0)
275
- ], 6)) : (l(), y(a, {
276
- key: 1,
277
- value: !0,
278
- width: "auto",
279
- "onClick:outside": t[0] || (t[0] = (p) => e.$emit("outside", p))
280
- }, {
281
- default: h(() => [
282
- A(e.$slots, "default", { isHoverable: i.isHoverable }, void 0, !0)
283
- ]),
284
- _: 3
285
- }))
491
+ (l(!0), m(R, null, D(n.currentSvgImage.svgObjects, ({ index: d, svg: p }) => (l(), m("g", {
492
+ key: d,
493
+ innerHTML: p,
494
+ style: M(s.getGClass(d)),
495
+ onMouseenter: (v) => s.mouseEnter(d),
496
+ onMouseleave: (v) => s.mouseLeave(d),
497
+ onClick: (v) => s.click(d)
498
+ }, null, 44, Ye))), 128))
499
+ ], 8, Pe)) : f("", !0)
500
+ ], 4), [
501
+ [B, !i.viewModel.isRotating]
286
502
  ]),
287
- _: 3
288
- }, 8, ["origin"]);
289
- }
290
- const ne = /* @__PURE__ */ C(ze, [["render", $e], ["__scopeId", "data-v-b74de171"]]), We = {
291
- name: "QiHoverProbe",
292
- computed: {
293
- isHoverEnabled() {
294
- return window.getComputedStyle(this.$refs.hoverCheck).display === "none";
295
- }
296
- }
297
- }, Je = {
298
- ref: "hoverCheck",
299
- class: "hover-check"
300
- };
301
- function Ge(e, t, i, r, n, s) {
302
- return l(), m("div", Je, null, 512);
503
+ u(a, { ref: "hoverProbe" }, null, 512)
504
+ ], 512);
303
505
  }
304
- const Q = /* @__PURE__ */ C(We, [["render", Ge], ["__scopeId", "data-v-e4729353"]]), Xe = {
305
- name: "QiZoomBox",
506
+ const ne = /* @__PURE__ */ C(je, [["render", Qe], ["__scopeId", "data-v-82a61864"]]), ze = {
507
+ name: "QiApartmentChooserNavigation",
508
+ inject: ["i18n"],
306
509
  props: {
307
- desktop: {
308
- type: Boolean,
309
- default: !0
310
- },
311
- mobile: {
312
- type: Boolean,
313
- default: !0
314
- },
315
- maxScale: {
316
- type: Number,
317
- default: 10
318
- },
319
- consumeMouseClickWhenMoved: {
320
- type: Boolean,
321
- default: !0
322
- },
323
- consumeMouseUpWhenMoved: {
324
- type: Boolean,
325
- default: !0
326
- }
327
- },
328
- data() {
329
- return {
330
- zoom: 100,
331
- originX: 0,
332
- originY: 0,
333
- moving: !1,
334
- scaling: !1,
335
- lastEvent: void 0,
336
- moved: !1
337
- };
338
- },
339
- computed: {
340
- transform() {
341
- return `translateX(${this.originX}px) translateY(${this.originY}px) scale(${this.scale})`;
342
- },
343
- scale() {
344
- return this.zoom / 100;
345
- },
346
- actualMaxScale() {
347
- return this.maxScale * 100;
348
- }
349
- },
350
- watch: {
351
- scale() {
352
- this.emitUpdate();
353
- },
354
- originX() {
355
- this.emitUpdate();
356
- },
357
- originY() {
358
- this.emitUpdate();
359
- },
360
- desktop() {
361
- this.desktop ? this.addDesktopHandlers() : this.removeDesktopHandlers();
362
- },
363
- mobile() {
364
- this.mobile ? this.addMobileHandlers() : this.removeMobileHandlers();
365
- }
510
+ canGoToUnitCallback: { type: Function, default: () => !0 },
511
+ selectedUnit: { type: Object, default: null },
512
+ prevUnit: { type: Object, default: null },
513
+ nextUnit: { type: Object, default: null },
514
+ viewModel: { type: Object, required: !0 }
366
515
  },
367
516
  mounted() {
368
- this.desktop && this.addDesktopHandlers(), this.mobile && this.addMobileHandlers();
517
+ window.addEventListener("keydown", this.keyNavigate);
369
518
  },
370
519
  beforeUnmount() {
371
- this.desktop && this.removeDesktopHandlers(), this.mobile && this.removeMobileHandlers();
520
+ window.removeEventListener("keydown", this.keyNavigate);
372
521
  },
373
522
  methods: {
374
- addDesktopHandlers() {
375
- this.$refs.box.addEventListener("wheel", this.wheelHandler, {
376
- capture: !0
377
- }), this.$refs.box.addEventListener("mousedown", this.mouseDownHandler, {
378
- capture: !0
379
- }), this.$refs.box.addEventListener("mousemove", this.mouseMoveHandler, {
380
- capture: !0
381
- }), window.addEventListener("mouseup", this.mouseUpHandler, {
382
- capture: !0
383
- }), window.addEventListener("click", this.mouseClickHandler, {
384
- capture: !0
385
- });
386
- },
387
- addMobileHandlers() {
388
- this.$refs.box.addEventListener("touchstart", this.touchStartHandler, {
389
- capture: !0
390
- }), this.$refs.box.addEventListener("touchmove", this.touchMoveHandler, {
391
- capture: !0
392
- }), window.addEventListener("touchend", this.touchEndHandler, {
393
- capture: !0
394
- }), window.addEventListener("touchcancel", this.touchEndHandler, {
395
- capture: !0
396
- });
397
- },
398
- removeDesktopHandlers() {
399
- this.$refs.box.removeEventListener("wheel", this.wheelHandler, {
400
- capture: !0
401
- }), this.$refs.box.removeEventListener("mousedown", this.mouseDownHandler, {
402
- capture: !0
403
- }), this.$refs.box.removeEventListener("mousemove", this.mouseMoveHandler, {
404
- capture: !0
405
- }), window.removeEventListener("mouseup", this.mouseUpHandler, {
406
- capture: !0
407
- }), window.removeEventListener("click", this.mouseClickHandler, {
408
- capture: !0
409
- });
410
- },
411
- removeMobileHandlers() {
412
- this.$refs.box.removeEventListener("touchstart", this.touchStartHandler, {
413
- capture: !0
414
- }), this.$refs.box.removeEventListener("touchmove", this.touchMoveHandler, {
415
- capture: !0
416
- }), window.removeEventListener("touchend", this.touchEndHandler, {
417
- capture: !0
418
- }), window.removeEventListener("touchcancel", this.touchEndHandler, {
419
- capture: !0
420
- });
421
- },
422
- wheelHandler(e) {
423
- const { x: t, y: i } = this.getOffsetCoordinates(e);
424
- this.adjustZoom(-e.deltaY / 10, t, i), e.preventDefault();
425
- },
426
- mouseDownHandler(e) {
427
- this.moving = !0, this.moved = !1, this.lastEvent = e;
428
- },
429
- mouseMoveHandler(e) {
430
- if (this.moving) {
431
- const { x: t, y: i } = this.getOffsetCoordinates(e), { x: r, y: n } = this.getOffsetCoordinates(this.lastEvent), s = {
432
- x: t - r,
433
- y: i - n
434
- };
435
- this.adjustTranslateX(s.x), this.adjustTranslateY(s.y), this.moved = !0, this.lastEvent = e;
436
- }
437
- },
438
- mouseUpHandler(e) {
439
- this.moving && this.moved && this.consumeMouseUpWhenMoved && (e.preventDefault(), e.stopImmediatePropagation());
440
- },
441
- mouseClickHandler(e) {
442
- this.moving && (this.moved && this.consumeMouseClickWhenMoved && (e.preventDefault(), e.stopImmediatePropagation()), this.moving = !1);
443
- },
444
- touchStartHandler(e) {
445
- this.moving = e.touches.length === 1, this.scaling = e.touches.length === 2, this.lastEvent = e;
446
- },
447
- touchMoveHandler(e) {
448
- if (this.moving) {
449
- const { x: t, y: i } = this.getOffsetCoordinates(e.touches[0]), { x: r, y: n } = this.getOffsetCoordinates(
450
- this.lastEvent.touches[0]
451
- ), s = {
452
- x: t - r,
453
- y: i - n
454
- };
455
- this.adjustTranslateX(s.x), this.adjustTranslateY(s.y);
456
- } else if (this.scaling && e.touches.length === 2) {
457
- const { x: t, y: i } = this.getOffsetCoordinates(e.touches[0]), { x: r, y: n } = this.getOffsetCoordinates(
458
- this.lastEvent.touches[0]
459
- ), { x: s, y: a } = this.getOffsetCoordinates(e.touches[1]), { x: d, y: p } = this.getOffsetCoordinates(
460
- this.lastEvent.touches[1]
461
- ), v = Math.hypot(r - d, n - p), w = Math.hypot(t - s, i - a), S = (s + t) / 2, g = (a + i) / 2;
462
- this.adjustZoom(w - v, S, g);
463
- }
464
- this.lastEvent = e;
465
- },
466
- touchEndHandler() {
467
- this.moving = !1, this.scaling = !1;
468
- },
469
- getOffsetCoordinates(e) {
470
- const { left: t, top: i } = this.$refs.box.getBoundingClientRect();
471
- return {
472
- x: e.clientX - t,
473
- y: e.clientY - i
474
- };
475
- },
476
- adjustTranslateX(e) {
477
- const t = this.$refs.box.clientWidth, i = t * this.scale;
478
- this.originX = Math.max(
479
- Math.min(0, this.originX + e),
480
- -(i - t)
481
- );
482
- },
483
- adjustTranslateY(e) {
484
- const t = this.$refs.box.clientHeight, i = t * this.scale;
485
- this.originY = Math.max(
486
- Math.min(0, this.originY + e),
487
- -(i - t)
488
- );
489
- },
490
- adjustZoom(e, t, i) {
491
- const r = this.$refs.box.clientWidth, n = this.$refs.box.clientHeight, s = r * this.scale, a = n * this.scale;
492
- this.zoom = Math.min(
493
- Math.max(100, this.zoom + e),
494
- this.actualMaxScale
495
- );
496
- const d = r * this.scale, p = n * this.scale, v = d - s, w = p - a;
497
- this.originX -= t / r * v, this.originY -= i / n * w, this.adjustTranslateX(0), this.adjustTranslateY(0);
498
- },
499
- emitUpdate() {
500
- this.$emit("update", {
501
- scale: this.scale,
502
- x: this.originX,
503
- y: this.originY,
504
- resolve: (e, t) => {
505
- const i = this.$refs.box.clientWidth, r = this.$refs.box.clientHeight, n = this.originX / -this.scale, s = this.originY / -this.scale, a = n + i / this.scale, d = s + r / this.scale, p = e / i * (a - n) + n, v = t / r * (d - s) + s;
506
- return { x: p, y: v };
507
- }
508
- });
523
+ keyNavigate(e) {
524
+ e.keyCode === 37 ? this.prevUnit && this.$emit("prev-unit") : e.keyCode === 39 && this.nextUnit && this.$emit("next-unit");
509
525
  }
510
526
  }
511
- }, Ze = {
512
- ref: "box",
513
- class: "zoom-box-container"
527
+ }, $e = {
528
+ key: 0,
529
+ class: "d-none d-md-flex"
514
530
  };
515
- function Ke(e, t, i, r, n, s) {
516
- return l(), m("div", Ze, [
517
- o("div", {
518
- style: M({ "transform-origin": "top left", transform: s.transform }),
519
- class: "zoom-box"
520
- }, [
521
- A(e.$slots, "default", {}, void 0, !0)
522
- ], 4)
523
- ], 512);
531
+ function We(e, t, i, r, n, s) {
532
+ const a = c("v-btn");
533
+ return l(), m("div", null, [
534
+ u(a, {
535
+ elevation: "1",
536
+ icon: "mdi-rotate-right",
537
+ class: "black darken-1",
538
+ onClick: t[0] || (t[0] = (d) => i.viewModel.rotateClockwise())
539
+ }),
540
+ u(a, {
541
+ elevation: "1",
542
+ plain: "",
543
+ icon: "mdi-chevron-left",
544
+ class: "mr-sm-4 ml-sm-8 mr-3 ml-3 black darken-1",
545
+ disabled: !i.prevUnit,
546
+ onClick: t[1] || (t[1] = (d) => e.$emit("prev-unit"))
547
+ }, null, 8, ["disabled"]),
548
+ u(a, {
549
+ color: "success darken-2",
550
+ elevation: "1",
551
+ rounded: "",
552
+ plain: "",
553
+ disabled: !i.selectedUnit || !i.canGoToUnitCallback(i.selectedUnit),
554
+ onClick: t[2] || (t[2] = (d) => e.$emit("go-to-unit", i.selectedUnit))
555
+ }, {
556
+ default: h(() => [
557
+ i.selectedUnit && i.canGoToUnitCallback(i.selectedUnit) ? (l(), m("span", $e, _(s.i18n.getLabel("see-apartment")) + "  ", 1)) : f("", !0),
558
+ o("span", null, _(i.selectedUnit && "title" in i.selectedUnit ? i.selectedUnit.title : "-"), 1)
559
+ ]),
560
+ _: 1
561
+ }, 8, ["disabled"]),
562
+ u(a, {
563
+ elevation: "1",
564
+ plain: "",
565
+ icon: "mdi-chevron-right",
566
+ class: "mr-sm-8 ml-sm-4 mr-3 ml-3 black darken-1",
567
+ disabled: !i.nextUnit,
568
+ onClick: t[3] || (t[3] = (d) => e.$emit("next-unit"))
569
+ }, null, 8, ["disabled"]),
570
+ u(a, {
571
+ elevation: "1",
572
+ plain: "",
573
+ icon: "mdi-rotate-left",
574
+ class: "black darken-1",
575
+ onClick: t[4] || (t[4] = (d) => i.viewModel.rotateCounterClockwise())
576
+ })
577
+ ]);
524
578
  }
525
- const se = /* @__PURE__ */ C(Xe, [["render", Ke], ["__scopeId", "data-v-83bfd28a"]]);
526
- class H {
527
- async loadJson(t) {
528
- return (await ke.get(t)).data;
529
- }
530
- async loadImage(t) {
531
- return new Promise((i, r) => {
532
- const n = new Image();
533
- n.crossOrigin = "anonymous", n.onload = () => {
534
- i(n);
535
- }, n.onerror = r, n.src = t;
536
- });
579
+ const Se = /* @__PURE__ */ C(ze, [["render", We], ["__scopeId", "data-v-129ef905"]]);
580
+ class se {
581
+ constructor(t) {
582
+ this._numParts = t, this._loadedCount = 0, this._isError = !1, this._finishedAction = () => {
583
+ }, this._errorAction = () => {
584
+ }, this._loadProgressAction = () => {
585
+ };
537
586
  }
538
- async loadImageData(t) {
539
- const i = await this.loadImage(t), r = document.createElement("canvas");
540
- try {
541
- const n = r.getContext("2d");
542
- return r.width = i.width, r.height = i.height, n.drawImage(i, 0, 0), r.toDataURL("image/png");
543
- } finally {
544
- r.remove();
545
- }
587
+ onLoadFinished(t) {
588
+ return this._finishedAction = t, this;
546
589
  }
547
- }
548
- const et = "buildingChooser.json", tt = 180;
549
- class Ie {
550
- constructor(t) {
551
- this._cdnFileResolver = t, this._resourceLoader = new H();
590
+ onLoadError(t) {
591
+ return this._errorAction = t, this;
552
592
  }
553
- constructFileUrl(t) {
554
- return this._cdnFileResolver ? this._cdnFileResolver(`/${t}`) : null;
593
+ onLoadProgress(t) {
594
+ return this._loadProgressAction = t, this;
555
595
  }
556
- loadConfigFile() {
557
- const t = this.constructFileUrl(et);
558
- return t ? this._resourceLoader.loadJson(t) : null;
596
+ partLoaded() {
597
+ this.isFinished || (this._loadedCount++, this._loadProgressAction(this.percentLoaded), this.isFinished && this._finishedAction());
559
598
  }
560
- loadBuildingMapImage(t) {
561
- const i = this.constructFileUrl(t.lookupFilename);
562
- return i ? this._resourceLoader.loadImage(i) : null;
599
+ errorDetected() {
600
+ this._isError || (this._isError = !0, this._errorAction());
563
601
  }
564
- getViewLongitude(t) {
565
- return t.cameraRotation && t.cameraRotation.y + 270;
602
+ get isFinished() {
603
+ return this._loadedCount >= this._numParts;
566
604
  }
567
- getBuildingData(t) {
568
- const i = t ? t.buildings : [], r = i.map((s) => s.id), n = i.map((s) => ({
569
- id: s.id,
570
- url: this.constructFileUrl(s.overlayFilename)
571
- }));
572
- return { buildingIds: r, buildingOverlays: n };
605
+ get isError() {
606
+ return this._isError;
573
607
  }
574
- getBackgroundImageData(t) {
575
- return "days" in t ? this.processMultipleDays(t.days) : [this.processTimeSamples(
576
- tt,
577
- t.timeSamples
578
- )];
608
+ get percentLoaded() {
609
+ return Math.round(this._loadedCount * 100 / this._numParts);
579
610
  }
580
- processMultipleDays(t) {
581
- return t.map(
582
- (i) => this.processTimeSamples(i.dayOfYear, i.timeSamples)
583
- );
611
+ }
612
+ class de {
613
+ constructor(t, i, r, n) {
614
+ this._rotator = t, this._direction = i, this._frameIndex = r, this._sceneCount = n;
584
615
  }
585
- processTimeSamples(t, i) {
586
- return {
587
- urls: i.map(
588
- (n) => this.constructFileUrl(n.filename)
589
- ),
590
- referenceDate: this.makeReferenceDate(t)
591
- };
616
+ get atEnd() {
617
+ return this._sceneCount === 0;
592
618
  }
593
- makeReferenceDate(t) {
594
- const i = /* @__PURE__ */ new Date(0);
595
- return i.setUTCDate(t), i;
619
+ get frameIndex() {
620
+ return this._frameIndex;
596
621
  }
597
- async loadBuildingChooser() {
598
- try {
599
- const t = await this.loadConfigFile();
600
- if (t) {
601
- const i = await this.loadBuildingMapImage(t);
602
- if (i) {
603
- const r = this.getViewLongitude(t), { buildingIds: n, buildingOverlays: s } = this.getBuildingData(t), a = this.getBackgroundImageData(t);
604
- return {
605
- mapImage: i,
606
- viewLongitude: r,
607
- buildingIds: n,
608
- buildingOverlays: s,
609
- backgrounds: a
610
- };
611
- }
612
- }
613
- return null;
614
- } catch {
615
- return null;
616
- }
622
+ nextFrame() {
623
+ const t = this._rotator.clampFrameIndex(
624
+ this._frameIndex + this._direction
625
+ ), i = this._rotator.isCardinalFrame(t) ? this._sceneCount - 1 : this._sceneCount;
626
+ return new de(
627
+ this._rotator,
628
+ this._direction,
629
+ t,
630
+ i
631
+ );
617
632
  }
618
633
  }
619
- class P {
620
- static empty() {
621
- return new P([]);
634
+ class Je {
635
+ constructor(t, i) {
636
+ this._cardinalFrames = t, this._totalFrameCount = i;
622
637
  }
623
- constructor(t) {
624
- this._buildingIds = t;
625
- }
626
- getBuildingId(t, i, r) {
627
- const n = this._getBuildingIndex(t, i, r);
628
- if (n !== void 0)
629
- return this._buildingIds[n];
630
- }
631
- _getBuildingIndex(t, i, r) {
632
- const [n, s, a, d] = t.getPixel(i, r);
633
- if (d === 255 && n === s && s === a)
634
- return n;
635
- }
636
- }
637
- class Y {
638
- static empty() {
639
- return new Y(null);
640
- }
641
- constructor(t) {
642
- this._mapImage = t, this._context = null;
643
- }
644
- update(t) {
645
- this._mapImage && (this._context = t.getContext("2d", { willReadFrequently: !0 }), this._context.drawImage(this._mapImage, 0, 0, t.width, t.height));
646
- }
647
- getPixel(t, i) {
648
- try {
649
- return this._context ? this._context.getImageData(t, i, 1, 1).data : [0, 0, 0, 0];
650
- } catch {
651
- return [0, 0, 0, 0];
652
- }
653
- }
654
- }
655
- const it = /* @__PURE__ */ new Date(0);
656
- class J {
657
- static empty() {
658
- return new J([{ referenceDate: it, urls: [] }]);
659
- }
660
- constructor(t) {
661
- this._imagesByDay = t, this._state = { selectedIndex: 0 };
662
- }
663
- selectIndex(t) {
664
- t < this._imagesByDay.length && (this._state.selectedIndex = t);
665
- }
666
- get dates() {
667
- return this._imagesByDay.map((t) => t.referenceDate);
668
- }
669
- get hasMultipleDates() {
670
- return this._imagesByDay.length > 1;
671
- }
672
- get selectedIndex() {
673
- return this._state.selectedIndex;
674
- }
675
- get selectedDate() {
676
- return this._imagesByDay[this.selectedIndex].referenceDate;
677
- }
678
- get imageUrls() {
679
- return this._imagesByDay[this.selectedIndex].urls;
638
+ start(t, i, r) {
639
+ const n = this.startFrameIndexForScene(i);
640
+ return new de(this, t, n, r);
680
641
  }
681
- }
682
- const nt = {
683
- // virtual tour default labels
684
- interior: "Interiør",
685
- "see-a-selection-of-the-options-in-the-project": "Se et utvalg av tilvalgsmulighetene i prosjektet.",
686
- "floor-plan": "Planløsning",
687
- "all-illustrations-are-indicative-deviations-may-occur": { nb: "Alle illustrasjoner er veiledende. Avvik kan forekomme.", en: "All illustrations are indicative. Discrepancies may exist." },
688
- "read-more-here": "Les mer her",
689
- "i-understand": { nb: "Jeg forstår", en: "I understand" },
690
- share: "Share",
691
- "share-to-facebook": "Share to Facebook",
692
- "share-to-linkedin": "Share to Linkedin",
693
- "share-to-twitter": "Share to Twitter",
694
- "share-via-email": "Share via Email",
695
- "copy-link": "Copy link",
696
- "virtual-view": "Virtuell Visning",
697
- "slide-show": "Slide Show",
698
- // building chooser default labels
699
- room: "Room",
700
- floor: "Floor",
701
- "see-apartments": "See apartments",
702
- // apartment chooser default labels
703
- "see-apartment": "See apartment",
704
- "click-and-drag-to-look-around": { en: "Click and drag to look around", nb: "Klikk og dra for å se deg rundt" },
705
- "click-on-the-cricles-to-move-around": { en: "Click on the circles to move around", nb: "Klikk på sirkelene for å gå rundt" },
706
- "use-the-mouse-wheel-to-zoom": { en: "Use the mouse wheel to zoom", nb: "Bruk mushjulet for å zoome" },
707
- "you-can-also-use-the-arrow-keys-to-move-around": { en: "You can also use the arrow keys to move around", nb: "Du kan også bruke pilene på tastaturet for å gå rundt" },
708
- "tap-and-drag-to-look-around": { en: "Tap and drag to look around", nb: "Trykk og dra for å se deg rundt" },
709
- "tap-on-the-circles-to-move-around": { en: "Tap on the circles to move around", nb: "Trykk på sirkelene for å gå rundt" },
710
- "use-two-fingers-to-zoom": { en: "Use two fingers to zoom", nb: "Bruk to fingre for å zoome" },
711
- "dont-show-again": { en: "Don't Show Again", nb: "Ikke vis igjen" }
712
- };
713
- class R {
714
- constructor(t, i) {
715
- this._labels = { ...nt, ...t || {} }, this._language = i || "en";
642
+ isCardinalFrame(t) {
643
+ return this._cardinalFrames.includes(t);
716
644
  }
717
- getLabel(t) {
718
- return t in this._labels ? this.get(this._labels[t]) : t;
645
+ clampFrameIndex(t) {
646
+ return (this._totalFrameCount + t) % this._totalFrameCount;
719
647
  }
720
- get(t) {
721
- if (typeof t == "string")
722
- return t;
723
- if (this._language in t && t[this._language])
724
- return t[this._language];
725
- for (const i in t)
726
- if (t[i])
727
- return t[i];
728
- return "";
648
+ startFrameIndexForScene(t) {
649
+ return this._cardinalFrames[t];
729
650
  }
730
651
  }
731
- const st = W({
732
- setup() {
733
- ge({});
734
- },
735
- name: "QiBuildingChooserSvg",
736
- components: {
737
- QiBuildingChooserSunSimControl: Ce,
738
- QiBuildingChooserSceneImageStack: _e,
739
- QiNorthDirection: ie,
740
- QiFloatingCard: ne,
741
- QiHoverProbe: Q,
742
- QiZoomBox: se
743
- },
744
- emits: ["go-to-building", "hover-over-building", "hover-out-building"],
745
- provide() {
746
- return {
747
- i18n: this.i18n ? new R(this.i18n.labels, this.i18n.language) : new R()
748
- };
749
- },
652
+ const pe = 64, q = 4, Ge = 120, Xe = {
653
+ name: "QiApartmentChooserRotator",
750
654
  props: {
751
- showCards: { type: Boolean, default: () => !0 },
752
- colorCallback: {
753
- type: Function,
754
- default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
755
- },
756
- buildingCallback: { type: Function, default: (e) => e },
757
- canGoToBuildingCallback: { type: Function, default: () => !0 },
758
- buildingChooserTimeOfDay: { type: String, default: null },
655
+ viewModel: { type: Object, required: !0 },
656
+ build: { type: String, default: "" },
759
657
  cdnFileResolver: { type: Function, required: !0 },
760
- i18n: { type: Object, default: void 0 },
761
- interactiveDesktop: { type: Boolean, default: !0 },
762
- interactiveMobile: { type: Boolean, default: !0 },
763
- customOverlayContent: { type: String, default: "" }
658
+ cardinalFrames: { type: Array, required: !0 }
764
659
  },
660
+ emits: ["loaded", "error", "progress"],
765
661
  data() {
662
+ const e = this.createFrames();
766
663
  return {
767
- sceneState: { preloaded: !1, ready: !1 },
768
- canvasDimensions: { width: 0, height: 0 },
769
- pos: { x: 0, y: 0, width: 0, height: 0 },
770
- pickerData: void 0,
771
- hoverBuildingId: void 0,
772
- halfHourMark: (/* @__PURE__ */ new Date()).getHours() * 2 + ((/* @__PURE__ */ new Date()).getMinutes() < 30 ? 0 : 1),
773
- error: !1,
774
- resourceLoader: new H(),
775
- svgObjects: void 0,
776
- svgViewBox: "0 0 0 0"
664
+ loadTracker: new se(e.length).onLoadFinished(() => this.$emit("loaded")).onLoadProgress((t) => this.$emit("progress", t)).onLoadError(() => this.$emit("error")),
665
+ sceneRotator: new Je(this.cardinalFrames, pe),
666
+ images: e,
667
+ isPreloaded: !1
777
668
  };
778
669
  },
779
670
  computed: {
780
- isHoverable() {
781
- return this.$refs.hoverProbe.isHoverEnabled;
782
- },
783
- hoverBuilding() {
784
- return this.getBuildingData(this.hoverBuildingId);
671
+ activeFrame() {
672
+ return this.images.find((e) => e.show);
785
673
  }
786
674
  },
787
675
  watch: {
788
- buildingChooserTimeOfDay: {
789
- handler() {
790
- if (this.buildingChooserTimeOfDay) {
791
- const [e, t, i] = /^(\d\d):(\d\d)$/.exec(
792
- this.buildingChooserTimeOfDay
793
- ), r = parseInt(i);
794
- this.halfHourMark = parseInt(t) * 2 + (r < 15 ? 0 : r > 45 ? 2 : 1);
795
- }
796
- },
797
- immediate: !0
798
- },
799
- hoverBuildingId(e, t) {
800
- e ? this.$emit("hover-over-building", this.getBuildingData(e)) : this.$emit("hover-out-building", this.getBuildingData(t));
676
+ "viewModel.currentScene"(e, t) {
677
+ const i = this.getDirection(t, e), r = this.getSceneCountBetween(t, e);
678
+ this.rotateInDirection(t, i, r);
801
679
  }
802
680
  },
803
- async mounted() {
804
- const t = await new Ie(
805
- this.cdnFileResolver
806
- ).loadBuildingChooser();
807
- if (t) {
808
- this.canvasRaster = new Y(t.mapImage), this.buildingMap = new P(t.buildingIds), this.daysOfYear = new J(t.backgrounds), this.pickerData = {
809
- buildingOverlays: t.buildingOverlays,
810
- sceneLongitude: t.viewLongitude
811
- };
812
- const i = [];
813
- for (let { id: r, url: n } of t.buildingOverlays)
814
- this.resourceLoader.loadJson(n.replace(".png", ".svg")).then((s) => {
815
- const d = new DOMParser().parseFromString(s, "image/svg+xml").getElementsByTagName("svg")[0];
816
- this.svgViewBox = d.getAttribute("viewBox"), i.push({
817
- id: r,
818
- svg: d.innerHTML
819
- });
820
- });
821
- this.svgObjects = i;
822
- } else
823
- this.error = !0;
681
+ created() {
682
+ this.rotateComplete();
824
683
  },
825
684
  methods: {
826
- resizeScene({ width: e, height: t }) {
827
- this.canvasDimensions.width = e, this.canvasDimensions.height = t;
828
- },
829
- sceneReset() {
830
- this.sceneState = { preloaded: !1, ready: !1 };
685
+ rotateInDirection(e, t, i) {
686
+ this.viewModel.isRotating || (this.viewModel.isRotating = !0, this.rotationStep(
687
+ this.sceneRotator.start(
688
+ t,
689
+ e % q,
690
+ i
691
+ )
692
+ ));
831
693
  },
832
- getBuildingData(e) {
833
- return this.buildingCallback ? this.buildingCallback(e) : e;
694
+ rotationStep(e) {
695
+ setTimeout(() => {
696
+ this.images[e.frameIndex].show = !1;
697
+ const t = e.nextFrame();
698
+ this.images[t.frameIndex].show = !0, t.atEnd ? this.rotateComplete() : window.requestAnimationFrame(() => this.rotationStep(t));
699
+ }, 1e3 / Ge);
834
700
  },
835
- getColor(e) {
836
- return this.colorCallback(
837
- this.getBuildingData(e),
838
- e === this.hoverBuildingId ? "hover" : "idle"
701
+ rotateComplete() {
702
+ const e = this.sceneRotator.startFrameIndexForScene(
703
+ this.viewModel.currentScene % q
839
704
  );
705
+ e in this.images && (this.images[e].show = !0), this.viewModel.isRotating = !1;
840
706
  },
841
- getGClass(e) {
842
- const t = this.getBuildingData(e), i = this.colorCallback(
843
- t,
844
- e === this.hoverBuildingId ? "hover" : "idle"
845
- ), r = [];
846
- return e === this.hoverBuildingId ? r.push("hover") : r.push("idle"), i && this.canGoToBuildingCallback(t) ? r.push("clickable") : r.push("restricted"), r.join(" ");
707
+ createFrames() {
708
+ const e = [];
709
+ for (let t = 0; t < pe; t++) {
710
+ const { sourceSet: i, defaultPath: r } = this.frameImageSource(t);
711
+ e.push({
712
+ index: t,
713
+ sourceSet: i,
714
+ defaultPath: r,
715
+ show: !1
716
+ });
717
+ }
718
+ return e;
847
719
  },
848
- getGStyle(e) {
849
- const t = this.getBuildingData(e), i = this.colorCallback(
850
- t,
851
- e === this.hoverBuildingId ? "hover" : "idle"
720
+ frameImageSource(e) {
721
+ const t = ("0000" + (e + 1)).slice(-4), i = this.build ? `?v=${this.build}` : "", r = [
722
+ `${this.cdnFileResolver(`/480/${t}.jpg${i}`)} 480w`,
723
+ `${this.cdnFileResolver(`/960/${t}.jpg${i}`)} 960w`,
724
+ `${this.cdnFileResolver(`/1280/${t}.jpg${i}`)} 1280w`
725
+ ].join(","), n = this.cdnFileResolver(
726
+ `/480/${t}.jpg${i}`
852
727
  );
853
- if (i) {
854
- const { r, g: n, b: s, a, s: d } = i;
855
- return {
856
- strokeWidth: d !== void 0 ? d : 2,
857
- stroke: `rgb(${r}, ${n}, ${s})`,
858
- strokeOpacity: 1,
859
- fill: `rgb(${r}, ${n}, ${s})`,
860
- fillOpacity: a / 255,
861
- cursor: `${this.canGoToBuildingCallback(t) ? "cursor" : "default"} !important`
862
- };
863
- } else
864
- return {
865
- strokeWidth: 0,
866
- stroke: "white",
867
- strokeOpacity: 0,
868
- fill: "white",
869
- fillOpacity: 0,
870
- cursor: "default !important"
871
- };
872
- },
873
- onBuildingMouseOver(e, t) {
874
- this.isHoverable && (this.pos = {
875
- x: e.layerX,
876
- y: e.layerY,
877
- width: this.canvasDimensions.width,
878
- height: this.canvasDimensions.height
879
- }, this.hoverBuildingId = t, this.$emit("hover-over-building", this.getBuildingData(t)));
880
- },
881
- onBuildingMouseOut(e, t) {
882
- this.isHoverable && (this.pos = {
883
- x: e.layerX,
884
- y: e.layerY,
885
- width: this.canvasDimensions.width,
886
- height: this.canvasDimensions.height
887
- }, this.hoverBuildingId = void 0, this.$emit("hover-out-building", this.getBuildingData(t)));
728
+ return { sourceSet: r, defaultPath: n };
888
729
  },
889
- onBuildingMouseMove(e) {
890
- this.isHoverable && (this.pos = {
891
- x: e.layerX,
892
- y: e.layerY,
893
- width: this.canvasDimensions.width,
894
- height: this.canvasDimensions.height
895
- });
730
+ getSceneCountBetween(e, t) {
731
+ const i = q / 2, r = Math.abs(e - t);
732
+ return r > i ? q - r : r;
896
733
  },
897
- onBuildingClick(e) {
898
- this.hoverBuildingId = e, this.isHoverable && this.hoverBuilding && this.canGoToBuildingCallback(this.hoverBuilding) && this.$emit("go-to-building", this.hoverBuilding);
734
+ getDirection(e, t) {
735
+ if (e === t)
736
+ return 0;
737
+ const r = Math.abs(e - t) < q / 2;
738
+ return r && e < t || !r && e > t ? 1 : -1;
899
739
  }
900
740
  }
901
- }), ot = {
741
+ }, Ze = {
902
742
  key: 0,
903
- style: { height: "50vh" },
904
- class: "d-flex justify-center align-center blue-grey lighten-5"
905
- }, rt = { class: "image-instances" }, at = { key: 0 }, lt = { class: "svg-container" }, dt = ["viewBox"], ct = ["innerHTML", "data-building-id", "onMouseover", "onMouseout", "onMousemove", "onClick"], ut = ["innerHTML"];
906
- function ht(e, t, i, r, n, s) {
907
- const a = c("v-icon"), d = c("qi-building-chooser-scene-image-stack"), p = c("qi-zoom-box"), v = c("qi-north-direction"), w = c("qi-building-chooser-sun-sim-control"), S = c("qi-floating-card"), g = c("qi-hover-probe");
908
- return e.error ? (l(), m("div", ot, [
909
- u(a, { "x-large": "" }, {
910
- default: h(() => [
911
- L("mdi-alert-circle-outline")
912
- ]),
913
- _: 1
914
- })
915
- ])) : e.pickerData ? (l(), m("div", {
916
- key: 1,
917
- style: M(`height: ${e.canvasDimensions.height}px; position: relative`),
918
- class: "image-container"
919
- }, [
920
- u(p, {
921
- desktop: e.interactiveDesktop,
922
- mobile: e.interactiveMobile
923
- }, {
924
- default: h(() => [
925
- o("div", rt, [
926
- u(d, {
927
- "image-urls": e.daysOfYear.imageUrls,
928
- "active-index": e.halfHourMark,
929
- onResize: e.resizeScene,
930
- onPreloaded: t[0] || (t[0] = (b) => e.sceneState.preloaded = !0),
931
- onReady: t[1] || (t[1] = (b) => e.sceneState.ready = !0),
932
- onReset: e.sceneReset
933
- }, null, 8, ["image-urls", "active-index", "onResize", "onReset"]),
934
- e.svgObjects ? x((l(), m("div", at, [
935
- o("div", lt, [
936
- (l(), m("svg", { viewBox: e.svgViewBox }, [
937
- (l(!0), m(U, null, D(e.svgObjects, ({ id: b, svg: k }, I) => (l(), m("g", {
938
- key: I,
939
- innerHTML: k,
940
- "data-building-id": b,
941
- class: E(e.getGClass(b)),
942
- style: M(e.getGStyle(b)),
943
- onMouseover: (O) => e.onBuildingMouseOver(O, b),
944
- onMouseout: (O) => e.onBuildingMouseOut(O, b),
945
- onMousemove: (O) => e.onBuildingMouseMove(O, b),
946
- onClick: (O) => e.onBuildingClick(b)
947
- }, null, 46, ct))), 128))
948
- ], 8, dt))
949
- ])
950
- ], 512)), [
951
- [B, e.sceneState.preloaded]
952
- ]) : f("", !0),
953
- x(o("div", {
954
- class: "custom-overlay-layer",
955
- innerHTML: e.customOverlayContent
956
- }, null, 8, ut), [
957
- [B, e.sceneState.preloaded]
958
- ])
959
- ])
960
- ]),
961
- _: 1
962
- }, 8, ["desktop", "mobile"]),
963
- x(o("div", null, [
964
- e.pickerData.sceneLongitude ? (l(), y(v, {
743
+ class: "fill-parent d-flex justify-center align-center blue-grey lighten-5"
744
+ }, Ke = {
745
+ key: 1,
746
+ class: "frame-container"
747
+ }, et = { class: "frame-image" }, tt = ["srcset", "type"], it = ["src"], nt = {
748
+ key: 2,
749
+ id: "image-stack",
750
+ class: "frame-container"
751
+ }, st = ["alt"], ot = ["srcset"], rt = ["src"];
752
+ function at(e, t, i, r, n, s) {
753
+ const a = c("v-icon");
754
+ return l(), m("div", null, [
755
+ n.loadTracker.isError ? (l(), m("div", Ze, [
756
+ u(a, { "x-large": "" }, {
757
+ default: h(() => [
758
+ L("mdi-alert-circle-outline")
759
+ ]),
760
+ _: 1
761
+ })
762
+ ])) : n.isPreloaded ? (l(), m("div", nt, [
763
+ (l(!0), m(R, null, D(n.images, (d) => (l(), m("picture", {
764
+ key: d.index,
765
+ alt: d.index,
766
+ class: E({ "frame-image": !0, show: d.show })
767
+ }, [
768
+ o("source", {
769
+ srcset: d.sourceSet,
770
+ type: "image/jpeg"
771
+ }, null, 8, ot),
772
+ o("img", {
773
+ src: d.defaultPath,
774
+ alt: "Building image",
775
+ onLoad: t[2] || (t[2] = (p) => n.loadTracker.partLoaded()),
776
+ onError: t[3] || (t[3] = (p) => n.loadTracker.errorDetected())
777
+ }, null, 40, rt)
778
+ ], 10, st))), 128))
779
+ ])) : (l(), m("div", Ke, [
780
+ o("picture", et, [
781
+ o("source", {
782
+ srcset: s.activeFrame.sourceSet,
783
+ type: s.activeFrame.type
784
+ }, null, 8, tt),
785
+ o("img", {
786
+ src: s.activeFrame.defaultPath,
787
+ onLoad: t[0] || (t[0] = (d) => n.isPreloaded = !0),
788
+ onError: t[1] || (t[1] = (d) => n.loadTracker.errorDetected())
789
+ }, null, 40, it)
790
+ ])
791
+ ]))
792
+ ]);
793
+ }
794
+ const Ae = /* @__PURE__ */ C(Xe, [["render", at], ["__scopeId", "data-v-e6481f8e"]]), lt = {
795
+ name: "FloatingCard",
796
+ props: {
797
+ pos: { type: Object, required: !0 },
798
+ isHoverable: Boolean
799
+ },
800
+ computed: {
801
+ q() {
802
+ const e = this.pos.x <= this.pos.width / 2 ? "left" : "right";
803
+ return `${this.pos.y <= this.pos.height / 2 ? "top" : "bottom"}-${e}`;
804
+ }
805
+ }
806
+ };
807
+ function dt(e, t, i, r, n, s) {
808
+ const a = c("v-dialog"), d = c("v-fade-transition");
809
+ return l(), y(d, {
810
+ origin: s.q.replace("-", " ") + " " + i.pos.x + " " + i.pos.y
811
+ }, {
812
+ default: h(() => [
813
+ i.isHoverable ? (l(), m("div", {
965
814
  key: 0,
966
- class: "north-indicator",
967
- longitude: e.pickerData.sceneLongitude
968
- }, null, 8, ["longitude"])) : f("", !0),
969
- u(w, {
970
- modelValue: e.halfHourMark,
971
- "onUpdate:modelValue": t[2] || (t[2] = (b) => e.halfHourMark = b),
972
- "date-selector": e.daysOfYear,
973
- "is-loading": !e.sceneState.ready
974
- }, null, 8, ["modelValue", "date-selector", "is-loading"])
975
- ], 512), [
976
- [B, e.sceneState.preloaded]
815
+ class: E(["floating-card", s.q]),
816
+ style: M({ left: `${i.pos.x}px`, top: `${i.pos.y}px`, pointerEvents: "none" })
817
+ }, [
818
+ A(e.$slots, "default", { isHoverable: i.isHoverable }, void 0, !0)
819
+ ], 6)) : (l(), y(a, {
820
+ key: 1,
821
+ value: !0,
822
+ width: "auto",
823
+ "onClick:outside": t[0] || (t[0] = (p) => e.$emit("outside", p))
824
+ }, {
825
+ default: h(() => [
826
+ A(e.$slots, "default", { isHoverable: i.isHoverable }, void 0, !0)
827
+ ]),
828
+ _: 3
829
+ }))
977
830
  ]),
978
- e.showCards && e.hoverBuilding ? (l(), y(S, {
979
- key: 0,
980
- "is-hoverable": e.isHoverable,
981
- pos: e.pos,
982
- onOutside: t[3] || (t[3] = () => e.hoverBuildingId = void 0)
983
- }, {
984
- default: h(() => [
985
- A(e.$slots, "default", {
986
- building: e.hoverBuilding,
987
- canGoToBuilding: e.canGoToBuildingCallback(e.hoverBuilding),
988
- goToBuilding: () => e.canGoToBuildingCallback(e.hoverBuilding) && e.$emit("go-to-building", e.hoverBuilding),
989
- pos: e.pos,
990
- isHoverable: e.isHoverable,
991
- close: () => e.hoverBuildingId = void 0
992
- }, void 0, !0)
993
- ]),
994
- _: 3
995
- }, 8, ["is-hoverable", "pos"])) : f("", !0),
996
- u(g, { ref: "hoverProbe" }, null, 512)
997
- ], 4)) : f("", !0);
831
+ _: 3
832
+ }, 8, ["origin"]);
998
833
  }
999
- const le = /* @__PURE__ */ C(st, [["render", ht], ["__scopeId", "data-v-0a2cec1f"]]), mt = {
1000
- name: "QiBuildingChooserRasterOverlay",
834
+ const J = /* @__PURE__ */ C(lt, [["render", dt], ["__scopeId", "data-v-b74de171"]]), ct = {
835
+ name: "QiZoomBox",
1001
836
  props: {
1002
- imageUrl: { type: String, required: !0 },
1003
- dimensions: { type: Object, required: !0 },
1004
- color: {
1005
- type: Object,
1006
- default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
837
+ desktop: {
838
+ type: Boolean,
839
+ default: !0
840
+ },
841
+ mobile: {
842
+ type: Boolean,
843
+ default: !0
844
+ },
845
+ maxScale: {
846
+ type: Number,
847
+ default: 10
848
+ },
849
+ consumeMouseClickWhenMoved: {
850
+ type: Boolean,
851
+ default: !0
852
+ },
853
+ consumeMouseUpWhenMoved: {
854
+ type: Boolean,
855
+ default: !0
1007
856
  }
1008
857
  },
1009
858
  data() {
1010
859
  return {
1011
- isLoaded: !1,
1012
- overlayImage: void 0,
1013
- resourceLoader: new H(),
1014
- context: void 0,
1015
- imageData: void 0,
1016
- imageDataIndices: []
860
+ zoom: 100,
861
+ originX: 0,
862
+ originY: 0,
863
+ moving: !1,
864
+ scaling: !1,
865
+ lastEvent: void 0,
866
+ moved: !1
1017
867
  };
1018
868
  },
1019
- watch: {
1020
- color(e, t) {
1021
- (e.r !== t.r || e.g !== t.g || e.b !== t.b || e.a !== t.a) && this.draw();
869
+ computed: {
870
+ transform() {
871
+ return `translateX(${this.originX}px) translateY(${this.originY}px) scale(${this.scale})`;
872
+ },
873
+ scale() {
874
+ return this.zoom / 100;
875
+ },
876
+ actualMaxScale() {
877
+ return this.maxScale * 100;
1022
878
  }
1023
879
  },
1024
- async mounted() {
1025
- this.overlayImage = await this.resourceLoader.loadImage(this.imageUrl), this.setupDraw();
1026
- },
1027
- methods: {
1028
- setupDraw() {
1029
- if (!this.overlayImage || !this.$refs.canvas)
1030
- return;
1031
- const { width: e, height: t } = this.dimensions;
1032
- if (!(e === 0 || t === 0)) {
1033
- this.context = this.$refs.canvas.getContext("2d", {
1034
- willReadFrequently: !0
1035
- }), this.context.drawImage(this.overlayImage, 0, 0, e, t), this.imageData = this.context.getImageData(0, 0, e, t);
1036
- for (let i = 3; i < this.imageData.data.length; i += 4)
1037
- this.imageData.data[i] !== 0 && this.imageDataIndices.push(i);
1038
- this.draw(), this.isLoaded = !0;
1039
- }
880
+ watch: {
881
+ scale() {
882
+ this.emitUpdate();
1040
883
  },
1041
- draw() {
1042
- this.context && this.imageData && (this.applyColor(), this.context.putImageData(this.imageData, 0, 0));
884
+ originX() {
885
+ this.emitUpdate();
1043
886
  },
1044
- applyColor() {
1045
- if (this.color)
1046
- for (let e = 0; e < this.imageDataIndices.length; e++)
1047
- this.imageData.data[this.imageDataIndices[e] - 3] = this.color.r, this.imageData.data[this.imageDataIndices[e] - 2] = this.color.g, this.imageData.data[this.imageDataIndices[e] - 1] = this.color.b, this.imageData.data[this.imageDataIndices[e]] = this.color.a;
1048
- }
1049
- }
1050
- };
1051
- function pt(e, t, i, r, n, s) {
1052
- return l(), m("canvas", F({
1053
- ref: "canvas",
1054
- class: "overlay"
1055
- }, i.dimensions), null, 16);
1056
- }
1057
- const gt = /* @__PURE__ */ C(mt, [["render", pt], ["__scopeId", "data-v-9a90fa2f"]]), vt = W({
1058
- setup() {
1059
- ge({});
1060
- },
1061
- name: "QiBuildingChooserRaster",
1062
- components: {
1063
- QiBuildingChooserRasterOverlay: gt,
1064
- QiBuildingChooserSunSimControl: Ce,
1065
- QiBuildingChooserSceneImageStack: _e,
1066
- QiNorthDirection: ie,
1067
- QiFloatingCard: ne,
1068
- QiHoverProbe: Q,
1069
- QiZoomBox: se
1070
- },
1071
- emits: ["go-to-building", "hover-over-building", "hover-out-building"],
1072
- provide() {
1073
- return {
1074
- i18n: this.i18n ? new R(this.i18n.labels, this.i18n.language) : new R()
1075
- };
1076
- },
1077
- props: {
1078
- showCards: { type: Boolean, default: () => !0 },
1079
- colorCallback: {
1080
- type: Function,
1081
- default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
887
+ originY() {
888
+ this.emitUpdate();
1082
889
  },
1083
- buildingCallback: { type: Function, default: (e) => e },
1084
- canGoToBuildingCallback: { type: Function, default: () => !0 },
1085
- buildingChooserTimeOfDay: { type: String, default: null },
1086
- cdnFileResolver: { type: Function, required: !0 },
1087
- i18n: { type: Object, default: void 0 },
1088
- interactiveDesktop: { type: Boolean, default: !0 },
1089
- interactiveMobile: { type: Boolean, default: !0 },
1090
- customOverlayContent: { type: String, default: "" }
1091
- },
1092
- data() {
1093
- return {
1094
- sceneState: { preloaded: !1, ready: !1 },
1095
- canvasDimensions: { width: 0, height: 0 },
1096
- pos: { x: 0, y: 0, width: 0, height: 0 },
1097
- pickerData: void 0,
1098
- buildingMap: P.empty(),
1099
- canvasRaster: Y.empty(),
1100
- selectedBuildingId: void 0,
1101
- halfHourMark: (/* @__PURE__ */ new Date()).getHours() * 2 + ((/* @__PURE__ */ new Date()).getMinutes() < 30 ? 0 : 1),
1102
- viewResolver: (e, t) => ({ x: e, y: t }),
1103
- error: !1
1104
- };
1105
- },
1106
- computed: {
1107
- isHoverable() {
1108
- return this.$refs.hoverProbe.isHoverEnabled;
890
+ desktop() {
891
+ this.desktop ? this.addDesktopHandlers() : this.removeDesktopHandlers();
1109
892
  },
1110
- selectedBuilding() {
1111
- return this.getBuildingData(this.selectedBuildingId);
893
+ mobile() {
894
+ this.mobile ? this.addMobileHandlers() : this.removeMobileHandlers();
1112
895
  }
1113
896
  },
1114
- watch: {
1115
- buildingChooserTimeOfDay: {
1116
- handler() {
1117
- if (this.buildingChooserTimeOfDay) {
1118
- const [e, t, i] = /^(\d\d):(\d\d)$/.exec(
1119
- this.buildingChooserTimeOfDay
1120
- ), r = parseInt(i);
1121
- this.halfHourMark = parseInt(t) * 2 + (r < 15 ? 0 : r > 45 ? 2 : 1);
1122
- }
1123
- },
1124
- immediate: !0
1125
- },
1126
- selectedBuildingId(e, t) {
1127
- e ? this.$emit("hover-over-building", this.getBuildingData(e)) : this.$emit("hover-out-building", this.getBuildingData(t));
1128
- }
897
+ mounted() {
898
+ this.desktop && this.addDesktopHandlers(), this.mobile && this.addMobileHandlers();
1129
899
  },
1130
- async mounted() {
1131
- const t = await new Ie(
1132
- this.cdnFileResolver
1133
- ).loadBuildingChooser();
1134
- t ? (this.canvasRaster = new Y(t.mapImage), this.buildingMap = new P(t.buildingIds), this.daysOfYear = new J(t.backgrounds), this.pickerData = {
1135
- buildingOverlays: t.buildingOverlays,
1136
- sceneLongitude: t.viewLongitude
1137
- }, this.resizeImages()) : this.error = !0;
900
+ beforeUnmount() {
901
+ this.desktop && this.removeDesktopHandlers(), this.mobile && this.removeMobileHandlers();
1138
902
  },
1139
903
  methods: {
1140
- resizeScene({ width: e, height: t }) {
1141
- this.canvasDimensions.width = e, this.canvasDimensions.height = t, this.$nextTick(this.resizeImages);
904
+ addDesktopHandlers() {
905
+ this.$refs.box.addEventListener("wheel", this.wheelHandler, {
906
+ capture: !0
907
+ }), this.$refs.box.addEventListener("mousedown", this.mouseDownHandler, {
908
+ capture: !0
909
+ }), this.$refs.box.addEventListener("mousemove", this.mouseMoveHandler, {
910
+ capture: !0
911
+ }), window.addEventListener("mouseup", this.mouseUpHandler, {
912
+ capture: !0
913
+ }), window.addEventListener("click", this.mouseClickHandler, {
914
+ capture: !0
915
+ });
1142
916
  },
1143
- sceneReset() {
1144
- this.sceneState = { preloaded: !1, ready: !1 };
917
+ addMobileHandlers() {
918
+ this.$refs.box.addEventListener("touchstart", this.touchStartHandler, {
919
+ capture: !0
920
+ }), this.$refs.box.addEventListener("touchmove", this.touchMoveHandler, {
921
+ capture: !0
922
+ }), window.addEventListener("touchend", this.touchEndHandler, {
923
+ capture: !0
924
+ }), window.addEventListener("touchcancel", this.touchEndHandler, {
925
+ capture: !0
926
+ });
1145
927
  },
1146
- getBuildingData(e) {
1147
- return this.buildingCallback ? this.buildingCallback(e) : e;
928
+ removeDesktopHandlers() {
929
+ this.$refs.box.removeEventListener("wheel", this.wheelHandler, {
930
+ capture: !0
931
+ }), this.$refs.box.removeEventListener("mousedown", this.mouseDownHandler, {
932
+ capture: !0
933
+ }), this.$refs.box.removeEventListener("mousemove", this.mouseMoveHandler, {
934
+ capture: !0
935
+ }), window.removeEventListener("mouseup", this.mouseUpHandler, {
936
+ capture: !0
937
+ }), window.removeEventListener("click", this.mouseClickHandler, {
938
+ capture: !0
939
+ });
1148
940
  },
1149
- getBuildingId(e) {
1150
- const { x: t, y: i } = this.viewResolver(e.layerX, e.layerY);
1151
- return this.buildingMap.getBuildingId(this.canvasRaster, t, i);
941
+ removeMobileHandlers() {
942
+ this.$refs.box.removeEventListener("touchstart", this.touchStartHandler, {
943
+ capture: !0
944
+ }), this.$refs.box.removeEventListener("touchmove", this.touchMoveHandler, {
945
+ capture: !0
946
+ }), window.removeEventListener("touchend", this.touchEndHandler, {
947
+ capture: !0
948
+ }), window.removeEventListener("touchcancel", this.touchEndHandler, {
949
+ capture: !0
950
+ });
1152
951
  },
1153
- resizeImages() {
1154
- if (this.$refs.canvas && (this.canvasRaster.update(this.$refs.canvas), this.$refs.overlays))
1155
- for (const e of this.$refs.overlays)
1156
- e.setupDraw();
952
+ wheelHandler(e) {
953
+ const { x: t, y: i } = this.getOffsetCoordinates(e);
954
+ this.adjustZoom(-e.deltaY / 10, t, i), e.preventDefault();
1157
955
  },
1158
- onMove(e) {
1159
- this.isHoverable && (this.selectedBuildingId = this.getBuildingId(e), this.selectedBuildingId !== void 0 && (this.pos = {
1160
- x: e.layerX,
1161
- y: e.layerY,
1162
- width: this.canvasDimensions.width,
1163
- height: this.canvasDimensions.height
1164
- }));
956
+ mouseDownHandler(e) {
957
+ this.moving = !0, this.moved = !1, this.lastEvent = e;
1165
958
  },
1166
- onClick(e) {
1167
- this.selectedBuildingId = this.getBuildingId(e), this.isHoverable && this.selectedBuilding && this.$emit("go-to-building", this.selectedBuilding);
959
+ mouseMoveHandler(e) {
960
+ if (this.moving) {
961
+ const { x: t, y: i } = this.getOffsetCoordinates(e), { x: r, y: n } = this.getOffsetCoordinates(this.lastEvent), s = {
962
+ x: t - r,
963
+ y: i - n
964
+ };
965
+ this.adjustTranslateX(s.x), this.adjustTranslateY(s.y), this.moved = !0, this.lastEvent = e;
966
+ }
1168
967
  },
1169
- getColor(e) {
1170
- return this.colorCallback(
1171
- this.getBuildingData(e),
1172
- e === this.selectedBuildingId ? "hover" : "idle"
968
+ mouseUpHandler(e) {
969
+ this.moving && this.moved && this.consumeMouseUpWhenMoved && (e.preventDefault(), e.stopImmediatePropagation());
970
+ },
971
+ mouseClickHandler(e) {
972
+ this.moving && (this.moved && this.consumeMouseClickWhenMoved && (e.preventDefault(), e.stopImmediatePropagation()), this.moving = !1);
973
+ },
974
+ touchStartHandler(e) {
975
+ this.moving = e.touches.length === 1, this.scaling = e.touches.length === 2, this.lastEvent = e;
976
+ },
977
+ touchMoveHandler(e) {
978
+ if (this.moving) {
979
+ const { x: t, y: i } = this.getOffsetCoordinates(e.touches[0]), { x: r, y: n } = this.getOffsetCoordinates(
980
+ this.lastEvent.touches[0]
981
+ ), s = {
982
+ x: t - r,
983
+ y: i - n
984
+ };
985
+ this.adjustTranslateX(s.x), this.adjustTranslateY(s.y);
986
+ } else if (this.scaling && e.touches.length === 2) {
987
+ const { x: t, y: i } = this.getOffsetCoordinates(e.touches[0]), { x: r, y: n } = this.getOffsetCoordinates(
988
+ this.lastEvent.touches[0]
989
+ ), { x: s, y: a } = this.getOffsetCoordinates(e.touches[1]), { x: d, y: p } = this.getOffsetCoordinates(
990
+ this.lastEvent.touches[1]
991
+ ), v = Math.hypot(r - d, n - p), w = Math.hypot(t - s, i - a), S = (s + t) / 2, g = (a + i) / 2;
992
+ this.adjustZoom(w - v, S, g);
993
+ }
994
+ this.lastEvent = e;
995
+ },
996
+ touchEndHandler() {
997
+ this.moving = !1, this.scaling = !1;
998
+ },
999
+ getOffsetCoordinates(e) {
1000
+ const { left: t, top: i } = this.$refs.box.getBoundingClientRect();
1001
+ return {
1002
+ x: e.clientX - t,
1003
+ y: e.clientY - i
1004
+ };
1005
+ },
1006
+ adjustTranslateX(e) {
1007
+ const t = this.$refs.box.clientWidth, i = t * this.scale;
1008
+ this.originX = Math.max(
1009
+ Math.min(0, this.originX + e),
1010
+ -(i - t)
1173
1011
  );
1174
1012
  },
1175
- updateView({ resolve: e }) {
1176
- this.viewResolver = e;
1013
+ adjustTranslateY(e) {
1014
+ const t = this.$refs.box.clientHeight, i = t * this.scale;
1015
+ this.originY = Math.max(
1016
+ Math.min(0, this.originY + e),
1017
+ -(i - t)
1018
+ );
1019
+ },
1020
+ adjustZoom(e, t, i) {
1021
+ const r = this.$refs.box.clientWidth, n = this.$refs.box.clientHeight, s = r * this.scale, a = n * this.scale;
1022
+ this.zoom = Math.min(
1023
+ Math.max(100, this.zoom + e),
1024
+ this.actualMaxScale
1025
+ );
1026
+ const d = r * this.scale, p = n * this.scale, v = d - s, w = p - a;
1027
+ this.originX -= t / r * v, this.originY -= i / n * w, this.adjustTranslateX(0), this.adjustTranslateY(0);
1028
+ },
1029
+ emitUpdate() {
1030
+ this.$emit("update", {
1031
+ scale: this.scale,
1032
+ x: this.originX,
1033
+ y: this.originY,
1034
+ resolve: (e, t) => {
1035
+ const i = this.$refs.box.clientWidth, r = this.$refs.box.clientHeight, n = this.originX / -this.scale, s = this.originY / -this.scale, a = n + i / this.scale, d = s + r / this.scale, p = e / i * (a - n) + n, v = t / r * (d - s) + s;
1036
+ return { x: p, y: v };
1037
+ }
1038
+ });
1177
1039
  }
1178
1040
  }
1179
- }), ft = {
1180
- key: 0,
1181
- style: { height: "50vh" },
1182
- class: "d-flex justify-center align-center blue-grey lighten-5"
1183
- }, bt = { class: "image-instances" }, yt = ["innerHTML"];
1184
- function wt(e, t, i, r, n, s) {
1185
- const a = c("v-icon"), d = c("qi-building-chooser-scene-image-stack"), p = c("qi-building-chooser-raster-overlay"), v = c("qi-zoom-box"), w = c("qi-north-direction"), S = c("qi-building-chooser-sun-sim-control"), g = c("qi-floating-card"), b = c("qi-hover-probe");
1186
- return e.error ? (l(), m("div", ft, [
1187
- u(a, { "x-large": "" }, {
1188
- default: h(() => [
1189
- L("mdi-alert-circle-outline")
1190
- ]),
1191
- _: 1
1192
- })
1193
- ])) : e.pickerData ? (l(), m("div", {
1194
- key: 1,
1195
- style: M(`cursor: ${e.selectedBuildingId ? "pointer" : "auto"};height: ${e.canvasDimensions.height}px; position: relative`),
1196
- class: "image-container"
1197
- }, [
1198
- u(v, {
1199
- desktop: e.interactiveDesktop,
1200
- mobile: e.interactiveMobile,
1201
- onUpdate: e.updateView
1202
- }, {
1203
- default: h(() => [
1204
- o("div", bt, [
1205
- u(d, {
1206
- "image-urls": e.daysOfYear.imageUrls,
1207
- "active-index": e.halfHourMark,
1208
- onResize: e.resizeScene,
1209
- onPreloaded: t[0] || (t[0] = (k) => e.sceneState.preloaded = !0),
1210
- onReady: t[1] || (t[1] = (k) => e.sceneState.ready = !0),
1211
- onReset: e.sceneReset
1212
- }, null, 8, ["image-urls", "active-index", "onResize", "onReset"]),
1213
- x(o("div", null, [
1214
- (l(!0), m(U, null, D(e.pickerData.buildingOverlays, (k) => (l(), y(p, {
1215
- ref_for: !0,
1216
- ref: "overlays",
1217
- key: k.id,
1218
- "image-url": k.url,
1219
- dimensions: e.canvasDimensions,
1220
- color: e.getColor(k.id)
1221
- }, null, 8, ["image-url", "dimensions", "color"]))), 128))
1222
- ], 512), [
1223
- [B, e.sceneState.preloaded]
1224
- ])
1225
- ]),
1226
- o("canvas", F(e.canvasDimensions, {
1227
- ref: "canvas",
1228
- class: { hover: !!e.selectedBuildingId },
1229
- onClick: t[2] || (t[2] = (...k) => e.onClick && e.onClick(...k)),
1230
- onMousemove: t[3] || (t[3] = (...k) => e.onMove && e.onMove(...k))
1231
- }), null, 16),
1232
- x(o("div", {
1233
- class: "custom-overlay-layer",
1234
- innerHTML: e.customOverlayContent
1235
- }, null, 8, yt), [
1236
- [B, e.sceneState.preloaded]
1237
- ])
1238
- ]),
1239
- _: 1
1240
- }, 8, ["desktop", "mobile", "onUpdate"]),
1241
- x(o("div", null, [
1242
- e.pickerData.sceneLongitude ? (l(), y(w, {
1243
- key: 0,
1244
- class: "north-indicator",
1245
- longitude: e.pickerData.sceneLongitude
1246
- }, null, 8, ["longitude"])) : f("", !0),
1247
- u(S, {
1248
- modelValue: e.halfHourMark,
1249
- "onUpdate:modelValue": t[4] || (t[4] = (k) => e.halfHourMark = k),
1250
- "date-selector": e.daysOfYear,
1251
- "is-loading": !e.sceneState.ready
1252
- }, null, 8, ["modelValue", "date-selector", "is-loading"])
1253
- ], 512), [
1254
- [B, e.sceneState.preloaded]
1255
- ]),
1256
- e.showCards && e.selectedBuilding ? (l(), y(g, {
1257
- key: 0,
1258
- "is-hoverable": e.isHoverable,
1259
- pos: e.pos,
1260
- onOutside: t[5] || (t[5] = () => e.selectedBuildingId = void 0)
1261
- }, {
1262
- default: h(() => [
1263
- A(e.$slots, "default", {
1264
- building: e.selectedBuilding,
1265
- canGoToBuilding: e.canGoToBuildingCallback(e.selectedBuilding),
1266
- goToBuilding: () => e.canGoToBuildingCallback(e.selectedBuilding) && e.$emit("go-to-building", e.selectedBuilding),
1267
- pos: e.pos,
1268
- isHoverable: e.isHoverable,
1269
- close: () => e.selectedBuildingId = void 0
1270
- }, void 0, !0)
1271
- ]),
1272
- _: 3
1273
- }, 8, ["is-hoverable", "pos"])) : f("", !0),
1274
- u(b, { ref: "hoverProbe" }, null, 512)
1275
- ], 4)) : f("", !0);
1041
+ }, ut = {
1042
+ ref: "box",
1043
+ class: "zoom-box-container"
1044
+ };
1045
+ function ht(e, t, i, r, n, s) {
1046
+ return l(), m("div", ut, [
1047
+ o("div", {
1048
+ style: M({ "transform-origin": "top left", transform: s.transform }),
1049
+ class: "zoom-box"
1050
+ }, [
1051
+ A(e.$slots, "default", {}, void 0, !0)
1052
+ ], 4)
1053
+ ], 512);
1276
1054
  }
1277
- const de = /* @__PURE__ */ C(vt, [["render", wt], ["__scopeId", "data-v-08f2ea1e"]]), kt = {
1278
- name: "QiBuildingChooser",
1279
- components: {
1280
- QiBuildingChooserSvg: le,
1281
- QiBuildingChooserRaster: de
1282
- },
1283
- emits: ["go-to-building", "hover-over-building", "hover-out-building"],
1284
- props: {
1285
- showCards: { type: Boolean, default: () => !0 },
1286
- colorCallback: {
1287
- type: Function,
1288
- default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
1289
- },
1290
- buildingCallback: { type: Function, default: (e) => e },
1291
- cdnFileResolver: { type: Function, required: !0 },
1292
- i18n: { type: Object, default: void 0 },
1293
- interactiveDesktop: { type: Boolean, default: !0 },
1294
- interactiveMobile: { type: Boolean, default: !0 },
1295
- useSvg: { type: Boolean, default: !1 },
1296
- buildingChooserTimeOfDay: { type: String, default: null },
1297
- canGoToBuildingCallback: { type: Function, default: () => !0 },
1298
- customOverlayContent: { type: String, default: "" }
1299
- },
1300
- computed: {
1301
- component() {
1302
- return this.useSvg ? le : de;
1303
- }
1055
+ const G = /* @__PURE__ */ C(ct, [["render", ht], ["__scopeId", "data-v-83bfd28a"]]), ce = 4;
1056
+ function Le(e) {
1057
+ return e < ce ? e + 1 : 1;
1058
+ }
1059
+ function mt(e) {
1060
+ return e > 1 ? e - 1 : ce;
1061
+ }
1062
+ class pt {
1063
+ constructor(t) {
1064
+ this._state = {
1065
+ isRotating: !1,
1066
+ currentScene: t
1067
+ };
1068
+ }
1069
+ get isRotating() {
1070
+ return this._state.isRotating;
1071
+ }
1072
+ set isRotating(t) {
1073
+ this._state.isRotating = t;
1074
+ }
1075
+ get navigator() {
1076
+ return this._navigator;
1077
+ }
1078
+ get sceneModel() {
1079
+ return this._sceneModel;
1080
+ }
1081
+ unlessRotatingDo(t) {
1082
+ this.isRotating || t();
1083
+ }
1084
+ get currentScene() {
1085
+ return this._state.currentScene;
1086
+ }
1087
+ set currentScene(t) {
1088
+ this._state.currentScene = t;
1089
+ }
1090
+ rotateCounterClockwise() {
1091
+ this.unlessRotatingDo(() => {
1092
+ this.currentScene = Le(this.currentScene);
1093
+ });
1094
+ }
1095
+ rotateClockwise() {
1096
+ this.unlessRotatingDo(() => {
1097
+ this.currentScene = mt(this.currentScene);
1098
+ });
1304
1099
  }
1305
- };
1306
- function Ct(e, t, i, r, n, s) {
1307
- return l(), y(ve(s.component), {
1308
- "show-cards": i.showCards,
1309
- "color-callback": i.colorCallback,
1310
- "building-callback": i.buildingCallback,
1311
- "cdn-file-resolver": i.cdnFileResolver,
1312
- i18n: i.i18n,
1313
- "interactive-desktop": i.interactiveDesktop,
1314
- "interactive-mobile": i.interactiveMobile,
1315
- "building-chooser-time-of-day": i.buildingChooserTimeOfDay,
1316
- "can-go-to-building-callback": i.canGoToBuildingCallback,
1317
- "custom-overlay-content": i.customOverlayContent,
1318
- onGoToBuilding: t[0] || (t[0] = (a) => e.$emit("go-to-building", a)),
1319
- onHoverOverBuilding: t[1] || (t[1] = (a) => e.$emit("hover-over-building", a)),
1320
- onHoverOutBuilding: t[2] || (t[2] = (a) => e.$emit("hover-out-building", a))
1321
- }, Be({ _: 2 }, [
1322
- D(Object.keys(e.$slots), (a) => ({
1323
- name: a,
1324
- fn: h((d) => [
1325
- A(e.$slots, a, fe(be(d)))
1326
- ])
1327
- }))
1328
- ]), 1064, ["show-cards", "color-callback", "building-callback", "cdn-file-resolver", "i18n", "interactive-desktop", "interactive-mobile", "building-chooser-time-of-day", "can-go-to-building-callback", "custom-overlay-content"]);
1329
1100
  }
1330
- const _t = /* @__PURE__ */ C(kt, [["render", Ct]]), Se = {
1331
- methods: {
1332
- throttle(e, t) {
1333
- let i = !0;
1334
- return function(...r) {
1335
- i && (i = !1, e.apply(this, r), setTimeout(() => i = !0, t));
1336
- };
1337
- }
1101
+ const gt = {
1102
+ // virtual tour default labels
1103
+ interior: "Interiør",
1104
+ "see-a-selection-of-the-options-in-the-project": "Se et utvalg av tilvalgsmulighetene i prosjektet.",
1105
+ "floor-plan": "Planløsning",
1106
+ "all-illustrations-are-indicative-deviations-may-occur": { nb: "Alle illustrasjoner er veiledende. Avvik kan forekomme.", en: "All illustrations are indicative. Discrepancies may exist." },
1107
+ "read-more-here": "Les mer her",
1108
+ "i-understand": { nb: "Jeg forstår", en: "I understand" },
1109
+ share: "Share",
1110
+ "share-to-facebook": "Share to Facebook",
1111
+ "share-to-linkedin": "Share to Linkedin",
1112
+ "share-to-twitter": "Share to Twitter",
1113
+ "share-via-email": "Share via Email",
1114
+ "copy-link": "Copy link",
1115
+ "virtual-view": "Virtuell Visning",
1116
+ "slide-show": "Slide Show",
1117
+ // building chooser default labels
1118
+ room: "Room",
1119
+ floor: "Floor",
1120
+ "see-apartments": "See apartments",
1121
+ // apartment chooser default labels
1122
+ "see-apartment": "See apartment",
1123
+ "click-and-drag-to-look-around": { en: "Click and drag to look around", nb: "Klikk og dra for å se deg rundt" },
1124
+ "click-on-the-cricles-to-move-around": { en: "Click on the circles to move around", nb: "Klikk på sirkelene for å gå rundt" },
1125
+ "use-the-mouse-wheel-to-zoom": { en: "Use the mouse wheel to zoom", nb: "Bruk mushjulet for å zoome" },
1126
+ "you-can-also-use-the-arrow-keys-to-move-around": { en: "You can also use the arrow keys to move around", nb: "Du kan også bruke pilene på tastaturet for å gå rundt" },
1127
+ "tap-and-drag-to-look-around": { en: "Tap and drag to look around", nb: "Trykk og dra for å se deg rundt" },
1128
+ "tap-on-the-circles-to-move-around": { en: "Tap on the circles to move around", nb: "Trykk på sirkelene for å gå rundt" },
1129
+ "use-two-fingers-to-zoom": { en: "Use two fingers to zoom", nb: "Bruk to fingre for å zoome" },
1130
+ "dont-show-again": { en: "Don't Show Again", nb: "Ikke vis igjen" }
1131
+ };
1132
+ class U {
1133
+ constructor(t, i) {
1134
+ this._labels = { ...gt, ...t || {} }, this._language = i || "en";
1338
1135
  }
1339
- }, It = {
1340
- name: "QiApartmentChooserRaster",
1341
- components: { QiHoverProbe: Q },
1342
- mixins: [Se],
1136
+ getLabel(t) {
1137
+ return t in this._labels ? this.get(this._labels[t]) : t;
1138
+ }
1139
+ get(t) {
1140
+ if (typeof t == "string")
1141
+ return t;
1142
+ if (this._language in t && t[this._language])
1143
+ return t[this._language];
1144
+ for (const i in t)
1145
+ if (t[i])
1146
+ return t[i];
1147
+ return "";
1148
+ }
1149
+ }
1150
+ const vt = 4, ft = [0, 16, 32, 48], bt = {
1151
+ name: "QiApartmentChooser",
1152
+ components: {
1153
+ QiApartmentChooserRaster: ie,
1154
+ QiApartmentChooserSvg: ne,
1155
+ QiApartmentChooserNavigation: Se,
1156
+ QiApartmentChooserRotator: Ae,
1157
+ QiFloatingCard: J,
1158
+ QiHoverProbe: N,
1159
+ QiZoomBox: G
1160
+ },
1161
+ provide() {
1162
+ return {
1163
+ i18n: this.i18n ? new U(this.i18n.labels, this.i18n.language) : new U()
1164
+ };
1165
+ },
1166
+ emits: [
1167
+ "select-unit",
1168
+ "go-to-unit",
1169
+ "nav-unit",
1170
+ "hover-over-unit",
1171
+ "hover-out-unit",
1172
+ "initialized"
1173
+ ],
1343
1174
  props: {
1175
+ i18n: { type: Object, default: void 0 },
1176
+ showCards: { type: Boolean, default: !0 },
1177
+ build: { type: String, default: "" },
1178
+ buildingSceneDataResolver: { type: Function, default: null },
1179
+ buildingScenesByApartmentResolver: { type: Function, default: null },
1344
1180
  cdnFileResolver: { type: Function, required: !0 },
1345
- viewModel: { type: Object, required: !0 },
1346
- selectedUnitId: { type: String, default: null },
1347
- unitCallback: { type: Function, default: (e) => e },
1348
- canGoToUnitCallback: { type: Function, default: () => !0 },
1349
- sceneData: { type: Array, default: [] },
1350
1181
  colorCallback: {
1351
1182
  type: Function,
1352
1183
  default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
1353
1184
  },
1185
+ unitCallback: { type: Function, default: (e) => e },
1186
+ canGoToUnitCallback: { type: Function, default: () => !0 },
1187
+ selectedUnitId: { type: String, default: null },
1188
+ nextUnit: { type: Object, default: null },
1189
+ prevUnit: { type: Object, default: null },
1354
1190
  drawObserver: {
1355
1191
  type: [Object, Array, String, Number, Boolean],
1356
1192
  default: null
1357
- }
1193
+ },
1194
+ interactiveDesktop: { type: Boolean, default: !0 },
1195
+ interactiveMobile: { type: Boolean, default: !0 },
1196
+ useSvg: { type: Boolean, default: !1 }
1358
1197
  },
1359
- emits: ["select-unit", "go-to-unit", "hover-over", "hover-out"],
1360
1198
  data() {
1361
1199
  return {
1362
- pos: { x: 0, y: 0, width: 0, height: 0 },
1363
- canvas: null,
1364
- canvasBg: null,
1365
- canvasWidth: 0,
1366
- canvasHeight: 0,
1367
- context: null,
1368
- contextBg: null,
1369
- image: null,
1370
- imageData: null,
1371
- originalImageData: null,
1372
- hoverApartmentIndex: -1,
1373
- showApartmentCard: !1,
1374
- cursorX: null,
1375
- cursorY: null,
1376
- rasterImages: {},
1377
- vueCanvasCursor: "auto",
1378
- timeout: null,
1379
- windowListener: void 0,
1200
+ loadState: { isReady: !1, isError: !1, progress: void 0 },
1201
+ scenesByApartment: null,
1202
+ sceneData: null,
1203
+ scenes: null,
1204
+ viewModel: void 0,
1380
1205
  resourceLoader: new H(),
1381
- apartmentIndexRasterMap: {}
1206
+ pos: { x: 0, y: 0, width: 0, height: 0 },
1207
+ closeHandler: void 0,
1208
+ hoverApartment: void 0
1382
1209
  };
1383
1210
  },
1384
1211
  computed: {
1385
1212
  isHoverable() {
1386
1213
  return this.$refs.hoverProbe.isHoverEnabled;
1387
1214
  },
1388
- rasterUrl() {
1389
- return this.cdnFileResolver(
1390
- `/scenedata${this.viewModel.currentScene}.png`
1391
- );
1392
- },
1393
- rasterImage() {
1394
- return this.rasterUrl in this.rasterImages ? this.rasterImages[this.rasterUrl] : null;
1395
- },
1396
- hoverApartment() {
1397
- if (this.hoverApartmentIndex < 0)
1398
- return !1;
1399
- const e = this.sceneData.find(
1400
- (t) => t.index === this.hoverApartmentIndex
1401
- );
1402
- return e ? this.unitCallback ? this.unitCallback(e.apartmentId) : e.apartmentId : !1;
1403
- },
1404
- canvasStyle() {
1405
- return {
1406
- width: this.canvasWidth + "px",
1407
- height: this.canvasHeight + "px",
1408
- cursor: this.vueCanvasCursor
1409
- };
1215
+ selectedUnit() {
1216
+ return this.unitCallback ? this.unitCallback(this.selectedUnitId) : this.selectedUnitId;
1410
1217
  },
1411
- hoverBehaviourIdentifier() {
1412
- return `hover-${this.showApartmentCard ? "over" : "out"}-${this.hoverApartment ? typeof this.hoverApartment == "object" && "unitId" in this.hoverApartment ? this.hoverApartment.unitId : this.hoverApartment : ""}`;
1218
+ overlayComponent() {
1219
+ return this.useSvg ? ne : ie;
1413
1220
  }
1414
1221
  },
1415
1222
  watch: {
1416
- rasterUrl: {
1417
- handler() {
1418
- this.rasterImages[this.rasterUrl] || this.resourceLoader.loadImageData(this.rasterUrl).then((e) => {
1419
- this.rasterImages = {
1420
- ...this.rasterImages,
1421
- [this.rasterUrl]: e
1422
- };
1423
- });
1424
- },
1425
- immediate: !0
1426
- },
1427
- rasterImage() {
1428
- this.rasterImage && this.init();
1429
- },
1430
- "viewModel.currentScene": {
1223
+ selectedUnitId: {
1431
1224
  handler() {
1432
- this.draw();
1225
+ if (this.selectedUnitId && this.viewModel) {
1226
+ const e = this.scenesByApartment[this.selectedUnitId];
1227
+ e && (this.viewModel.currentScene = e);
1228
+ }
1433
1229
  },
1434
1230
  immediate: !0
1435
- },
1436
- "viewModel.isRotating"() {
1437
- this.draw();
1438
- },
1439
- drawObserver() {
1440
- this.draw();
1441
- },
1442
- selectedUnitId() {
1443
- this.draw();
1444
- },
1445
- hoverApartment() {
1446
- this.draw(), this.hoverApartment ? this.vueCanvasCursor = "pointer" : this.vueCanvasCursor = "auto";
1447
- },
1448
- hoverBehaviourIdentifier() {
1449
- this.$emit(this.showApartmentCard ? "hover-over" : "hover-out", {
1450
- hoverApartment: this.hoverApartment,
1451
- closeHandler: () => this.closeDialog()
1452
- });
1453
- },
1454
- pos() {
1455
- this.$emit("pos", this.pos);
1456
1231
  }
1457
1232
  },
1458
- mounted() {
1459
- this.windowListener = () => {
1460
- clearTimeout(this.timeout), this.updateCanvasSize(), this.timeout = setTimeout(() => {
1461
- this.updateCanvasSize();
1462
- }, 50);
1463
- }, window.addEventListener("resize", this.windowListener), this.updateCanvasSize();
1464
- },
1465
- beforeUnmount() {
1466
- window.removeEventListener("resize", this.windowListener);
1467
- for (const e in this.rasterImages)
1468
- URL.revokeObjectURL(this.rasterImages[e]);
1469
- },
1470
- methods: {
1471
- init() {
1472
- this.canvas = this.$refs.canvasMask, this.context = this.canvas.getContext("2d", { willReadFrequently: !0 }), this.image = new Image(), this.image.onload = () => {
1473
- this.setupDraw(), this.canvas.addEventListener(
1474
- "mousemove",
1475
- this.throttle(this.handleMouseMove, 50)
1476
- );
1477
- }, this.image.src = this.rasterImage;
1478
- },
1479
- handleMouseMove(e) {
1480
- const t = this.getApartmentIndexByCursorPosition(
1481
- e.offsetX,
1482
- e.offsetY
1483
- );
1484
- this.showApartmentCard = t >= 0, this.hoverApartmentIndex = t, this.pos = {
1485
- x: e.offsetX,
1486
- y: e.offsetY,
1487
- width: this.canvasWidth,
1488
- height: this.canvasHeight
1489
- };
1490
- },
1491
- clickCanvas(e) {
1492
- const t = this.getApartmentIndexByCursorPosition(
1493
- e.offsetX,
1494
- e.offsetY
1233
+ async mounted() {
1234
+ let e = null;
1235
+ try {
1236
+ e = await this.resourceLoader.loadJson(
1237
+ this.cdnFileResolver("/apartmentChooser.json")
1495
1238
  );
1496
- t < 0 || this.isHoverable && this.goToApartmentByIndex(t);
1497
- },
1498
- setImageData() {
1499
- if (this.image && this.image.width) {
1500
- this.canvas.width = this.image.width, this.canvas.height = this.image.height, this.context.drawImage(
1501
- this.image,
1502
- 0,
1503
- 0,
1504
- this.image.width,
1505
- this.image.height
1506
- ), this.originalImageData = this.context.getImageData(
1507
- 0,
1508
- 0,
1509
- this.canvas.width,
1510
- this.canvas.height
1511
- ), this.imageData = this.context.getImageData(
1512
- 0,
1513
- 0,
1514
- this.canvas.width,
1515
- this.canvas.height
1516
- );
1517
- const e = this.originalImageData.data;
1518
- this.apartmentIndexRasterMap = {};
1519
- for (let t = 0; t < e.length; t += 4)
1520
- this.apartmentIndexRasterMap[e[t]] = [];
1521
- for (let t = 3; t < e.length; t += 4)
1522
- e[t] === 255 && e[t - 3] in this.apartmentIndexRasterMap && this.apartmentIndexRasterMap[e[t - 3]].push(t - 3);
1523
- }
1524
- },
1525
- getApartmentIndexByCursorPosition(e, t) {
1526
- this.cursorX = e, this.cursorY = t;
1527
- const i = this.canvas.offsetWidth / this.canvas.width, r = this.canvas.offsetHeight / this.canvas.height, n = (e / i).toFixed(), a = (t / r).toFixed() * (this.canvas.width * 4) + n * 4, d = this.originalImageData.data[a];
1528
- return this.originalImageData.data[a + 3] > 0 ? d : -1;
1529
- },
1530
- getApartmentIndexById(e) {
1531
- const t = this.sceneData.find((i) => i.apartmentId === e);
1532
- return t ? t.index : -1;
1533
- },
1534
- highlightApartments() {
1535
- this.getApartmentsInRaster().forEach((t) => {
1536
- if (t.index >= 0) {
1537
- const i = this.getApartmentPixelsByIndex(t.index), r = this.getApartmentIdByIndex(t.index);
1538
- let n = "idle";
1539
- !this.hoverApartment && this.selectedUnitId && r === this.selectedUnitId ? n = "selected" : this.hoverApartment && this.hoverApartmentIndex === t.index && (n = "hover");
1540
- const s = this.unitCallback ? this.unitCallback(r) : r;
1541
- if (s) {
1542
- const a = this.colorCallback(s, n);
1543
- if (a)
1544
- for (let d = 0; d < i.length; d++)
1545
- this.imageData.data[i[d]] = a.r, this.imageData.data[i[d] + 1] = a.g, this.imageData.data[i[d] + 2] = a.b, this.imageData.data[i[d] + 3] = a.a;
1546
- }
1547
- }
1548
- });
1549
- },
1550
- // GETTING APARTMENT DATA
1551
- // Returns the index of each RGBA value of a given apartment
1552
- getApartmentPixelsByIndex(e) {
1553
- return this.originalImageData ? this.apartmentIndexRasterMap[e] : !1;
1554
- },
1555
- getApartmentIdByIndex(e) {
1556
- const t = this.sceneData.find((i) => i.index === e);
1557
- return t && t.apartmentId;
1558
- },
1559
- getApartmentsInRaster() {
1560
- if (this.originalImageData) {
1561
- const e = Object.keys(this.apartmentIndexRasterMap).map(
1562
- (i) => parseInt(i)
1563
- );
1564
- return this.sceneData.filter(
1565
- (i) => e.includes(i.index)
1239
+ } catch {
1240
+ console.info("apartmentChooser.json not found");
1241
+ }
1242
+ const t = e && e.startScene !== void 0 ? e.startScene : vt;
1243
+ this.scenes = e && e.scenes !== void 0 ? e.scenes : ft, this.sceneData = e && e.sceneData !== void 0 ? e.sceneData.map((n) => ({
1244
+ apartmentId: n.apartmentID,
1245
+ index: n.index
1246
+ })) : this.buildingSceneDataResolver ? await this.buildingSceneDataResolver() : [], this.scenesByApartment = e && e.sceneData !== void 0 ? e.sceneData.map((n) => {
1247
+ const s = n.bestScene === 0 ? 4 : n.bestScene;
1248
+ return { unitId: n.apartmentID, scene: s };
1249
+ }).reduce((n, s) => ({ ...n, [s.unitId]: s.scene }), {}) : this.buildingScenesByApartmentResolver ? await this.buildingScenesByApartmentResolver() : [];
1250
+ const i = (n, s = "unitId") => {
1251
+ let a = t, d = [];
1252
+ for (let p = 0; p < ce; p++)
1253
+ d.push(a), a = Le(a);
1254
+ return n.sort((p, v) => {
1255
+ const w = d.findIndex(
1256
+ (g) => g === this.scenesByApartment[p[s]]
1257
+ ), S = d.findIndex(
1258
+ (g) => g === this.scenesByApartment[v[s]]
1566
1259
  );
1567
- } else
1568
- return [];
1260
+ return w < S ? -1 : w > S ? 1 : 0;
1261
+ }), n;
1262
+ }, r = (n) => {
1263
+ this.viewModel = new pt(n);
1264
+ };
1265
+ this.$emit("initialized", {
1266
+ scene: t,
1267
+ scenes: this.scenes,
1268
+ sceneData: this.sceneData,
1269
+ scenesByApartment: this.scenesByApartment,
1270
+ unitsSceneSort: i,
1271
+ initialize: r
1272
+ });
1273
+ },
1274
+ methods: {
1275
+ onPos(e) {
1276
+ this.pos = e;
1569
1277
  },
1570
- goToApartmentByIndex(e) {
1571
- const t = this.getApartmentIdByIndex(e);
1572
- this.goToApartmentById(t);
1278
+ hoverOver({ hoverApartment: e, closeHandler: t }) {
1279
+ this.hoverApartment = e, this.closeHandler = t, this.$emit("hover-over-unit", e);
1573
1280
  },
1574
- goToApartmentById(e) {
1575
- const t = this.unitCallback ? this.unitCallback(e) : e;
1576
- this.$emit("select-unit", t), t && this.canGoToUnitCallback(t) && this.$emit("go-to-unit", t);
1281
+ hoverOut({ hoverApartment: e, closeHandler: t }) {
1282
+ this.hoverApartment = null, this.closeHandler = t, this.$emit("hover-out-unit", e);
1283
+ }
1284
+ }
1285
+ }, yt = { key: 0 }, wt = { class: "interactive-viewer" }, kt = { class: "fill-parent" }, Ct = { key: 0 }, _t = {
1286
+ key: 1,
1287
+ class: "navigation"
1288
+ }, It = { key: 2 };
1289
+ function St(e, t, i, r, n, s) {
1290
+ const a = c("qi-apartment-chooser-rotator"), d = c("qi-zoom-box"), p = c("qi-floating-card"), v = c("qi-apartment-chooser-navigation"), w = c("v-progress-linear"), S = c("qi-hover-probe");
1291
+ return n.viewModel ? (l(), m("div", yt, [
1292
+ o("div", wt, [
1293
+ o("div", kt, [
1294
+ u(d, {
1295
+ desktop: n.loadState.isReady && i.interactiveDesktop,
1296
+ mobile: n.loadState.isReady && i.interactiveMobile
1297
+ }, {
1298
+ default: h(() => [
1299
+ u(a, {
1300
+ "cdn-file-resolver": i.cdnFileResolver,
1301
+ "view-model": n.viewModel,
1302
+ "cardinal-frames": n.scenes,
1303
+ build: i.build,
1304
+ onProgress: t[0] || (t[0] = (g) => n.loadState.progress = g),
1305
+ onLoaded: t[1] || (t[1] = (g) => n.loadState.isReady = !0),
1306
+ onError: t[2] || (t[2] = (g) => n.loadState.isError = !0)
1307
+ }, null, 8, ["cdn-file-resolver", "view-model", "cardinal-frames", "build"]),
1308
+ n.loadState.isReady ? (l(), m("div", Ct, [
1309
+ (l(), y(be(s.overlayComponent), {
1310
+ "cdn-file-resolver": i.cdnFileResolver,
1311
+ "view-model": n.viewModel,
1312
+ "selected-unit-id": i.selectedUnitId,
1313
+ "scene-data": n.sceneData,
1314
+ "color-callback": i.colorCallback,
1315
+ "unit-callback": i.unitCallback,
1316
+ "can-go-to-unit-callback": i.canGoToUnitCallback,
1317
+ "draw-observer": i.drawObserver,
1318
+ onSelectUnit: t[3] || (t[3] = (g) => e.$emit("select-unit", g)),
1319
+ onGoToUnit: t[4] || (t[4] = (g) => e.$emit("go-to-unit", g)),
1320
+ onHoverOver: s.hoverOver,
1321
+ onHoverOut: s.hoverOut,
1322
+ onPos: s.onPos
1323
+ }, {
1324
+ default: h((g) => [
1325
+ A(e.$slots, "default", ye(we(g)), void 0, !0)
1326
+ ]),
1327
+ _: 3
1328
+ }, 40, ["cdn-file-resolver", "view-model", "selected-unit-id", "scene-data", "color-callback", "unit-callback", "can-go-to-unit-callback", "draw-observer", "onHoverOver", "onHoverOut", "onPos"]))
1329
+ ])) : f("", !0)
1330
+ ]),
1331
+ _: 3
1332
+ }, 8, ["desktop", "mobile"]),
1333
+ n.hoverApartment && i.showCards ? (l(), y(p, {
1334
+ key: 0,
1335
+ "is-hoverable": s.isHoverable,
1336
+ pos: n.pos,
1337
+ onOutside: n.closeHandler
1338
+ }, {
1339
+ default: h(() => [
1340
+ A(e.$slots, "default", {
1341
+ unit: n.hoverApartment,
1342
+ canGoToUnit: i.canGoToUnitCallback(n.hoverApartment),
1343
+ goToUnit: () => i.canGoToUnitCallback(n.hoverApartment) && e.$emit("go-to-unit", n.hoverApartment),
1344
+ pos: n.pos,
1345
+ isHoverable: s.isHoverable,
1346
+ close: n.closeHandler
1347
+ }, void 0, !0)
1348
+ ]),
1349
+ _: 3
1350
+ }, 8, ["is-hoverable", "pos", "onOutside"])) : f("", !0),
1351
+ n.loadState.isReady ? (l(), m("div", _t, [
1352
+ u(v, {
1353
+ "can-go-to-unit-callback": i.canGoToUnitCallback,
1354
+ "selected-unit": s.selectedUnit,
1355
+ "prev-unit": i.prevUnit,
1356
+ "next-unit": i.nextUnit,
1357
+ "view-model": n.viewModel,
1358
+ onGoToUnit: t[5] || (t[5] = (g) => e.$emit("go-to-unit", g)),
1359
+ onPrevUnit: t[6] || (t[6] = (g) => e.$emit("nav-unit", i.prevUnit)),
1360
+ onNextUnit: t[7] || (t[7] = (g) => e.$emit("nav-unit", i.nextUnit))
1361
+ }, null, 8, ["can-go-to-unit-callback", "selected-unit", "prev-unit", "next-unit", "view-model"])
1362
+ ])) : n.loadState.isError ? f("", !0) : (l(), m("div", It, [
1363
+ u(w, {
1364
+ indeterminate: !n.loadState.progress,
1365
+ value: n.loadState.progress
1366
+ }, null, 8, ["indeterminate", "value"])
1367
+ ]))
1368
+ ])
1369
+ ]),
1370
+ u(S, { ref: "hoverProbe" }, null, 512)
1371
+ ])) : f("", !0);
1372
+ }
1373
+ const At = /* @__PURE__ */ C(bt, [["render", St], ["__scopeId", "data-v-3a1121f3"]]), Lt = "data:image/png;base64,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", Mt = {
1374
+ name: "QiNorthDirection",
1375
+ props: {
1376
+ longitude: { type: Number, default: () => 0 }
1377
+ },
1378
+ data() {
1379
+ return {
1380
+ compassNeedle: Lt
1381
+ };
1382
+ },
1383
+ computed: {
1384
+ needleRotation() {
1385
+ return {
1386
+ transform: `rotate(${90 - this.longitude}deg)`,
1387
+ transition: " transform 0.5s ease-in"
1388
+ };
1389
+ }
1390
+ }
1391
+ };
1392
+ function xt(e, t, i, r, n, s) {
1393
+ const a = c("v-img");
1394
+ return l(), y(a, {
1395
+ src: n.compassNeedle,
1396
+ style: M(s.needleRotation)
1397
+ }, null, 8, ["src", "style"]);
1398
+ }
1399
+ const X = /* @__PURE__ */ C(Mt, [["render", xt]]);
1400
+ function ee(e) {
1401
+ return e.toLocaleString("en-no", {
1402
+ month: "short",
1403
+ day: "numeric"
1404
+ });
1405
+ }
1406
+ const Bt = W({
1407
+ setup() {
1408
+ },
1409
+ name: "QiBuildingChooserSunSimControl",
1410
+ props: {
1411
+ modelValue: { type: Number, required: !0 },
1412
+ dateSelector: { type: Object, required: !0 },
1413
+ isLoading: { type: Boolean, default: !1 }
1414
+ },
1415
+ emits: ["update:modelValue"],
1416
+ data() {
1417
+ return {
1418
+ currentValue: this.modelValue,
1419
+ currentDate: null
1420
+ };
1421
+ },
1422
+ computed: {
1423
+ currentValueString() {
1424
+ const e = Math.floor(this.currentValue / 2).toString().padStart(2, "0"), t = this.currentValue % 2 === 0 ? "00" : "30";
1425
+ return `${e}:${t}`;
1577
1426
  },
1578
- setAlpha(e = 0) {
1579
- if (!this.imageData)
1580
- return;
1581
- const t = this.imageData.data;
1582
- for (let i = 3; i < t.length; i += 4)
1583
- t[i] = e;
1427
+ dates() {
1428
+ return this.dateSelector.dates.map(ee);
1584
1429
  },
1585
- updateCanvasSize() {
1586
- if (!this.$el)
1587
- return !1;
1588
- this.canvasWidth = this.$el.offsetWidth, this.canvasHeight = this.$el.offsetHeight;
1430
+ selectedDate: {
1431
+ get() {
1432
+ return ee(this.dateSelector.selectedDate);
1433
+ },
1434
+ set(e) {
1435
+ this.dateSelector.selectIndex(this.dates.indexOf(e));
1436
+ }
1437
+ }
1438
+ },
1439
+ watch: {
1440
+ currentValue(e) {
1441
+ this.$emit("update:modelValue", e);
1589
1442
  },
1590
- setupDraw() {
1591
- this.setImageData(), this.draw();
1443
+ modelValue(e) {
1444
+ this.currentValue = Math.floor(e);
1592
1445
  },
1593
- draw() {
1594
- this.setAlpha(), this.highlightApartments(), this.context && this.imageData && this.context.putImageData(this.imageData, 0, 0);
1446
+ dates: {
1447
+ handler(e) {
1448
+ this.currentDate = ee(this.dateSelector.selectedDate);
1449
+ },
1450
+ immediate: !0
1595
1451
  },
1596
- closeDialog() {
1597
- this.showApartmentCard = !1;
1452
+ currentDate(e) {
1453
+ this.dateSelector.selectIndex(this.dates.indexOf(e));
1598
1454
  }
1599
- }
1600
- }, St = { id: "canvas" };
1601
- function At(e, t, i, r, n, s) {
1602
- const a = c("qi-hover-probe");
1603
- return l(), m("div", St, [
1604
- x(o("canvas", {
1605
- id: "canvas-mask",
1606
- ref: "canvasMask",
1607
- style: M(s.canvasStyle),
1608
- onClick: t[0] || (t[0] = (...d) => s.clickCanvas && s.clickCanvas(...d))
1609
- }, null, 4), [
1610
- [B, !i.viewModel.isRotating]
1455
+ },
1456
+ methods: {}
1457
+ }), Ft = { class: "sunsim-bar-wrapper" }, Et = { class: "sunsim-date d-flex align-center pl-5 pr-5" }, Dt = {
1458
+ key: 1,
1459
+ class: "text-center text-body-1"
1460
+ }, Ot = { class: "sunsim-wrapper d-flex align-center px-3" }, Rt = { class: "sunsim-time-label text-body-1 font-weight-normal ml-2" };
1461
+ function Ut(e, t, i, r, n, s) {
1462
+ const a = c("v-icon"), d = c("v-select"), p = c("v-progress-linear"), v = c("v-slider");
1463
+ return l(), m("div", Ft, [
1464
+ o("div", Et, [
1465
+ u(a, {
1466
+ color: "black",
1467
+ class: "mr-2",
1468
+ icon: "mdi-calendar-blank-outline"
1469
+ }),
1470
+ e.dateSelector.hasMultipleDates ? (l(), y(d, {
1471
+ key: 0,
1472
+ modelValue: e.currentDate,
1473
+ "onUpdate:modelValue": t[0] || (t[0] = (w) => e.currentDate = w),
1474
+ items: e.dates,
1475
+ density: "compact",
1476
+ variant: "underlined",
1477
+ "hide-details": "",
1478
+ class: "day-selector"
1479
+ }, null, 8, ["modelValue", "items"])) : (l(), m("span", Dt, _(e.selectedDate), 1))
1611
1480
  ]),
1612
- u(a, { ref: "hoverProbe" }, null, 512)
1481
+ o("div", Ot, [
1482
+ o("span", Rt, _(e.currentValueString), 1),
1483
+ u(a, {
1484
+ medium: "",
1485
+ class: "ml-2 mr-2 icon"
1486
+ }, {
1487
+ default: h(() => [
1488
+ L("mdi-white-balance-sunny")
1489
+ ]),
1490
+ _: 1
1491
+ }),
1492
+ e.isLoading ? (l(), y(p, {
1493
+ key: 0,
1494
+ indeterminate: "",
1495
+ rounded: "",
1496
+ height: "6",
1497
+ color: "grey lighten-1",
1498
+ class: "mr-2"
1499
+ })) : (l(), y(v, {
1500
+ key: 1,
1501
+ modelValue: e.currentValue,
1502
+ "onUpdate:modelValue": t[1] || (t[1] = (w) => e.currentValue = w),
1503
+ min: 0,
1504
+ max: 47,
1505
+ step: 1,
1506
+ "thumb-label": !1,
1507
+ "hide-details": !0,
1508
+ "thumb-color": "white",
1509
+ "thumb-size": "25",
1510
+ "track-size": "7",
1511
+ "track-fill-color": "transparent",
1512
+ class: "sunsim-slider mr-1"
1513
+ }, null, 8, ["modelValue"]))
1514
+ ])
1613
1515
  ]);
1614
1516
  }
1615
- const ce = /* @__PURE__ */ C(It, [["render", At], ["__scopeId", "data-v-3bbbc77b"]]), Lt = {
1616
- name: "QiApartmentChooserSvg",
1617
- components: { QiHoverProbe: Q },
1618
- mixins: [Se],
1517
+ const ue = /* @__PURE__ */ C(Bt, [["render", Ut], ["__scopeId", "data-v-1fba3edd"]]), Tt = W({
1518
+ setup() {
1519
+ },
1520
+ name: "QiBuildingChooserSceneImageStack",
1521
+ props: {
1522
+ imageUrls: { type: Array, required: !0 },
1523
+ activeIndex: { type: Number, required: !0 }
1524
+ },
1525
+ emits: ["resize", "ready", "preloaded", "reset"],
1526
+ data() {
1527
+ return {
1528
+ state: "init",
1529
+ activeStates: ["preloaded", "loaded"],
1530
+ loadTracker: new se(0)
1531
+ };
1532
+ },
1533
+ watch: {
1534
+ imageUrls(e) {
1535
+ this.$emit("reset"), this.loadImages(e);
1536
+ }
1537
+ },
1538
+ mounted() {
1539
+ this.loadImages(this.imageUrls), new ResizeObserver((e) => {
1540
+ window.requestAnimationFrame(() => {
1541
+ const t = e[0].contentRect.width, i = e[0].contentRect.height;
1542
+ this.$emit("resize", { width: t, height: i });
1543
+ });
1544
+ }).observe(this.$refs.baseImage);
1545
+ },
1546
+ methods: {
1547
+ onPreloaded() {
1548
+ this.state = "preloaded", this.$emit("preloaded");
1549
+ },
1550
+ loadImages(e) {
1551
+ this.state = "init", this.$refs.baseImage.src = e[0], this.loadTracker = new se(e.length).onLoadFinished(
1552
+ () => {
1553
+ this.state = "loaded", this.$emit("ready");
1554
+ }
1555
+ );
1556
+ }
1557
+ }
1558
+ }), Vt = { key: 0 }, Ht = ["src"];
1559
+ function Nt(e, t, i, r, n, s) {
1560
+ return l(), m("div", null, [
1561
+ o("img", {
1562
+ ref: "baseImage",
1563
+ class: "image-instance zero",
1564
+ style: { opacity: 1, borderRadius: 50 },
1565
+ onLoad: t[0] || (t[0] = (...a) => e.onPreloaded && e.onPreloaded(...a))
1566
+ }, null, 544),
1567
+ e.state === "preloaded" || e.state === "loaded" ? x((l(), m("div", Vt, [
1568
+ (l(!0), m(R, null, D(e.imageUrls, (a, d) => (l(), m("img", {
1569
+ key: d,
1570
+ class: E({ "image-instance": !0, active: d === e.activeIndex }),
1571
+ src: a,
1572
+ onLoad: t[1] || (t[1] = (p) => e.loadTracker.partLoaded())
1573
+ }, null, 42, Ht))), 128)),
1574
+ L(" Here ")
1575
+ ], 512)), [
1576
+ [B, e.state === "loaded"]
1577
+ ]) : f("", !0)
1578
+ ]);
1579
+ }
1580
+ const he = /* @__PURE__ */ C(Tt, [["render", Nt], ["__scopeId", "data-v-fad48118"]]), jt = "buildingChooser.json", qt = 180;
1581
+ class Me {
1582
+ constructor(t) {
1583
+ this._cdnFileResolver = t, this._resourceLoader = new H();
1584
+ }
1585
+ constructFileUrl(t) {
1586
+ return this._cdnFileResolver ? this._cdnFileResolver(`/${t}`) : null;
1587
+ }
1588
+ loadConfigFile() {
1589
+ const t = this.constructFileUrl(jt);
1590
+ return t ? this._resourceLoader.loadJson(t) : null;
1591
+ }
1592
+ loadBuildingMapImage(t) {
1593
+ const i = this.constructFileUrl(t.lookupFilename);
1594
+ return i ? this._resourceLoader.loadImage(i) : null;
1595
+ }
1596
+ getViewLongitude(t) {
1597
+ return t.cameraRotation && t.cameraRotation.y + 270;
1598
+ }
1599
+ getBuildingData(t) {
1600
+ const i = t ? t.buildings : [], r = i.map((s) => s.id), n = i.map((s) => ({
1601
+ id: s.id,
1602
+ url: this.constructFileUrl(s.overlayFilename)
1603
+ }));
1604
+ return { buildingIds: r, buildingOverlays: n };
1605
+ }
1606
+ getBackgroundImageData(t) {
1607
+ return "days" in t ? this.processMultipleDays(t.days) : [this.processTimeSamples(
1608
+ qt,
1609
+ t.timeSamples
1610
+ )];
1611
+ }
1612
+ processMultipleDays(t) {
1613
+ return t.map(
1614
+ (i) => this.processTimeSamples(i.dayOfYear, i.timeSamples)
1615
+ );
1616
+ }
1617
+ processTimeSamples(t, i) {
1618
+ return {
1619
+ urls: i.map(
1620
+ (n) => this.constructFileUrl(n.filename)
1621
+ ),
1622
+ referenceDate: this.makeReferenceDate(t)
1623
+ };
1624
+ }
1625
+ makeReferenceDate(t) {
1626
+ const i = /* @__PURE__ */ new Date(0);
1627
+ return i.setUTCDate(t), i;
1628
+ }
1629
+ async loadBuildingChooser() {
1630
+ try {
1631
+ const t = await this.loadConfigFile();
1632
+ if (t) {
1633
+ const i = await this.loadBuildingMapImage(t);
1634
+ if (i) {
1635
+ const r = this.getViewLongitude(t), { buildingIds: n, buildingOverlays: s } = this.getBuildingData(t), a = this.getBackgroundImageData(t);
1636
+ return {
1637
+ mapImage: i,
1638
+ viewLongitude: r,
1639
+ buildingIds: n,
1640
+ buildingOverlays: s,
1641
+ backgrounds: a
1642
+ };
1643
+ }
1644
+ }
1645
+ return null;
1646
+ } catch {
1647
+ return null;
1648
+ }
1649
+ }
1650
+ }
1651
+ class Y {
1652
+ static empty() {
1653
+ return new Y([]);
1654
+ }
1655
+ constructor(t) {
1656
+ this._buildingIds = t;
1657
+ }
1658
+ getBuildingId(t, i, r) {
1659
+ const n = this._getBuildingIndex(t, i, r);
1660
+ if (n !== void 0)
1661
+ return this._buildingIds[n];
1662
+ }
1663
+ _getBuildingIndex(t, i, r) {
1664
+ const [n, s, a, d] = t.getPixel(i, r);
1665
+ if (d === 255 && n === s && s === a)
1666
+ return n;
1667
+ }
1668
+ }
1669
+ class Q {
1670
+ static empty() {
1671
+ return new Q(null);
1672
+ }
1673
+ constructor(t) {
1674
+ this._mapImage = t, this._context = null;
1675
+ }
1676
+ update(t) {
1677
+ this._mapImage && (this._context = t.getContext("2d", { willReadFrequently: !0 }), this._context.drawImage(this._mapImage, 0, 0, t.width, t.height));
1678
+ }
1679
+ getPixel(t, i) {
1680
+ try {
1681
+ return this._context ? this._context.getImageData(t, i, 1, 1).data : [0, 0, 0, 0];
1682
+ } catch {
1683
+ return [0, 0, 0, 0];
1684
+ }
1685
+ }
1686
+ }
1687
+ const Pt = /* @__PURE__ */ new Date(0);
1688
+ class Z {
1689
+ static empty() {
1690
+ return new Z([{ referenceDate: Pt, urls: [] }]);
1691
+ }
1692
+ constructor(t) {
1693
+ this._imagesByDay = t, this._state = { selectedIndex: 0 };
1694
+ }
1695
+ selectIndex(t) {
1696
+ t < this._imagesByDay.length && (this._state.selectedIndex = t);
1697
+ }
1698
+ get dates() {
1699
+ return this._imagesByDay.map((t) => t.referenceDate);
1700
+ }
1701
+ get hasMultipleDates() {
1702
+ return this._imagesByDay.length > 1;
1703
+ }
1704
+ get selectedIndex() {
1705
+ return this._state.selectedIndex;
1706
+ }
1707
+ get selectedDate() {
1708
+ return this._imagesByDay[this.selectedIndex].referenceDate;
1709
+ }
1710
+ get imageUrls() {
1711
+ return this._imagesByDay[this.selectedIndex].urls;
1712
+ }
1713
+ }
1714
+ const Yt = W({
1715
+ setup() {
1716
+ ke({});
1717
+ },
1718
+ name: "QiBuildingChooserSvg",
1719
+ components: {
1720
+ QiBuildingChooserSunSimControl: ue,
1721
+ QiBuildingChooserSceneImageStack: he,
1722
+ QiNorthDirection: X,
1723
+ QiFloatingCard: J,
1724
+ QiHoverProbe: N,
1725
+ QiZoomBox: G
1726
+ },
1727
+ emits: ["go-to-building", "hover-over-building", "hover-out-building"],
1728
+ provide() {
1729
+ return {
1730
+ i18n: this.i18n ? new U(this.i18n.labels, this.i18n.language) : new U()
1731
+ };
1732
+ },
1619
1733
  props: {
1620
- cdnFileResolver: { type: Function, required: !0 },
1621
- viewModel: { type: Object, required: !0 },
1622
- selectedUnitId: { type: String, default: null },
1623
- unitCallback: { type: Function, default: (e) => e },
1624
- canGoToUnitCallback: { type: Function, default: () => !0 },
1625
- sceneData: { type: Array, default: [] },
1734
+ showCards: { type: Boolean, default: () => !0 },
1626
1735
  colorCallback: {
1627
1736
  type: Function,
1628
1737
  default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
1629
1738
  },
1630
- drawObserver: {
1631
- type: [Object, Array, String, Number, Boolean],
1632
- default: null
1633
- }
1739
+ buildingCallback: { type: Function, default: (e) => e },
1740
+ canGoToBuildingCallback: { type: Function, default: () => !0 },
1741
+ buildingChooserTimeOfDay: { type: String, default: null },
1742
+ cdnFileResolver: { type: Function, required: !0 },
1743
+ i18n: { type: Object, default: void 0 },
1744
+ interactiveDesktop: { type: Boolean, default: !0 },
1745
+ interactiveMobile: { type: Boolean, default: !0 },
1746
+ customOverlayContent: { type: String, default: "" }
1634
1747
  },
1635
- emits: ["select-unit", "go-to-unit", "hover-over", "hover-out"],
1636
1748
  data() {
1637
1749
  return {
1750
+ sceneState: { preloaded: !1, ready: !1 },
1751
+ canvasDimensions: { width: 0, height: 0 },
1638
1752
  pos: { x: 0, y: 0, width: 0, height: 0 },
1639
- hoverApartmentIndex: -1,
1640
- svgImages: {},
1641
- currentSvgImage: null,
1642
- resourceLoader: new H()
1753
+ pickerData: void 0,
1754
+ hoverBuildingId: void 0,
1755
+ halfHourMark: (/* @__PURE__ */ new Date()).getHours() * 2 + ((/* @__PURE__ */ new Date()).getMinutes() < 30 ? 0 : 1),
1756
+ error: !1,
1757
+ resourceLoader: new H(),
1758
+ svgObjects: void 0,
1759
+ svgViewBox: "0 0 0 0"
1643
1760
  };
1644
1761
  },
1645
1762
  computed: {
1646
1763
  isHoverable() {
1647
1764
  return this.$refs.hoverProbe.isHoverEnabled;
1765
+ },
1766
+ hoverBuilding() {
1767
+ return this.getBuildingData(this.hoverBuildingId);
1648
1768
  }
1649
1769
  },
1650
1770
  watch: {
1651
- "viewModel.currentScene": {
1771
+ buildingChooserTimeOfDay: {
1652
1772
  handler() {
1653
- this.viewModel.currentScene in this.svgImages && (this.currentSvgImage = this.svgImages[this.viewModel.currentScene]);
1773
+ if (this.buildingChooserTimeOfDay) {
1774
+ const [e, t, i] = /^(\d\d):(\d\d)$/.exec(
1775
+ this.buildingChooserTimeOfDay
1776
+ ), r = parseInt(i);
1777
+ this.halfHourMark = parseInt(t) * 2 + (r < 15 ? 0 : r > 45 ? 2 : 1);
1778
+ }
1654
1779
  },
1655
1780
  immediate: !0
1656
1781
  },
1657
- svgImages: {
1658
- handler() {
1659
- this.viewModel.currentScene in this.svgImages && (this.currentSvgImage = this.svgImages[this.viewModel.currentScene]);
1660
- },
1661
- immediate: !0
1782
+ hoverBuildingId(e, t) {
1783
+ e ? this.$emit("hover-over-building", this.getBuildingData(e)) : this.$emit("hover-out-building", this.getBuildingData(t));
1784
+ }
1785
+ },
1786
+ async mounted() {
1787
+ const t = await new Me(
1788
+ this.cdnFileResolver
1789
+ ).loadBuildingChooser();
1790
+ if (t) {
1791
+ this.canvasRaster = new Q(t.mapImage), this.buildingMap = new Y(t.buildingIds), this.daysOfYear = new Z(t.backgrounds), this.pickerData = {
1792
+ buildingOverlays: t.buildingOverlays,
1793
+ sceneLongitude: t.viewLongitude
1794
+ };
1795
+ const i = [];
1796
+ for (let { id: r, url: n } of t.buildingOverlays)
1797
+ this.resourceLoader.loadJson(n.replace(".png", ".svg")).then((s) => {
1798
+ const d = new DOMParser().parseFromString(s, "image/svg+xml").getElementsByTagName("svg")[0];
1799
+ this.svgViewBox = d.getAttribute("viewBox"), i.push({
1800
+ id: r,
1801
+ svg: d.innerHTML
1802
+ });
1803
+ });
1804
+ this.svgObjects = i;
1805
+ } else
1806
+ this.error = !0;
1807
+ },
1808
+ methods: {
1809
+ resizeScene({ width: e, height: t }) {
1810
+ this.canvasDimensions.width = e, this.canvasDimensions.height = t;
1662
1811
  },
1663
- pos() {
1664
- this.$emit("pos", this.pos);
1812
+ sceneReset() {
1813
+ this.sceneState = { preloaded: !1, ready: !1 };
1665
1814
  },
1666
- hoverApartmentIndex(e, t) {
1667
- if (e >= 0) {
1668
- const i = this.getApartmentByIndex(e);
1669
- this.$emit("hover-over", {
1670
- hoverApartment: i,
1671
- closeHandler: () => {
1672
- this.hoverApartmentIndex = -1;
1673
- }
1674
- });
1675
- } else {
1676
- const i = this.getApartmentByIndex(t);
1677
- this.$emit("hover-out", {
1678
- hoverApartment: i,
1679
- closeHandler: () => {
1680
- this.hoverApartmentIndex = -1;
1681
- }
1682
- });
1683
- }
1815
+ getBuildingData(e) {
1816
+ return this.buildingCallback ? this.buildingCallback(e) : e;
1817
+ },
1818
+ getColor(e) {
1819
+ return this.colorCallback(
1820
+ this.getBuildingData(e),
1821
+ e === this.hoverBuildingId ? "hover" : "idle"
1822
+ );
1823
+ },
1824
+ getGClass(e) {
1825
+ const t = this.getBuildingData(e), i = this.colorCallback(
1826
+ t,
1827
+ e === this.hoverBuildingId ? "hover" : "idle"
1828
+ ), r = [];
1829
+ return e === this.hoverBuildingId ? r.push("hover") : r.push("idle"), i && this.canGoToBuildingCallback(t) ? r.push("clickable") : r.push("restricted"), r.join(" ");
1830
+ },
1831
+ getGStyle(e) {
1832
+ const t = this.getBuildingData(e), i = this.colorCallback(
1833
+ t,
1834
+ e === this.hoverBuildingId ? "hover" : "idle"
1835
+ );
1836
+ if (i) {
1837
+ const { r, g: n, b: s, a, s: d } = i;
1838
+ return {
1839
+ strokeWidth: d !== void 0 ? d : 2,
1840
+ stroke: `rgb(${r}, ${n}, ${s})`,
1841
+ strokeOpacity: 1,
1842
+ fill: `rgb(${r}, ${n}, ${s})`,
1843
+ fillOpacity: a / 255,
1844
+ cursor: `${this.canGoToBuildingCallback(t) ? "cursor" : "default"} !important`
1845
+ };
1846
+ } else
1847
+ return {
1848
+ strokeWidth: 0,
1849
+ stroke: "white",
1850
+ strokeOpacity: 0,
1851
+ fill: "white",
1852
+ fillOpacity: 0,
1853
+ cursor: "default !important"
1854
+ };
1855
+ },
1856
+ onBuildingMouseOver(e, t) {
1857
+ this.isHoverable && (this.pos = {
1858
+ x: e.layerX,
1859
+ y: e.layerY,
1860
+ width: this.canvasDimensions.width,
1861
+ height: this.canvasDimensions.height
1862
+ }, this.hoverBuildingId = t, this.$emit("hover-over-building", this.getBuildingData(t)));
1863
+ },
1864
+ onBuildingMouseOut(e, t) {
1865
+ this.isHoverable && (this.pos = {
1866
+ x: e.layerX,
1867
+ y: e.layerY,
1868
+ width: this.canvasDimensions.width,
1869
+ height: this.canvasDimensions.height
1870
+ }, this.hoverBuildingId = void 0, this.$emit("hover-out-building", this.getBuildingData(t)));
1871
+ },
1872
+ onBuildingMouseMove(e) {
1873
+ this.isHoverable && (this.pos = {
1874
+ x: e.layerX,
1875
+ y: e.layerY,
1876
+ width: this.canvasDimensions.width,
1877
+ height: this.canvasDimensions.height
1878
+ });
1879
+ },
1880
+ onBuildingClick(e) {
1881
+ this.hoverBuildingId = e, this.isHoverable && this.hoverBuilding && this.canGoToBuildingCallback(this.hoverBuilding) && this.$emit("go-to-building", this.hoverBuilding);
1882
+ }
1883
+ }
1884
+ }), Qt = {
1885
+ key: 0,
1886
+ style: { height: "50vh" },
1887
+ class: "d-flex justify-center align-center blue-grey lighten-5"
1888
+ }, zt = { class: "image-instances" }, $t = { key: 0 }, Wt = { class: "svg-container" }, Jt = ["viewBox"], Gt = ["innerHTML", "data-building-id", "onMouseover", "onMouseout", "onMousemove", "onClick"], Xt = ["innerHTML"];
1889
+ function Zt(e, t, i, r, n, s) {
1890
+ const a = c("v-icon"), d = c("qi-building-chooser-scene-image-stack"), p = c("qi-zoom-box"), v = c("qi-north-direction"), w = c("qi-building-chooser-sun-sim-control"), S = c("qi-floating-card"), g = c("qi-hover-probe");
1891
+ return e.error ? (l(), m("div", Qt, [
1892
+ u(a, { "x-large": "" }, {
1893
+ default: h(() => [
1894
+ L("mdi-alert-circle-outline")
1895
+ ]),
1896
+ _: 1
1897
+ })
1898
+ ])) : e.pickerData ? (l(), m("div", {
1899
+ key: 1,
1900
+ style: M(`height: ${e.canvasDimensions.height}px; position: relative`),
1901
+ class: "image-container"
1902
+ }, [
1903
+ u(p, {
1904
+ desktop: e.interactiveDesktop,
1905
+ mobile: e.interactiveMobile
1906
+ }, {
1907
+ default: h(() => [
1908
+ o("div", zt, [
1909
+ u(d, {
1910
+ "image-urls": e.daysOfYear.imageUrls,
1911
+ "active-index": e.halfHourMark,
1912
+ onResize: e.resizeScene,
1913
+ onPreloaded: t[0] || (t[0] = (b) => e.sceneState.preloaded = !0),
1914
+ onReady: t[1] || (t[1] = (b) => e.sceneState.ready = !0),
1915
+ onReset: e.sceneReset
1916
+ }, null, 8, ["image-urls", "active-index", "onResize", "onReset"]),
1917
+ e.svgObjects ? x((l(), m("div", $t, [
1918
+ o("div", Wt, [
1919
+ (l(), m("svg", { viewBox: e.svgViewBox }, [
1920
+ (l(!0), m(R, null, D(e.svgObjects, ({ id: b, svg: k }, I) => (l(), m("g", {
1921
+ key: I,
1922
+ innerHTML: k,
1923
+ "data-building-id": b,
1924
+ class: E(e.getGClass(b)),
1925
+ style: M(e.getGStyle(b)),
1926
+ onMouseover: (O) => e.onBuildingMouseOver(O, b),
1927
+ onMouseout: (O) => e.onBuildingMouseOut(O, b),
1928
+ onMousemove: (O) => e.onBuildingMouseMove(O, b),
1929
+ onClick: (O) => e.onBuildingClick(b)
1930
+ }, null, 46, Gt))), 128))
1931
+ ], 8, Jt))
1932
+ ])
1933
+ ], 512)), [
1934
+ [B, e.sceneState.preloaded]
1935
+ ]) : f("", !0),
1936
+ x(o("div", {
1937
+ class: "custom-overlay-layer",
1938
+ innerHTML: e.customOverlayContent
1939
+ }, null, 8, Xt), [
1940
+ [B, e.sceneState.preloaded]
1941
+ ])
1942
+ ])
1943
+ ]),
1944
+ _: 1
1945
+ }, 8, ["desktop", "mobile"]),
1946
+ x(o("div", null, [
1947
+ e.pickerData.sceneLongitude ? (l(), y(v, {
1948
+ key: 0,
1949
+ class: "north-indicator",
1950
+ longitude: e.pickerData.sceneLongitude
1951
+ }, null, 8, ["longitude"])) : f("", !0),
1952
+ u(w, {
1953
+ modelValue: e.halfHourMark,
1954
+ "onUpdate:modelValue": t[2] || (t[2] = (b) => e.halfHourMark = b),
1955
+ "date-selector": e.daysOfYear,
1956
+ "is-loading": !e.sceneState.ready
1957
+ }, null, 8, ["modelValue", "date-selector", "is-loading"])
1958
+ ], 512), [
1959
+ [B, e.sceneState.preloaded]
1960
+ ]),
1961
+ e.showCards && e.hoverBuilding ? (l(), y(S, {
1962
+ key: 0,
1963
+ "is-hoverable": e.isHoverable,
1964
+ pos: e.pos,
1965
+ onOutside: t[3] || (t[3] = () => e.hoverBuildingId = void 0)
1966
+ }, {
1967
+ default: h(() => [
1968
+ A(e.$slots, "default", {
1969
+ building: e.hoverBuilding,
1970
+ canGoToBuilding: e.canGoToBuildingCallback(e.hoverBuilding),
1971
+ goToBuilding: () => e.canGoToBuildingCallback(e.hoverBuilding) && e.$emit("go-to-building", e.hoverBuilding),
1972
+ pos: e.pos,
1973
+ isHoverable: e.isHoverable,
1974
+ close: () => e.hoverBuildingId = void 0
1975
+ }, void 0, !0)
1976
+ ]),
1977
+ _: 3
1978
+ }, 8, ["is-hoverable", "pos"])) : f("", !0),
1979
+ u(g, { ref: "hoverProbe" }, null, 512)
1980
+ ], 4)) : f("", !0);
1981
+ }
1982
+ const oe = /* @__PURE__ */ C(Yt, [["render", Zt], ["__scopeId", "data-v-0a2cec1f"]]), Kt = {
1983
+ name: "QiBuildingChooserRasterOverlay",
1984
+ props: {
1985
+ imageUrl: { type: String, required: !0 },
1986
+ dimensions: { type: Object, required: !0 },
1987
+ color: {
1988
+ type: Object,
1989
+ default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
1684
1990
  }
1685
1991
  },
1686
- mounted() {
1687
- for (let e = 1; e <= 4; e++) {
1688
- const t = this.cdnFileResolver(`/scenedata${e}.svg`), i = {};
1689
- this.resourceLoader.loadJson(t).then((r) => {
1690
- i.markup = r;
1691
- const s = new DOMParser().parseFromString(r, "image/svg+xml").getElementsByTagName("svg")[0];
1692
- i.viewBox = s.getAttribute("viewBox"), i.svgObjects = Array.from(
1693
- s.querySelectorAll("*[data-index]")
1694
- ).map((a) => ({
1695
- index: parseInt(a.getAttribute("data-index")),
1696
- svg: a.innerHTML
1697
- })), this.svgImages = { ...this.svgImages, [e]: i };
1698
- });
1992
+ data() {
1993
+ return {
1994
+ isLoaded: !1,
1995
+ overlayImage: void 0,
1996
+ resourceLoader: new H(),
1997
+ context: void 0,
1998
+ imageData: void 0,
1999
+ imageDataIndices: []
2000
+ };
2001
+ },
2002
+ watch: {
2003
+ color(e, t) {
2004
+ (e.r !== t.r || e.g !== t.g || e.b !== t.b || e.a !== t.a) && this.draw();
1699
2005
  }
1700
- this.$refs.container.addEventListener(
1701
- "mousemove",
1702
- this.throttle(this.handleMouseMove, 50)
1703
- );
2006
+ },
2007
+ async mounted() {
2008
+ this.overlayImage = await this.resourceLoader.loadImage(this.imageUrl), this.setupDraw();
1704
2009
  },
1705
2010
  methods: {
1706
- handleMouseMove(e) {
1707
- this.pos = {
1708
- x: e.offsetX,
1709
- y: e.offsetY,
1710
- width: this.$el.offsetWidth,
1711
- height: this.$el.offsetHeight
1712
- };
1713
- },
1714
- getApartmentIdByIndex(e) {
1715
- var t;
1716
- return (t = this.sceneData.find((i) => i.index === parseInt(e))) == null ? void 0 : t.apartmentId;
1717
- },
1718
- getApartmentByIndex(e) {
1719
- const t = this.getApartmentIdByIndex(e);
1720
- return this.unitCallback ? this.unitCallback(t) : t;
1721
- },
1722
- mouseEnter(e) {
1723
- this.isHoverable && (this.hoverApartmentIndex = e);
1724
- },
1725
- mouseLeave() {
1726
- this.isHoverable && (this.hoverApartmentIndex = -1);
2011
+ setupDraw() {
2012
+ if (!this.overlayImage || !this.$refs.canvas)
2013
+ return;
2014
+ const { width: e, height: t } = this.dimensions;
2015
+ if (!(e === 0 || t === 0)) {
2016
+ this.context = this.$refs.canvas.getContext("2d", {
2017
+ willReadFrequently: !0
2018
+ }), this.context.drawImage(this.overlayImage, 0, 0, e, t), this.imageData = this.context.getImageData(0, 0, e, t);
2019
+ for (let i = 3; i < this.imageData.data.length; i += 4)
2020
+ this.imageData.data[i] !== 0 && this.imageDataIndices.push(i);
2021
+ this.draw(), this.isLoaded = !0;
2022
+ }
1727
2023
  },
1728
- click(e) {
1729
- const t = this.getApartmentByIndex(e);
1730
- this.$emit("select-unit", t), this.isHoverable && t && this.canGoToUnitCallback(t) ? this.$emit("go-to-unit", t) : this.hoverApartmentIndex = e;
2024
+ draw() {
2025
+ this.context && this.imageData && (this.applyColor(), this.context.putImageData(this.imageData, 0, 0));
1731
2026
  },
1732
- getGClass(e) {
1733
- const t = this.getApartmentIdByIndex(e), i = this.getApartmentByIndex(e);
1734
- let r = "idle";
1735
- this.hoverApartmentIndex < 0 && this.selectedUnitId && t === this.selectedUnitId ? r = "selected" : this.hoverApartmentIndex >= 0 && this.hoverApartmentIndex === e && (r = "hover");
1736
- const n = this.colorCallback(i, r);
1737
- if (n) {
1738
- const { r: s, g: a, b: d, a: p, s: v } = n;
1739
- return {
1740
- strokeWidth: v !== void 0 ? v : 2,
1741
- stroke: `rgb(${s}, ${a}, ${d})`,
1742
- strokeOpacity: 1,
1743
- fill: `rgb(${s}, ${a}, ${d})`,
1744
- fillOpacity: p / 255,
1745
- cursor: `${this.canGoToUnitCallback(i) ? "cursor" : "default"} !important`
1746
- };
1747
- } else
1748
- return {
1749
- strokeWidth: 0,
1750
- stroke: "white",
1751
- strokeOpacity: 0,
1752
- fill: "white",
1753
- fillOpacity: 0,
1754
- cursor: "default !important"
1755
- };
2027
+ applyColor() {
2028
+ if (this.color)
2029
+ for (let e = 0; e < this.imageDataIndices.length; e++)
2030
+ this.imageData.data[this.imageDataIndices[e] - 3] = this.color.r, this.imageData.data[this.imageDataIndices[e] - 2] = this.color.g, this.imageData.data[this.imageDataIndices[e] - 1] = this.color.b, this.imageData.data[this.imageDataIndices[e]] = this.color.a;
1756
2031
  }
1757
2032
  }
1758
- }, Mt = {
1759
- id: "container",
1760
- ref: "container"
1761
- }, xt = ["viewBox"], Bt = ["innerHTML", "onMouseenter", "onMouseleave", "onClick"];
1762
- function Ft(e, t, i, r, n, s) {
1763
- const a = c("qi-hover-probe");
1764
- return l(), m("div", Mt, [
1765
- x(o("div", {
1766
- class: "svg-container",
1767
- style: M({
1768
- opacity: !n.currentSvgImage || !n.currentSvgImage.svgObjects ? 0 : 1
1769
- })
1770
- }, [
1771
- n.currentSvgImage && n.currentSvgImage.svgObjects ? (l(), m("svg", {
1772
- key: 0,
1773
- viewBox: n.currentSvgImage.viewBox
1774
- }, [
1775
- (l(!0), m(U, null, D(n.currentSvgImage.svgObjects, ({ index: d, svg: p }) => (l(), m("g", {
1776
- key: d,
1777
- innerHTML: p,
1778
- style: M(s.getGClass(d)),
1779
- onMouseenter: (v) => s.mouseEnter(d),
1780
- onMouseleave: (v) => s.mouseLeave(d),
1781
- onClick: (v) => s.click(d)
1782
- }, null, 44, Bt))), 128))
1783
- ], 8, xt)) : f("", !0)
1784
- ], 4), [
1785
- [B, !i.viewModel.isRotating]
1786
- ]),
1787
- u(a, { ref: "hoverProbe" }, null, 512)
1788
- ], 512);
2033
+ };
2034
+ function ei(e, t, i, r, n, s) {
2035
+ return l(), m("canvas", F({
2036
+ ref: "canvas",
2037
+ class: "overlay"
2038
+ }, i.dimensions), null, 16);
1789
2039
  }
1790
- const ue = /* @__PURE__ */ C(Lt, [["render", Ft], ["__scopeId", "data-v-82a61864"]]), Et = {
1791
- name: "QiApartmentChooserNavigation",
1792
- inject: ["i18n"],
1793
- props: {
1794
- canGoToUnitCallback: { type: Function, default: () => !0 },
1795
- selectedUnit: { type: Object, default: null },
1796
- prevUnit: { type: Object, default: null },
1797
- nextUnit: { type: Object, default: null },
1798
- viewModel: { type: Object, required: !0 }
2040
+ const xe = /* @__PURE__ */ C(Kt, [["render", ei], ["__scopeId", "data-v-9a90fa2f"]]), ti = W({
2041
+ setup() {
2042
+ ke({});
1799
2043
  },
1800
- mounted() {
1801
- window.addEventListener("keydown", this.keyNavigate);
2044
+ name: "QiBuildingChooserRaster",
2045
+ components: {
2046
+ QiBuildingChooserRasterOverlay: xe,
2047
+ QiBuildingChooserSunSimControl: ue,
2048
+ QiBuildingChooserSceneImageStack: he,
2049
+ QiNorthDirection: X,
2050
+ QiFloatingCard: J,
2051
+ QiHoverProbe: N,
2052
+ QiZoomBox: G
1802
2053
  },
1803
- beforeUnmount() {
1804
- window.removeEventListener("keydown", this.keyNavigate);
2054
+ emits: ["go-to-building", "hover-over-building", "hover-out-building"],
2055
+ provide() {
2056
+ return {
2057
+ i18n: this.i18n ? new U(this.i18n.labels, this.i18n.language) : new U()
2058
+ };
1805
2059
  },
1806
- methods: {
1807
- keyNavigate(e) {
1808
- e.keyCode === 37 ? this.prevUnit && this.$emit("prev-unit") : e.keyCode === 39 && this.nextUnit && this.$emit("next-unit");
1809
- }
1810
- }
1811
- }, Dt = {
1812
- key: 0,
1813
- class: "d-none d-md-flex"
1814
- };
1815
- function Ot(e, t, i, r, n, s) {
1816
- const a = c("v-btn");
1817
- return l(), m("div", null, [
1818
- u(a, {
1819
- elevation: "1",
1820
- icon: "mdi-rotate-right",
1821
- class: "black darken-1",
1822
- onClick: t[0] || (t[0] = (d) => i.viewModel.rotateClockwise())
1823
- }),
1824
- u(a, {
1825
- elevation: "1",
1826
- plain: "",
1827
- icon: "mdi-chevron-left",
1828
- class: "mr-sm-4 ml-sm-8 mr-3 ml-3 black darken-1",
1829
- disabled: !i.prevUnit,
1830
- onClick: t[1] || (t[1] = (d) => e.$emit("prev-unit"))
1831
- }, null, 8, ["disabled"]),
1832
- u(a, {
1833
- color: "success darken-2",
1834
- elevation: "1",
1835
- rounded: "",
1836
- plain: "",
1837
- disabled: !i.selectedUnit || !i.canGoToUnitCallback(i.selectedUnit),
1838
- onClick: t[2] || (t[2] = (d) => e.$emit("go-to-unit", i.selectedUnit))
1839
- }, {
1840
- default: h(() => [
1841
- i.selectedUnit && i.canGoToUnitCallback(i.selectedUnit) ? (l(), m("span", Dt, _(s.i18n.getLabel("see-apartment")) + "  ", 1)) : f("", !0),
1842
- o("span", null, _(i.selectedUnit && "title" in i.selectedUnit ? i.selectedUnit.title : "-"), 1)
1843
- ]),
1844
- _: 1
1845
- }, 8, ["disabled"]),
1846
- u(a, {
1847
- elevation: "1",
1848
- plain: "",
1849
- icon: "mdi-chevron-right",
1850
- class: "mr-sm-8 ml-sm-4 mr-3 ml-3 black darken-1",
1851
- disabled: !i.nextUnit,
1852
- onClick: t[3] || (t[3] = (d) => e.$emit("next-unit"))
1853
- }, null, 8, ["disabled"]),
1854
- u(a, {
1855
- elevation: "1",
1856
- plain: "",
1857
- icon: "mdi-rotate-left",
1858
- class: "black darken-1",
1859
- onClick: t[4] || (t[4] = (d) => i.viewModel.rotateCounterClockwise())
1860
- })
1861
- ]);
1862
- }
1863
- const Ut = /* @__PURE__ */ C(Et, [["render", Ot], ["__scopeId", "data-v-129ef905"]]);
1864
- class oe {
1865
- constructor(t, i, r, n) {
1866
- this._rotator = t, this._direction = i, this._frameIndex = r, this._sceneCount = n;
1867
- }
1868
- get atEnd() {
1869
- return this._sceneCount === 0;
1870
- }
1871
- get frameIndex() {
1872
- return this._frameIndex;
1873
- }
1874
- nextFrame() {
1875
- const t = this._rotator.clampFrameIndex(
1876
- this._frameIndex + this._direction
1877
- ), i = this._rotator.isCardinalFrame(t) ? this._sceneCount - 1 : this._sceneCount;
1878
- return new oe(
1879
- this._rotator,
1880
- this._direction,
1881
- t,
1882
- i
1883
- );
1884
- }
1885
- }
1886
- class Rt {
1887
- constructor(t, i) {
1888
- this._cardinalFrames = t, this._totalFrameCount = i;
1889
- }
1890
- start(t, i, r) {
1891
- const n = this.startFrameIndexForScene(i);
1892
- return new oe(this, t, n, r);
1893
- }
1894
- isCardinalFrame(t) {
1895
- return this._cardinalFrames.includes(t);
1896
- }
1897
- clampFrameIndex(t) {
1898
- return (this._totalFrameCount + t) % this._totalFrameCount;
1899
- }
1900
- startFrameIndexForScene(t) {
1901
- return this._cardinalFrames[t];
1902
- }
1903
- }
1904
- const he = 64, j = 4, Tt = 120, Vt = {
1905
- name: "QiApartmentChooserRotator",
1906
2060
  props: {
1907
- viewModel: { type: Object, required: !0 },
1908
- build: { type: String, default: "" },
2061
+ showCards: { type: Boolean, default: () => !0 },
2062
+ colorCallback: {
2063
+ type: Function,
2064
+ default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
2065
+ },
2066
+ buildingCallback: { type: Function, default: (e) => e },
2067
+ canGoToBuildingCallback: { type: Function, default: () => !0 },
2068
+ buildingChooserTimeOfDay: { type: String, default: null },
1909
2069
  cdnFileResolver: { type: Function, required: !0 },
1910
- cardinalFrames: { type: Array, required: !0 }
2070
+ i18n: { type: Object, default: void 0 },
2071
+ interactiveDesktop: { type: Boolean, default: !0 },
2072
+ interactiveMobile: { type: Boolean, default: !0 },
2073
+ customOverlayContent: { type: String, default: "" }
1911
2074
  },
1912
- emits: ["loaded", "error", "progress"],
1913
2075
  data() {
1914
- const e = this.createFrames();
1915
2076
  return {
1916
- loadTracker: new K(e.length).onLoadFinished(() => this.$emit("loaded")).onLoadProgress((t) => this.$emit("progress", t)).onLoadError(() => this.$emit("error")),
1917
- sceneRotator: new Rt(this.cardinalFrames, he),
1918
- images: e,
1919
- isPreloaded: !1
2077
+ sceneState: { preloaded: !1, ready: !1 },
2078
+ canvasDimensions: { width: 0, height: 0 },
2079
+ pos: { x: 0, y: 0, width: 0, height: 0 },
2080
+ pickerData: void 0,
2081
+ buildingMap: Y.empty(),
2082
+ canvasRaster: Q.empty(),
2083
+ selectedBuildingId: void 0,
2084
+ halfHourMark: (/* @__PURE__ */ new Date()).getHours() * 2 + ((/* @__PURE__ */ new Date()).getMinutes() < 30 ? 0 : 1),
2085
+ viewResolver: (e, t) => ({ x: e, y: t }),
2086
+ error: !1
1920
2087
  };
1921
2088
  },
1922
2089
  computed: {
1923
- activeFrame() {
1924
- return this.images.find((e) => e.show);
2090
+ isHoverable() {
2091
+ return this.$refs.hoverProbe.isHoverEnabled;
2092
+ },
2093
+ selectedBuilding() {
2094
+ return this.getBuildingData(this.selectedBuildingId);
1925
2095
  }
1926
2096
  },
1927
2097
  watch: {
1928
- "viewModel.currentScene"(e, t) {
1929
- const i = this.getDirection(t, e), r = this.getSceneCountBetween(t, e);
1930
- this.rotateInDirection(t, i, r);
2098
+ buildingChooserTimeOfDay: {
2099
+ handler() {
2100
+ if (this.buildingChooserTimeOfDay) {
2101
+ const [e, t, i] = /^(\d\d):(\d\d)$/.exec(
2102
+ this.buildingChooserTimeOfDay
2103
+ ), r = parseInt(i);
2104
+ this.halfHourMark = parseInt(t) * 2 + (r < 15 ? 0 : r > 45 ? 2 : 1);
2105
+ }
2106
+ },
2107
+ immediate: !0
2108
+ },
2109
+ selectedBuildingId(e, t) {
2110
+ e ? this.$emit("hover-over-building", this.getBuildingData(e)) : this.$emit("hover-out-building", this.getBuildingData(t));
1931
2111
  }
1932
2112
  },
1933
- created() {
1934
- this.rotateComplete();
2113
+ async mounted() {
2114
+ const t = await new Me(
2115
+ this.cdnFileResolver
2116
+ ).loadBuildingChooser();
2117
+ t ? (this.canvasRaster = new Q(t.mapImage), this.buildingMap = new Y(t.buildingIds), this.daysOfYear = new Z(t.backgrounds), this.pickerData = {
2118
+ buildingOverlays: t.buildingOverlays,
2119
+ sceneLongitude: t.viewLongitude
2120
+ }, this.resizeImages()) : this.error = !0;
1935
2121
  },
1936
2122
  methods: {
1937
- rotateInDirection(e, t, i) {
1938
- this.viewModel.isRotating || (this.viewModel.isRotating = !0, this.rotationStep(
1939
- this.sceneRotator.start(
1940
- t,
1941
- e % j,
1942
- i
1943
- )
1944
- ));
2123
+ resizeScene({ width: e, height: t }) {
2124
+ this.canvasDimensions.width = e, this.canvasDimensions.height = t, this.$nextTick(this.resizeImages);
1945
2125
  },
1946
- rotationStep(e) {
1947
- setTimeout(() => {
1948
- this.images[e.frameIndex].show = !1;
1949
- const t = e.nextFrame();
1950
- this.images[t.frameIndex].show = !0, t.atEnd ? this.rotateComplete() : window.requestAnimationFrame(() => this.rotationStep(t));
1951
- }, 1e3 / Tt);
2126
+ sceneReset() {
2127
+ this.sceneState = { preloaded: !1, ready: !1 };
1952
2128
  },
1953
- rotateComplete() {
1954
- const e = this.sceneRotator.startFrameIndexForScene(
1955
- this.viewModel.currentScene % j
1956
- );
1957
- e in this.images && (this.images[e].show = !0), this.viewModel.isRotating = !1;
2129
+ getBuildingData(e) {
2130
+ return this.buildingCallback ? this.buildingCallback(e) : e;
1958
2131
  },
1959
- createFrames() {
1960
- const e = [];
1961
- for (let t = 0; t < he; t++) {
1962
- const { sourceSet: i, defaultPath: r } = this.frameImageSource(t);
1963
- e.push({
1964
- index: t,
1965
- sourceSet: i,
1966
- defaultPath: r,
1967
- show: !1
1968
- });
1969
- }
1970
- return e;
2132
+ getBuildingId(e) {
2133
+ const { x: t, y: i } = this.viewResolver(e.layerX, e.layerY);
2134
+ return this.buildingMap.getBuildingId(this.canvasRaster, t, i);
1971
2135
  },
1972
- frameImageSource(e) {
1973
- const t = ("0000" + (e + 1)).slice(-4), i = this.build ? `?v=${this.build}` : "", r = [
1974
- `${this.cdnFileResolver(`/480/${t}.jpg${i}`)} 480w`,
1975
- `${this.cdnFileResolver(`/960/${t}.jpg${i}`)} 960w`,
1976
- `${this.cdnFileResolver(`/1280/${t}.jpg${i}`)} 1280w`
1977
- ].join(","), n = this.cdnFileResolver(
1978
- `/480/${t}.jpg${i}`
1979
- );
1980
- return { sourceSet: r, defaultPath: n };
2136
+ resizeImages() {
2137
+ if (this.$refs.canvas && (this.canvasRaster.update(this.$refs.canvas), this.$refs.overlays))
2138
+ for (const e of this.$refs.overlays)
2139
+ e.setupDraw();
1981
2140
  },
1982
- getSceneCountBetween(e, t) {
1983
- const i = j / 2, r = Math.abs(e - t);
1984
- return r > i ? j - r : r;
2141
+ onMove(e) {
2142
+ this.isHoverable && (this.selectedBuildingId = this.getBuildingId(e), this.selectedBuildingId !== void 0 && (this.pos = {
2143
+ x: e.layerX,
2144
+ y: e.layerY,
2145
+ width: this.canvasDimensions.width,
2146
+ height: this.canvasDimensions.height
2147
+ }));
1985
2148
  },
1986
- getDirection(e, t) {
1987
- if (e === t)
1988
- return 0;
1989
- const r = Math.abs(e - t) < j / 2;
1990
- return r && e < t || !r && e > t ? 1 : -1;
2149
+ onClick(e) {
2150
+ this.selectedBuildingId = this.getBuildingId(e), this.isHoverable && this.selectedBuilding && this.$emit("go-to-building", this.selectedBuilding);
2151
+ },
2152
+ getColor(e) {
2153
+ return this.colorCallback(
2154
+ this.getBuildingData(e),
2155
+ e === this.selectedBuildingId ? "hover" : "idle"
2156
+ );
2157
+ },
2158
+ updateView({ resolve: e }) {
2159
+ this.viewResolver = e;
1991
2160
  }
1992
2161
  }
1993
- }, Ht = {
2162
+ }), ii = {
1994
2163
  key: 0,
1995
- class: "fill-parent d-flex justify-center align-center blue-grey lighten-5"
1996
- }, Nt = {
1997
- key: 1,
1998
- class: "frame-container"
1999
- }, jt = { class: "frame-image" }, qt = ["srcset", "type"], Pt = ["src"], Yt = {
2000
- key: 2,
2001
- id: "image-stack",
2002
- class: "frame-container"
2003
- }, Qt = ["alt"], zt = ["srcset"], $t = ["src"];
2004
- function Wt(e, t, i, r, n, s) {
2005
- const a = c("v-icon");
2006
- return l(), m("div", null, [
2007
- n.loadTracker.isError ? (l(), m("div", Ht, [
2008
- u(a, { "x-large": "" }, {
2009
- default: h(() => [
2010
- L("mdi-alert-circle-outline")
2164
+ style: { height: "50vh" },
2165
+ class: "d-flex justify-center align-center blue-grey lighten-5"
2166
+ }, ni = { class: "image-instances" }, si = ["innerHTML"];
2167
+ function oi(e, t, i, r, n, s) {
2168
+ const a = c("v-icon"), d = c("qi-building-chooser-scene-image-stack"), p = c("qi-building-chooser-raster-overlay"), v = c("qi-zoom-box"), w = c("qi-north-direction"), S = c("qi-building-chooser-sun-sim-control"), g = c("qi-floating-card"), b = c("qi-hover-probe");
2169
+ return e.error ? (l(), m("div", ii, [
2170
+ u(a, { "x-large": "" }, {
2171
+ default: h(() => [
2172
+ L("mdi-alert-circle-outline")
2173
+ ]),
2174
+ _: 1
2175
+ })
2176
+ ])) : e.pickerData ? (l(), m("div", {
2177
+ key: 1,
2178
+ style: M(`cursor: ${e.selectedBuildingId ? "pointer" : "auto"};height: ${e.canvasDimensions.height}px; position: relative`),
2179
+ class: "image-container"
2180
+ }, [
2181
+ u(v, {
2182
+ desktop: e.interactiveDesktop,
2183
+ mobile: e.interactiveMobile,
2184
+ onUpdate: e.updateView
2185
+ }, {
2186
+ default: h(() => [
2187
+ o("div", ni, [
2188
+ u(d, {
2189
+ "image-urls": e.daysOfYear.imageUrls,
2190
+ "active-index": e.halfHourMark,
2191
+ onResize: e.resizeScene,
2192
+ onPreloaded: t[0] || (t[0] = (k) => e.sceneState.preloaded = !0),
2193
+ onReady: t[1] || (t[1] = (k) => e.sceneState.ready = !0),
2194
+ onReset: e.sceneReset
2195
+ }, null, 8, ["image-urls", "active-index", "onResize", "onReset"]),
2196
+ x(o("div", null, [
2197
+ (l(!0), m(R, null, D(e.pickerData.buildingOverlays, (k) => (l(), y(p, {
2198
+ ref_for: !0,
2199
+ ref: "overlays",
2200
+ key: k.id,
2201
+ "image-url": k.url,
2202
+ dimensions: e.canvasDimensions,
2203
+ color: e.getColor(k.id)
2204
+ }, null, 8, ["image-url", "dimensions", "color"]))), 128))
2205
+ ], 512), [
2206
+ [B, e.sceneState.preloaded]
2207
+ ])
2011
2208
  ]),
2012
- _: 1
2013
- })
2014
- ])) : n.isPreloaded ? (l(), m("div", Yt, [
2015
- (l(!0), m(U, null, D(n.images, (d) => (l(), m("picture", {
2016
- key: d.index,
2017
- alt: d.index,
2018
- class: E({ "frame-image": !0, show: d.show })
2019
- }, [
2020
- o("source", {
2021
- srcset: d.sourceSet,
2022
- type: "image/jpeg"
2023
- }, null, 8, zt),
2024
- o("img", {
2025
- src: d.defaultPath,
2026
- alt: "Building image",
2027
- onLoad: t[2] || (t[2] = (p) => n.loadTracker.partLoaded()),
2028
- onError: t[3] || (t[3] = (p) => n.loadTracker.errorDetected())
2029
- }, null, 40, $t)
2030
- ], 10, Qt))), 128))
2031
- ])) : (l(), m("div", Nt, [
2032
- o("picture", jt, [
2033
- o("source", {
2034
- srcset: s.activeFrame.sourceSet,
2035
- type: s.activeFrame.type
2036
- }, null, 8, qt),
2037
- o("img", {
2038
- src: s.activeFrame.defaultPath,
2039
- onLoad: t[0] || (t[0] = (d) => n.isPreloaded = !0),
2040
- onError: t[1] || (t[1] = (d) => n.loadTracker.errorDetected())
2041
- }, null, 40, Pt)
2042
- ])
2043
- ]))
2044
- ]);
2045
- }
2046
- const Jt = /* @__PURE__ */ C(Vt, [["render", Wt], ["__scopeId", "data-v-e6481f8e"]]), re = 4;
2047
- function Ae(e) {
2048
- return e < re ? e + 1 : 1;
2049
- }
2050
- function Gt(e) {
2051
- return e > 1 ? e - 1 : re;
2052
- }
2053
- class Xt {
2054
- constructor(t) {
2055
- this._state = {
2056
- isRotating: !1,
2057
- currentScene: t
2058
- };
2059
- }
2060
- get isRotating() {
2061
- return this._state.isRotating;
2062
- }
2063
- set isRotating(t) {
2064
- this._state.isRotating = t;
2065
- }
2066
- get navigator() {
2067
- return this._navigator;
2068
- }
2069
- get sceneModel() {
2070
- return this._sceneModel;
2071
- }
2072
- unlessRotatingDo(t) {
2073
- this.isRotating || t();
2074
- }
2075
- get currentScene() {
2076
- return this._state.currentScene;
2077
- }
2078
- set currentScene(t) {
2079
- this._state.currentScene = t;
2080
- }
2081
- rotateCounterClockwise() {
2082
- this.unlessRotatingDo(() => {
2083
- this.currentScene = Ae(this.currentScene);
2084
- });
2085
- }
2086
- rotateClockwise() {
2087
- this.unlessRotatingDo(() => {
2088
- this.currentScene = Gt(this.currentScene);
2089
- });
2090
- }
2209
+ o("canvas", F(e.canvasDimensions, {
2210
+ ref: "canvas",
2211
+ class: { hover: !!e.selectedBuildingId },
2212
+ onClick: t[2] || (t[2] = (...k) => e.onClick && e.onClick(...k)),
2213
+ onMousemove: t[3] || (t[3] = (...k) => e.onMove && e.onMove(...k))
2214
+ }), null, 16),
2215
+ x(o("div", {
2216
+ class: "custom-overlay-layer",
2217
+ innerHTML: e.customOverlayContent
2218
+ }, null, 8, si), [
2219
+ [B, e.sceneState.preloaded]
2220
+ ])
2221
+ ]),
2222
+ _: 1
2223
+ }, 8, ["desktop", "mobile", "onUpdate"]),
2224
+ x(o("div", null, [
2225
+ e.pickerData.sceneLongitude ? (l(), y(w, {
2226
+ key: 0,
2227
+ class: "north-indicator",
2228
+ longitude: e.pickerData.sceneLongitude
2229
+ }, null, 8, ["longitude"])) : f("", !0),
2230
+ u(S, {
2231
+ modelValue: e.halfHourMark,
2232
+ "onUpdate:modelValue": t[4] || (t[4] = (k) => e.halfHourMark = k),
2233
+ "date-selector": e.daysOfYear,
2234
+ "is-loading": !e.sceneState.ready
2235
+ }, null, 8, ["modelValue", "date-selector", "is-loading"])
2236
+ ], 512), [
2237
+ [B, e.sceneState.preloaded]
2238
+ ]),
2239
+ e.showCards && e.selectedBuilding ? (l(), y(g, {
2240
+ key: 0,
2241
+ "is-hoverable": e.isHoverable,
2242
+ pos: e.pos,
2243
+ onOutside: t[5] || (t[5] = () => e.selectedBuildingId = void 0)
2244
+ }, {
2245
+ default: h(() => [
2246
+ A(e.$slots, "default", {
2247
+ building: e.selectedBuilding,
2248
+ canGoToBuilding: e.canGoToBuildingCallback(e.selectedBuilding),
2249
+ goToBuilding: () => e.canGoToBuildingCallback(e.selectedBuilding) && e.$emit("go-to-building", e.selectedBuilding),
2250
+ pos: e.pos,
2251
+ isHoverable: e.isHoverable,
2252
+ close: () => e.selectedBuildingId = void 0
2253
+ }, void 0, !0)
2254
+ ]),
2255
+ _: 3
2256
+ }, 8, ["is-hoverable", "pos"])) : f("", !0),
2257
+ u(b, { ref: "hoverProbe" }, null, 512)
2258
+ ], 4)) : f("", !0);
2091
2259
  }
2092
- const Zt = 4, Kt = [0, 16, 32, 48], ei = {
2093
- name: "QiApartmentChooser",
2260
+ const re = /* @__PURE__ */ C(ti, [["render", oi], ["__scopeId", "data-v-08f2ea1e"]]), ri = {
2261
+ name: "QiBuildingChooser",
2094
2262
  components: {
2095
- QiApartmentChooserRaster: ce,
2096
- QiApartmentChooserSvg: ue,
2097
- QiApartmentChooserNavigation: Ut,
2098
- QiApartmentChooserRotator: Jt,
2099
- QiFloatingCard: ne,
2100
- QiHoverProbe: Q,
2101
- QiZoomBox: se
2102
- },
2103
- provide() {
2104
- return {
2105
- i18n: this.i18n ? new R(this.i18n.labels, this.i18n.language) : new R()
2106
- };
2263
+ QiBuildingChooserSvg: oe,
2264
+ QiBuildingChooserRaster: re
2107
2265
  },
2108
- emits: [
2109
- "select-unit",
2110
- "go-to-unit",
2111
- "nav-unit",
2112
- "hover-over-unit",
2113
- "hover-out-unit",
2114
- "initialized"
2115
- ],
2266
+ emits: ["go-to-building", "hover-over-building", "hover-out-building"],
2116
2267
  props: {
2117
- i18n: { type: Object, default: void 0 },
2118
- showCards: { type: Boolean, default: !0 },
2119
- build: { type: String, default: "" },
2120
- buildingSceneDataResolver: { type: Function, default: null },
2121
- buildingScenesByApartmentResolver: { type: Function, default: null },
2122
- cdnFileResolver: { type: Function, required: !0 },
2268
+ showCards: { type: Boolean, default: () => !0 },
2123
2269
  colorCallback: {
2124
2270
  type: Function,
2125
2271
  default: () => ({ r: 108, g: 0, b: 108, a: 144, s: 2 })
2126
2272
  },
2127
- unitCallback: { type: Function, default: (e) => e },
2128
- canGoToUnitCallback: { type: Function, default: () => !0 },
2129
- selectedUnitId: { type: String, default: null },
2130
- nextUnit: { type: Object, default: null },
2131
- prevUnit: { type: Object, default: null },
2132
- drawObserver: {
2133
- type: [Object, Array, String, Number, Boolean],
2134
- default: null
2135
- },
2273
+ buildingCallback: { type: Function, default: (e) => e },
2274
+ cdnFileResolver: { type: Function, required: !0 },
2275
+ i18n: { type: Object, default: void 0 },
2136
2276
  interactiveDesktop: { type: Boolean, default: !0 },
2137
2277
  interactiveMobile: { type: Boolean, default: !0 },
2138
- useSvg: { type: Boolean, default: !1 }
2139
- },
2140
- data() {
2141
- return {
2142
- loadState: { isReady: !1, isError: !1, progress: void 0 },
2143
- scenesByApartment: null,
2144
- sceneData: null,
2145
- scenes: null,
2146
- viewModel: void 0,
2147
- resourceLoader: new H(),
2148
- pos: { x: 0, y: 0, width: 0, height: 0 },
2149
- closeHandler: void 0,
2150
- hoverApartment: void 0
2151
- };
2278
+ useSvg: { type: Boolean, default: !1 },
2279
+ buildingChooserTimeOfDay: { type: String, default: null },
2280
+ canGoToBuildingCallback: { type: Function, default: () => !0 },
2281
+ customOverlayContent: { type: String, default: "" }
2152
2282
  },
2153
2283
  computed: {
2154
- isHoverable() {
2155
- return this.$refs.hoverProbe.isHoverEnabled;
2156
- },
2157
- selectedUnit() {
2158
- return this.unitCallback ? this.unitCallback(this.selectedUnitId) : this.selectedUnitId;
2159
- },
2160
- overlayComponent() {
2161
- return this.useSvg ? ue : ce;
2162
- }
2163
- },
2164
- watch: {
2165
- selectedUnitId: {
2166
- handler() {
2167
- if (this.selectedUnitId && this.viewModel) {
2168
- const e = this.scenesByApartment[this.selectedUnitId];
2169
- e && (this.viewModel.currentScene = e);
2170
- }
2171
- },
2172
- immediate: !0
2173
- }
2174
- },
2175
- async mounted() {
2176
- let e = null;
2177
- try {
2178
- e = await this.resourceLoader.loadJson(
2179
- this.cdnFileResolver("/apartmentChooser.json")
2180
- );
2181
- } catch {
2182
- console.info("apartmentChooser.json not found");
2183
- }
2184
- const t = e && e.startScene !== void 0 ? e.startScene : Zt;
2185
- this.scenes = e && e.scenes !== void 0 ? e.scenes : Kt, this.sceneData = e && e.sceneData !== void 0 ? e.sceneData.map((n) => ({
2186
- apartmentId: n.apartmentID,
2187
- index: n.index
2188
- })) : this.buildingSceneDataResolver ? await this.buildingSceneDataResolver() : [], this.scenesByApartment = e && e.sceneData !== void 0 ? e.sceneData.map((n) => {
2189
- const s = n.bestScene === 0 ? 4 : n.bestScene;
2190
- return { unitId: n.apartmentID, scene: s };
2191
- }).reduce((n, s) => ({ ...n, [s.unitId]: s.scene }), {}) : this.buildingScenesByApartmentResolver ? await this.buildingScenesByApartmentResolver() : [];
2192
- const i = (n, s = "unitId") => {
2193
- let a = t, d = [];
2194
- for (let p = 0; p < re; p++)
2195
- d.push(a), a = Ae(a);
2196
- return n.sort((p, v) => {
2197
- const w = d.findIndex(
2198
- (g) => g === this.scenesByApartment[p[s]]
2199
- ), S = d.findIndex(
2200
- (g) => g === this.scenesByApartment[v[s]]
2201
- );
2202
- return w < S ? -1 : w > S ? 1 : 0;
2203
- }), n;
2204
- }, r = (n) => {
2205
- this.viewModel = new Xt(n);
2206
- };
2207
- this.$emit("initialized", {
2208
- scene: t,
2209
- scenes: this.scenes,
2210
- sceneData: this.sceneData,
2211
- scenesByApartment: this.scenesByApartment,
2212
- unitsSceneSort: i,
2213
- initialize: r
2214
- });
2215
- },
2216
- methods: {
2217
- onPos(e) {
2218
- this.pos = e;
2219
- },
2220
- hoverOver({ hoverApartment: e, closeHandler: t }) {
2221
- this.hoverApartment = e, this.closeHandler = t, this.$emit("hover-over-unit", e);
2222
- },
2223
- hoverOut({ hoverApartment: e, closeHandler: t }) {
2224
- this.hoverApartment = null, this.closeHandler = t, this.$emit("hover-out-unit", e);
2284
+ component() {
2285
+ return this.useSvg ? oe : re;
2225
2286
  }
2226
2287
  }
2227
- }, ti = { key: 0 }, ii = { class: "interactive-viewer" }, ni = { class: "fill-parent" }, si = { key: 0 }, oi = {
2228
- key: 1,
2229
- class: "navigation"
2230
- }, ri = { key: 2 };
2288
+ };
2231
2289
  function ai(e, t, i, r, n, s) {
2232
- const a = c("qi-apartment-chooser-rotator"), d = c("qi-zoom-box"), p = c("qi-floating-card"), v = c("qi-apartment-chooser-navigation"), w = c("v-progress-linear"), S = c("qi-hover-probe");
2233
- return n.viewModel ? (l(), m("div", ti, [
2234
- o("div", ii, [
2235
- o("div", ni, [
2236
- u(d, {
2237
- desktop: n.loadState.isReady && i.interactiveDesktop,
2238
- mobile: n.loadState.isReady && i.interactiveMobile
2239
- }, {
2240
- default: h(() => [
2241
- u(a, {
2242
- "cdn-file-resolver": i.cdnFileResolver,
2243
- "view-model": n.viewModel,
2244
- "cardinal-frames": n.scenes,
2245
- build: i.build,
2246
- onProgress: t[0] || (t[0] = (g) => n.loadState.progress = g),
2247
- onLoaded: t[1] || (t[1] = (g) => n.loadState.isReady = !0),
2248
- onError: t[2] || (t[2] = (g) => n.loadState.isError = !0)
2249
- }, null, 8, ["cdn-file-resolver", "view-model", "cardinal-frames", "build"]),
2250
- n.loadState.isReady ? (l(), m("div", si, [
2251
- (l(), y(ve(s.overlayComponent), {
2252
- "cdn-file-resolver": i.cdnFileResolver,
2253
- "view-model": n.viewModel,
2254
- "selected-unit-id": i.selectedUnitId,
2255
- "scene-data": n.sceneData,
2256
- "color-callback": i.colorCallback,
2257
- "unit-callback": i.unitCallback,
2258
- "can-go-to-unit-callback": i.canGoToUnitCallback,
2259
- "draw-observer": i.drawObserver,
2260
- onSelectUnit: t[3] || (t[3] = (g) => e.$emit("select-unit", g)),
2261
- onGoToUnit: t[4] || (t[4] = (g) => e.$emit("go-to-unit", g)),
2262
- onHoverOver: s.hoverOver,
2263
- onHoverOut: s.hoverOut,
2264
- onPos: s.onPos
2265
- }, {
2266
- default: h((g) => [
2267
- A(e.$slots, "default", fe(be(g)), void 0, !0)
2268
- ]),
2269
- _: 3
2270
- }, 40, ["cdn-file-resolver", "view-model", "selected-unit-id", "scene-data", "color-callback", "unit-callback", "can-go-to-unit-callback", "draw-observer", "onHoverOver", "onHoverOut", "onPos"]))
2271
- ])) : f("", !0)
2272
- ]),
2273
- _: 3
2274
- }, 8, ["desktop", "mobile"]),
2275
- n.hoverApartment && i.showCards ? (l(), y(p, {
2276
- key: 0,
2277
- "is-hoverable": s.isHoverable,
2278
- pos: n.pos,
2279
- onOutside: n.closeHandler
2280
- }, {
2281
- default: h(() => [
2282
- A(e.$slots, "default", {
2283
- unit: n.hoverApartment,
2284
- canGoToUnit: i.canGoToUnitCallback(n.hoverApartment),
2285
- goToUnit: () => i.canGoToUnitCallback(n.hoverApartment) && e.$emit("go-to-unit", n.hoverApartment),
2286
- pos: n.pos,
2287
- isHoverable: s.isHoverable,
2288
- close: n.closeHandler
2289
- }, void 0, !0)
2290
- ]),
2291
- _: 3
2292
- }, 8, ["is-hoverable", "pos", "onOutside"])) : f("", !0),
2293
- n.loadState.isReady ? (l(), m("div", oi, [
2294
- u(v, {
2295
- "can-go-to-unit-callback": i.canGoToUnitCallback,
2296
- "selected-unit": s.selectedUnit,
2297
- "prev-unit": i.prevUnit,
2298
- "next-unit": i.nextUnit,
2299
- "view-model": n.viewModel,
2300
- onGoToUnit: t[5] || (t[5] = (g) => e.$emit("go-to-unit", g)),
2301
- onPrevUnit: t[6] || (t[6] = (g) => e.$emit("nav-unit", i.prevUnit)),
2302
- onNextUnit: t[7] || (t[7] = (g) => e.$emit("nav-unit", i.nextUnit))
2303
- }, null, 8, ["can-go-to-unit-callback", "selected-unit", "prev-unit", "next-unit", "view-model"])
2304
- ])) : n.loadState.isError ? f("", !0) : (l(), m("div", ri, [
2305
- u(w, {
2306
- indeterminate: !n.loadState.progress,
2307
- value: n.loadState.progress
2308
- }, null, 8, ["indeterminate", "value"])
2309
- ]))
2290
+ return l(), y(be(s.component), {
2291
+ "show-cards": i.showCards,
2292
+ "color-callback": i.colorCallback,
2293
+ "building-callback": i.buildingCallback,
2294
+ "cdn-file-resolver": i.cdnFileResolver,
2295
+ i18n: i.i18n,
2296
+ "interactive-desktop": i.interactiveDesktop,
2297
+ "interactive-mobile": i.interactiveMobile,
2298
+ "building-chooser-time-of-day": i.buildingChooserTimeOfDay,
2299
+ "can-go-to-building-callback": i.canGoToBuildingCallback,
2300
+ "custom-overlay-content": i.customOverlayContent,
2301
+ onGoToBuilding: t[0] || (t[0] = (a) => e.$emit("go-to-building", a)),
2302
+ onHoverOverBuilding: t[1] || (t[1] = (a) => e.$emit("hover-over-building", a)),
2303
+ onHoverOutBuilding: t[2] || (t[2] = (a) => e.$emit("hover-out-building", a))
2304
+ }, De({ _: 2 }, [
2305
+ D(Object.keys(e.$slots), (a) => ({
2306
+ name: a,
2307
+ fn: h((d) => [
2308
+ A(e.$slots, a, ye(we(d)))
2310
2309
  ])
2311
- ]),
2312
- u(S, { ref: "hoverProbe" }, null, 512)
2313
- ])) : f("", !0);
2310
+ }))
2311
+ ]), 1064, ["show-cards", "color-callback", "building-callback", "cdn-file-resolver", "i18n", "interactive-desktop", "interactive-mobile", "building-chooser-time-of-day", "can-go-to-building-callback", "custom-overlay-content"]);
2314
2312
  }
2315
- const li = /* @__PURE__ */ C(ei, [["render", ai], ["__scopeId", "data-v-3a1121f3"]]);
2316
- var N = {};
2317
- Object.defineProperty(N, "__esModule", {
2313
+ const li = /* @__PURE__ */ C(ri, [["render", ai]]);
2314
+ var j = {};
2315
+ Object.defineProperty(j, "__esModule", {
2318
2316
  value: !0
2319
2317
  });
2320
2318
  var di = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) {
2321
2319
  return typeof e;
2322
2320
  } : function(e) {
2323
2321
  return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
2324
- }, ci = typeof window < "u" && typeof window.document < "u", ui = typeof process < "u" && process.versions != null && process.versions.node != null, hi = (typeof self > "u" ? "undefined" : di(self)) === "object" && self.constructor && self.constructor.name === "DedicatedWorkerGlobalScope", mi = typeof window < "u" && window.name === "nodejs" || typeof navigator < "u" && (navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom")), pi = typeof Deno < "u" && typeof Deno.version < "u" && typeof Deno.version.deno < "u", gi = N.isBrowser = ci;
2325
- N.isWebWorker = hi;
2326
- N.isNode = ui;
2327
- N.isJsDom = mi;
2328
- N.isDeno = pi;
2322
+ }, ci = typeof window < "u" && typeof window.document < "u", ui = typeof process < "u" && process.versions != null && process.versions.node != null, hi = (typeof self > "u" ? "undefined" : di(self)) === "object" && self.constructor && self.constructor.name === "DedicatedWorkerGlobalScope", mi = typeof window < "u" && window.name === "nodejs" || typeof navigator < "u" && (navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom")), pi = typeof Deno < "u" && typeof Deno.version < "u" && typeof Deno.version.deno < "u", gi = j.isBrowser = ci;
2323
+ j.isWebWorker = hi;
2324
+ j.isNode = ui;
2325
+ j.isJsDom = mi;
2326
+ j.isDeno = pi;
2329
2327
  const vi = {
2330
2328
  name: "Player",
2331
2329
  emits: [
@@ -2382,7 +2380,7 @@ const vi = {
2382
2380
  window.addEventListener("resize", this.setPlayerSize), this.setPlayerSize();
2383
2381
  const r = {
2384
2382
  initialized: () => {
2385
- this.playerAPI = G.Main.getPlayerAPI();
2383
+ this.playerAPI = K.Main.getPlayerAPI();
2386
2384
  const s = this.playerAPI.getCurrentCamera();
2387
2385
  s && (this.playerCamera = s.id), this.$emit("new-camera-callback", this.playerCamera);
2388
2386
  },
@@ -2399,7 +2397,7 @@ const vi = {
2399
2397
  };
2400
2398
  if (!gi)
2401
2399
  return;
2402
- const n = await new G.Main(
2400
+ const n = await new K.Main(
2403
2401
  this.rootUrl,
2404
2402
  "qpc",
2405
2403
  r,
@@ -2410,7 +2408,7 @@ const vi = {
2410
2408
  n && (n.handleWindowResize(), window.addEventListener(
2411
2409
  "resize",
2412
2410
  n.handleWindowResize.bind(n)
2413
- ), n.animate(), this.playerAPI = G.Main.getPlayerAPI(), this.playerAPI && this.playerAPI.setLookSensitivity(this.mouseSensitivity));
2411
+ ), n.animate(), this.playerAPI = K.Main.getPlayerAPI(), this.playerAPI && this.playerAPI.setLookSensitivity(this.mouseSensitivity));
2414
2412
  },
2415
2413
  beforeUnmount() {
2416
2414
  this.playerAPI && this.playerAPI.destroy();
@@ -2546,7 +2544,7 @@ const Bi = /* @__PURE__ */ C(vi, [["render", xi], ["__scopeId", "data-v-dd836eff
2546
2544
  }
2547
2545
  }
2548
2546
  }, Oi = { class: "waypoint-carousel" };
2549
- function Ui(e, t, i, r, n, s) {
2547
+ function Ri(e, t, i, r, n, s) {
2550
2548
  const a = c("v-icon"), d = c("v-btn"), p = c("v-hover"), v = c("v-img"), w = c("v-card"), S = c("v-slide-group-item"), g = c("v-slide-group");
2551
2549
  return l(), m("div", Oi, [
2552
2550
  u(g, {
@@ -2609,7 +2607,7 @@ function Ui(e, t, i, r, n, s) {
2609
2607
  })
2610
2608
  ]),
2611
2609
  default: h(() => [
2612
- (l(!0), m(U, null, D(i.thumbnails, (b) => (l(), y(S, {
2610
+ (l(!0), m(R, null, D(i.thumbnails, (b) => (l(), y(S, {
2613
2611
  key: b.id
2614
2612
  }, {
2615
2613
  default: h(({ toggle: k, selectedClass: I }) => [
@@ -2640,7 +2638,7 @@ function Ui(e, t, i, r, n, s) {
2640
2638
  }, 8, ["modelValue"])
2641
2639
  ]);
2642
2640
  }
2643
- const Ri = /* @__PURE__ */ C(Di, [["render", Ui], ["__scopeId", "data-v-f4e6ce2e"]]), Ti = {
2641
+ const Ui = /* @__PURE__ */ C(Di, [["render", Ri], ["__scopeId", "data-v-f4e6ce2e"]]), Ti = {
2644
2642
  name: "FloorLevel",
2645
2643
  inject: ["i18n"],
2646
2644
  props: {
@@ -2675,7 +2673,7 @@ function qi(e, t, i, r, n, s) {
2675
2673
  density: "comfortable",
2676
2674
  elevation: "1",
2677
2675
  icon: ""
2678
- }, ye({ ...p })), {
2676
+ }, Ce({ ...p })), {
2679
2677
  default: h(() => [
2680
2678
  (l(), m("svg", Vi, [
2681
2679
  o("path", {
@@ -2756,7 +2754,7 @@ function zi(e, t, i, r, n, s) {
2756
2754
  elevation: "1",
2757
2755
  icon: "mdi-share-variant",
2758
2756
  onClick: t[0] || (t[0] = (I) => n.showSocialShare = !n.showSocialShare)
2759
- }, ye({ ...k })), null, 16)
2757
+ }, Ce({ ...k })), null, 16)
2760
2758
  ]),
2761
2759
  default: h(() => [
2762
2760
  o("span", null, _(s.i18n.getLabel("share")), 1)
@@ -2916,7 +2914,7 @@ function Ji(e, t, i, r, n, s) {
2916
2914
  default: h(() => [
2917
2915
  u(w, { class: "interior-selector-list" }, {
2918
2916
  default: h(() => [
2919
- (l(!0), m(U, null, D(i.availableArchetypes, (g, b) => (l(), y(v, {
2917
+ (l(!0), m(R, null, D(i.availableArchetypes, (g, b) => (l(), y(v, {
2920
2918
  density: "compact",
2921
2919
  key: `at-menuitem-${b}`,
2922
2920
  onClick: (k) => e.$emit("select-interior", g.archetypeID),
@@ -3002,7 +3000,7 @@ function on(e, t, i, r, n, s) {
3002
3000
  ]);
3003
3001
  }
3004
3002
  const rn = /* @__PURE__ */ C(nn, [["render", on], ["__scopeId", "data-v-b418cf51"]]), an = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAqCAMAAADyHTlpAAAAllBMVEUAAAD/rwD/rwD/qgP/qwL/qAL/qwP/qwH/rAL/rAL/qwL/qQD/qwL/qwD/qQD/qwL/pQD/qgH/nwD/pwD/qQL/rAL/qwD/qwT/rAP/qwL/rAL/rAD/rAL/qgD/qwL/qQP/rAP/rAH/qgH/qwL/qwD/qgL/rwD/qgD/qwH/qgD/qgL/rAD/qgD/qgD/qwH/rAP/qgX/qwA+O5E+AAAAMnRSTlMAECBg/3C/v5Dff4+PT1/PMN8QII9vf0CfgO9vnzDvUF+vr3BA3zA/z2+fX59g71AwcDsf6p0AAAFGSURBVHicvdRtT8MgEABgaM9hu1aHXV/cpm6zWt829f//OYEK9qC3NDF6HxYCTw5GuWPsd8GjqTIGOJtIZwDi/ymnKPflOSTub6cAcwdnkHk5AQY2v3Dzl2phga1EFkl5hScLbZc+LbUs/FltK5OpLpsmrS0NpbLLSu3Er1dgIsn0cdabEdlHlICL5IZSRq5gELcn7DCnsfQL24AX5PeNfAlAHSEOaYrFXaNiqwa7kO7V9L1dt9u25kX58cBY7dbZYz/MKdr2o06nrZ6klNX4AYRdf8aHzkL6QtxAG9KculjhS0nJMO0rSVmF5ZyWnn2jFC+36vcgLTzq+3lPRx6XrjjTqQ7iqJxY6+KLydp0ZWhrVHWE0JoqHq1NSHBxF0h+1Mh6LUMM5LC/Kht8h+5nG9zeTtbt37Ti3XT6+d29pkTXTZVEfAEKARRF2iiwhQAAAB10RVh0U29mdHdhcmUAQGx1bmFwYWludC9wbmctY29kZWP1QxkeAAAAAElFTkSuQmCC";
3005
- function me(e) {
3003
+ function ge(e) {
3006
3004
  return ("0" + e).slice(-2);
3007
3005
  }
3008
3006
  const ln = {
@@ -3016,7 +3014,7 @@ const ln = {
3016
3014
  },
3017
3015
  computed: {
3018
3016
  displayValue() {
3019
- return [me(this.hours), ":", me(this.minutes)].join("");
3017
+ return [ge(this.hours), ":", ge(this.minutes)].join("");
3020
3018
  }
3021
3019
  }
3022
3020
  }, dn = { class: "d-flex flex-column align-center justify-center clock-face" }, cn = { class: "clock-icon" }, un = { class: "clock-value grey--text text--darken-3" };
@@ -3070,19 +3068,19 @@ class pn {
3070
3068
  this._state.isActive = t;
3071
3069
  }
3072
3070
  }
3073
- function q(e) {
3071
+ function P(e) {
3074
3072
  return ("0" + e).slice(-2);
3075
3073
  }
3076
3074
  function gn() {
3077
3075
  const e = /* @__PURE__ */ new Date();
3078
3076
  return [
3079
3077
  e.getFullYear().toString(),
3080
- q(e.getMonth() + 1),
3081
- q(e.getDate()),
3078
+ P(e.getMonth() + 1),
3079
+ P(e.getDate()),
3082
3080
  " ",
3083
- q(e.getHours()),
3084
- q(e.getMinutes()),
3085
- q(e.getSeconds())
3081
+ P(e.getHours()),
3082
+ P(e.getMinutes()),
3083
+ P(e.getSeconds())
3086
3084
  ].join("");
3087
3085
  }
3088
3086
  function vn() {
@@ -3219,7 +3217,7 @@ const Mn = /* @__PURE__ */ C(Sn, [["render", Ln], ["__scopeId", "data-v-6e4f02d6
3219
3217
  localStorage.setItem(`${this.project}-dont-show-tutorial`, !0);
3220
3218
  }
3221
3219
  }
3222
- }, V = (e) => (ee("data-v-d87b088a"), e = e(), te(), e), Bn = {
3220
+ }, V = (e) => (ae("data-v-d87b088a"), e = e(), le(), e), Bn = {
3223
3221
  key: 0,
3224
3222
  class: "tutorial"
3225
3223
  }, Fn = {
@@ -3272,7 +3270,7 @@ const Mn = /* @__PURE__ */ C(Sn, [["render", Ln], ["__scopeId", "data-v-6e4f02d6
3272
3270
  "stroke-width": "1.5"
3273
3271
  })
3274
3272
  ])
3275
- ], -1)), Un = { class: "text mt-3" }, Rn = { class: "box col" }, Tn = /* @__PURE__ */ V(() => /* @__PURE__ */ o("div", { class: "tutorial-icon d-flex align-items-center justify-center" }, [
3273
+ ], -1)), Rn = { class: "text mt-3" }, Un = { class: "box col" }, Tn = /* @__PURE__ */ V(() => /* @__PURE__ */ o("div", { class: "tutorial-icon d-flex align-items-center justify-center" }, [
3276
3274
  /* @__PURE__ */ o("svg", {
3277
3275
  width: "100",
3278
3276
  height: "65",
@@ -3756,9 +3754,9 @@ function ns(e, t, i, r, n, s) {
3756
3754
  o("div", En, [
3757
3755
  o("div", Dn, [
3758
3756
  On,
3759
- o("div", Un, _(s.i18n.getLabel("click-and-drag-to-look-around")), 1)
3757
+ o("div", Rn, _(s.i18n.getLabel("click-and-drag-to-look-around")), 1)
3760
3758
  ]),
3761
- o("div", Rn, [
3759
+ o("div", Un, [
3762
3760
  Tn,
3763
3761
  o("div", Vn, _(s.i18n.getLabel("click-on-the-cricles-to-move-around")), 1)
3764
3762
  ]),
@@ -3816,14 +3814,14 @@ function os(e) {
3816
3814
  const t = parseInt(e.substr(1, 2), 16) / 255, i = parseInt(e.substr(3, 2), 16) / 255, r = parseInt(e.substr(5, 2), 16) / 255;
3817
3815
  return [t, i, r];
3818
3816
  }
3819
- function Z(e) {
3817
+ function te(e) {
3820
3818
  var t = e.toString(16);
3821
3819
  return t.length == 1 ? "0" + t : t;
3822
3820
  }
3823
3821
  function rs([e, t, i]) {
3824
- return "#" + Z(parseInt(e * 255)) + Z(parseInt(t * 255)) + Z(parseInt(i * 255));
3822
+ return "#" + te(parseInt(e * 255)) + te(parseInt(t * 255)) + te(parseInt(i * 255));
3825
3823
  }
3826
- function pe(e) {
3824
+ function ve(e) {
3827
3825
  const t = [
3828
3826
  "Cool 5",
3829
3827
  "Cool 10",
@@ -3932,7 +3930,7 @@ const as = {
3932
3930
  },
3933
3931
  data() {
3934
3932
  return {
3935
- allSettings: pe(this.initialSettings)
3933
+ allSettings: ve(this.initialSettings)
3936
3934
  };
3937
3935
  },
3938
3936
  watch: {
@@ -3967,10 +3965,10 @@ const as = {
3967
3965
  this.$emit("save-settings", this.settingsToUpdate);
3968
3966
  },
3969
3967
  resetForm() {
3970
- this.allSettings = pe(), this.$emit("update-settings", this.settingsToUpdate);
3968
+ this.allSettings = ve(), this.$emit("update-settings", this.settingsToUpdate);
3971
3969
  }
3972
3970
  }
3973
- }, ls = (e) => (ee("data-v-c04f3195"), e = e(), te(), e), ds = { class: "player-settings-ui" }, cs = { id: "settings-ui-form" }, us = { class: "form-inputs" }, hs = { class: "setting-label" }, ms = { class: "setting-label" }, ps = ["max", "min", "step"], gs = { class: "setting-label" }, vs = { class: "flex-grow-1 flex-shrink-0" }, fs = ["onUpdate:modelValue"], bs = {
3971
+ }, ls = (e) => (ae("data-v-c04f3195"), e = e(), le(), e), ds = { class: "player-settings-ui" }, cs = { id: "settings-ui-form" }, us = { class: "form-inputs" }, hs = { class: "setting-label" }, ms = { class: "setting-label" }, ps = ["max", "min", "step"], gs = { class: "setting-label" }, vs = { class: "flex-grow-1 flex-shrink-0" }, fs = ["onUpdate:modelValue"], bs = {
3974
3972
  key: 3,
3975
3973
  "d-block": "",
3976
3974
  class: "mt-3"
@@ -3986,7 +3984,7 @@ function Ss(e, t, i, r, n, s) {
3986
3984
  return l(), m("div", ds, [
3987
3985
  o("form", cs, [
3988
3986
  o("div", us, [
3989
- (l(!0), m(U, null, D(n.allSettings, (g, b, k) => (l(), m("div", {
3987
+ (l(!0), m(R, null, D(n.allSettings, (g, b, k) => (l(), m("div", {
3990
3988
  key: k,
3991
3989
  "d-block": ""
3992
3990
  }, [
@@ -4049,7 +4047,7 @@ function Ss(e, t, i, r, n, s) {
4049
4047
  type: "color",
4050
4048
  onChange: t[0] || (t[0] = (...I) => s.updateSettings && s.updateSettings(...I))
4051
4049
  }, null, 40, fs), [
4052
- [Fe, n.allSettings[b].value]
4050
+ [Oe, n.allSettings[b].value]
4053
4051
  ])
4054
4052
  ]),
4055
4053
  o("div", null, [
@@ -4170,7 +4168,7 @@ const As = /* @__PURE__ */ C(as, [["render", Ss], ["__scopeId", "data-v-c04f3195
4170
4168
  class: "rotation-marker-svg",
4171
4169
  viewBox: "0 0 40 40",
4172
4170
  xmlns: "http://www.w3.org/2000/svg"
4173
- }, xs = /* @__PURE__ */ we('<defs><radialGradient id="Gradient" cx="0" cy="0" r="0.9" fx="0" fy="0"><stop offset="0%" class="stop1"></stop><stop offset="60%" class="stop2"></stop><stop offset="90%" class="stop3"></stop></radialGradient><linearGradient id="LineGradient" gradientTransform="rotate(90)"><stop offset="0%" class="stop1"></stop><stop offset="75%" class="stop2"></stop><stop offset="100%" class="stop3"></stop></linearGradient></defs>', 1), Bs = ["transform"], Fs = /* @__PURE__ */ we('<rect id="field-of-view-gradient" x="20" y="20" width="38" height="38" transform="rotate(0)" transform-origin="20 20" fill="url(#Gradient)"></rect><rect class="field-of-view-border" x="20" y="20" width="1" height="25" fill="url(#LineGradient)" transform="rotate(0)" transform-origin="20 20"></rect><rect class="field-of-view-border" x="19" y="19" width="1" height="25" fill="url(#LineGradient)" transform="rotate(-90)" transform-origin="20 20"></rect><circle cx="20" cy="20" r="5" fill="white"></circle><circle cx="20" cy="20" r="3" fill="red"></circle>', 5), Es = [
4171
+ }, xs = /* @__PURE__ */ _e('<defs><radialGradient id="Gradient" cx="0" cy="0" r="0.9" fx="0" fy="0"><stop offset="0%" class="stop1"></stop><stop offset="60%" class="stop2"></stop><stop offset="90%" class="stop3"></stop></radialGradient><linearGradient id="LineGradient" gradientTransform="rotate(90)"><stop offset="0%" class="stop1"></stop><stop offset="75%" class="stop2"></stop><stop offset="100%" class="stop3"></stop></linearGradient></defs>', 1), Bs = ["transform"], Fs = /* @__PURE__ */ _e('<rect id="field-of-view-gradient" x="20" y="20" width="38" height="38" transform="rotate(0)" transform-origin="20 20" fill="url(#Gradient)"></rect><rect class="field-of-view-border" x="20" y="20" width="1" height="25" fill="url(#LineGradient)" transform="rotate(0)" transform-origin="20 20"></rect><rect class="field-of-view-border" x="19" y="19" width="1" height="25" fill="url(#LineGradient)" transform="rotate(-90)" transform-origin="20 20"></rect><circle cx="20" cy="20" r="5" fill="white"></circle><circle cx="20" cy="20" r="3" fill="red"></circle>', 5), Es = [
4174
4172
  Fs
4175
4173
  ];
4176
4174
  function Ds(e, t, i, r, n, s) {
@@ -4183,10 +4181,10 @@ function Ds(e, t, i, r, n, s) {
4183
4181
  ]);
4184
4182
  }
4185
4183
  const Os = /* @__PURE__ */ C(Ls, [["render", Ds]]);
4186
- function Us(e) {
4184
+ function Rs(e) {
4187
4185
  return T.MathUtils.degToRad(e);
4188
4186
  }
4189
- const Rs = {
4187
+ const Us = {
4190
4188
  name: "MiniMapMap",
4191
4189
  components: { RotationMarkerV2: Os },
4192
4190
  props: {
@@ -4303,7 +4301,7 @@ const Rs = {
4303
4301
  },
4304
4302
  calculateRelativeValues() {
4305
4303
  const e = this.minimapCamera.position.y - this.floorVerticalPosition;
4306
- this.planeHeight = 2 * (e * Math.tan(Us(this.minimapCamera.fovY / 2))), this.planeWidth = 512 / 384 * this.planeHeight;
4304
+ this.planeHeight = 2 * (e * Math.tan(Rs(this.minimapCamera.fovY / 2))), this.planeWidth = 512 / 384 * this.planeHeight;
4307
4305
  const t = this.planeHeight / 2, i = this.planeWidth / 2, r = new T.Vector3(
4308
4306
  i * -1,
4309
4307
  0,
@@ -4336,7 +4334,7 @@ function Hs(e, t, i, r, n, s) {
4336
4334
  class: "center-pivot",
4337
4335
  style: M(n.centerPivotStyle)
4338
4336
  }, [
4339
- (l(!0), m(U, null, D(s.camerasWithRelativePosition, (d) => (l(), m("div", {
4337
+ (l(!0), m(R, null, D(s.camerasWithRelativePosition, (d) => (l(), m("div", {
4340
4338
  key: d.id
4341
4339
  }, [
4342
4340
  s.currentCameraObject.floorLevel === d.floorLevel ? (l(), m("div", {
@@ -4356,7 +4354,7 @@ function Hs(e, t, i, r, n, s) {
4356
4354
  ])
4357
4355
  ]);
4358
4356
  }
4359
- const Ns = /* @__PURE__ */ C(Rs, [["render", Hs], ["__scopeId", "data-v-341837d7"]]), js = {
4357
+ const Ns = /* @__PURE__ */ C(Us, [["render", Hs], ["__scopeId", "data-v-341837d7"]]), js = {
4360
4358
  name: "Moveable",
4361
4359
  emits: ["close"],
4362
4360
  data() {
@@ -4393,7 +4391,7 @@ function qs(e) {
4393
4391
  document.removeEventListener("mouseup", p, !1), document.removeEventListener("mousemove", d, !1), document.removeEventListener("touchend", p, !1), document.removeEventListener("touchmove", d, !1);
4394
4392
  }
4395
4393
  }
4396
- const Ps = (e) => (ee("data-v-243baf73"), e = e(), te(), e), Ys = /* @__PURE__ */ Ps(() => /* @__PURE__ */ o("div", { id: "filler-div" }, null, -1)), Qs = {
4394
+ const Ps = (e) => (ae("data-v-243baf73"), e = e(), le(), e), Ys = /* @__PURE__ */ Ps(() => /* @__PURE__ */ o("div", { id: "filler-div" }, null, -1)), Qs = {
4397
4395
  class: "moveable-body",
4398
4396
  id: "moveableDivheader"
4399
4397
  }, zs = { class: "moveable-footer" };
@@ -4434,7 +4432,7 @@ function $s(e, t, i, r, n, s) {
4434
4432
  }
4435
4433
  const Ws = /* @__PURE__ */ C(js, [["render", $s], ["__scopeId", "data-v-243baf73"]]), Js = {
4436
4434
  name: "MinimapCompass",
4437
- components: { QiNorthDirection: ie },
4435
+ components: { QiNorthDirection: X },
4438
4436
  props: {
4439
4437
  scale: {
4440
4438
  type: Number,
@@ -4720,7 +4718,7 @@ const ao = /* @__PURE__ */ C(oo, [["render", ro], ["__scopeId", "data-v-547d8112
4720
4718
  ],
4721
4719
  components: {
4722
4720
  Player: Bi,
4723
- WaypointCarousel: Ri,
4721
+ WaypointCarousel: Ui,
4724
4722
  InteriorSelector: Gi,
4725
4723
  Compass: tn,
4726
4724
  SingleImage: rn,
@@ -4806,7 +4804,7 @@ const ao = /* @__PURE__ */ C(oo, [["render", ro], ["__scopeId", "data-v-547d8112
4806
4804
  };
4807
4805
  },
4808
4806
  provide() {
4809
- const e = this.i18n ? new R(this.i18n.labels, this.i18n.language) : new R();
4807
+ const e = this.i18n ? new U(this.i18n.labels, this.i18n.language) : new U();
4810
4808
  return {
4811
4809
  localMode: this.localMode,
4812
4810
  fileLoader: this.fileLoader,
@@ -5122,7 +5120,7 @@ function uo(e) {
5122
5120
  }
5123
5121
  async function ho(e) {
5124
5122
  try {
5125
- return (await ke.get(e)).data;
5123
+ return (await fe.get(e)).data;
5126
5124
  } catch (t) {
5127
5125
  throw console.error(t), new Error(t);
5128
5126
  }
@@ -5147,7 +5145,7 @@ const po = { class: "virtual-tour-v2-wrapper" }, go = {
5147
5145
  class: "btn-placeholder"
5148
5146
  }, Co = { key: 0 };
5149
5147
  function _o(e, t, i, r, n, s) {
5150
- const a = c("mini-map-v-2"), d = c("single-image"), p = c("v-btn"), v = c("floor-level"), w = c("settings-u-i"), S = c("disclaimer"), g = c("compass"), b = c("time-of-day"), k = c("tutorial"), I = c("full-screen-button"), O = c("social-share"), Le = c("view-mode-toggle"), ae = c("waypoint-carousel"), Me = c("interior-selector"), xe = c("player");
5148
+ const a = c("mini-map-v-2"), d = c("single-image"), p = c("v-btn"), v = c("floor-level"), w = c("settings-u-i"), S = c("disclaimer"), g = c("compass"), b = c("time-of-day"), k = c("tutorial"), I = c("full-screen-button"), O = c("social-share"), Be = c("view-mode-toggle"), me = c("waypoint-carousel"), Fe = c("interior-selector"), Ee = c("player");
5151
5149
  return l(), m("div", po, [
5152
5150
  n.error ? (l(), m("div", go, "Error loading the player!!")) : f("", !0),
5153
5151
  o("div", vo, [
@@ -5165,7 +5163,7 @@ function _o(e, t, i, r, n, s) {
5165
5163
  onSetBackgroundImage: s.setMinimapBackgroundImage
5166
5164
  }, null, 8, ["allCameras", "rootUrl", "level", "backgroundImage", "minimapJSON", "rotation", "currentCamera", "minimapCamera", "onSetBackgroundImage"])) : f("", !0),
5167
5165
  s.interiorId && n.currentCameraId ? (l(), m("div", fo, [
5168
- u(xe, {
5166
+ u(Ee, {
5169
5167
  ref: "player",
5170
5168
  "file-loader": i.fileLoader,
5171
5169
  style: M({ zIndex: n.showStaticImage ? 1 : 2 }),
@@ -5309,12 +5307,12 @@ function _o(e, t, i, r, n, s) {
5309
5307
  ]),
5310
5308
  "bottom-center": h(() => [
5311
5309
  n.showUI && i.showCarousel ? (l(), m("div", Co, [
5312
- i.displayViewModeSwitch ? (l(), y(Le, {
5310
+ i.displayViewModeSwitch ? (l(), y(Be, {
5313
5311
  key: 0,
5314
5312
  "show-static-image": n.showStaticImage,
5315
5313
  onToggle: s.toggleViewMode
5316
5314
  }, null, 8, ["show-static-image", "onToggle"])) : f("", !0),
5317
- n.showUI && n.fullScreen.isActive ? (l(), y(ae, {
5315
+ n.showUI && n.fullScreen.isActive ? (l(), y(me, {
5318
5316
  key: 1,
5319
5317
  class: E([n.fullScreen.isActive ? "full-screen" : ""]),
5320
5318
  thumbnails: s.thumbnails,
@@ -5326,7 +5324,7 @@ function _o(e, t, i, r, n, s) {
5326
5324
  ])) : f("", !0)
5327
5325
  ]),
5328
5326
  "bottom-right": h(() => [
5329
- n.showUI && i.showInteriorOptions && s.interiorsWithImage ? (l(), y(Me, {
5327
+ n.showUI && i.showInteriorOptions && s.interiorsWithImage ? (l(), y(Fe, {
5330
5328
  key: 0,
5331
5329
  availableArchetypes: s.interiorsWithImage,
5332
5330
  selectedIndex: s.selectedInteriorIndex,
@@ -5335,7 +5333,7 @@ function _o(e, t, i, r, n, s) {
5335
5333
  ]),
5336
5334
  _: 1
5337
5335
  }, 8, ["file-loader", "style", "showStaticImage", "isFullScreen", "rootUrl", "currentCameraId", "mouse-sensitivity", "is-in-iframe", "onNewCameraCallback", "onNewRotationCallback", "onNewFloorCallback", "onNewFovCallback", "onNewSizeCallback", "onPlayerApiCallback"]),
5338
- i.showCarousel && n.thumbsJSON ? (l(), y(ae, {
5336
+ i.showCarousel && n.thumbsJSON ? (l(), y(me, {
5339
5337
  key: 0,
5340
5338
  thumbnails: s.thumbnails,
5341
5339
  active: n.currentThumbnailIndex,
@@ -5347,7 +5345,70 @@ function _o(e, t, i, r, n, s) {
5347
5345
  ])
5348
5346
  ]);
5349
5347
  }
5350
- const Io = /* @__PURE__ */ C(co, [["render", _o], ["__scopeId", "data-v-5e036d71"]]), Mo = { QiBuildingChooser: _t, QiApartmentChooser: li, VirtualTourV2: Io };
5348
+ const Io = /* @__PURE__ */ C(co, [["render", _o], ["__scopeId", "data-v-5e036d71"]]), So = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
5349
+ __proto__: null,
5350
+ QiApartmentChooser: At,
5351
+ QiApartmentChooserNavigation: Se,
5352
+ QiApartmentChooserRaster: ie,
5353
+ QiApartmentChooserRotator: Ae,
5354
+ QiApartmentChooserSvg: ne,
5355
+ QiBuildingChooser: li,
5356
+ QiBuildingChooserRaster: re,
5357
+ QiBuildingChooserRasterOverlay: xe,
5358
+ QiBuildingChooserSceneImageStack: he,
5359
+ QiBuildingChooserSunSimControl: ue,
5360
+ QiBuildingChooserSvg: oe,
5361
+ QiFloatingCard: J,
5362
+ QiHoverProbe: N,
5363
+ QiNorthDirection: X,
5364
+ QiZoomBox: G,
5365
+ VirtualTourV2: Io
5366
+ }, Symbol.toStringTag, { value: "Module" }));
5367
+ class xo {
5368
+ constructor(t) {
5369
+ this._data = t;
5370
+ }
5371
+ getPixel(t, i) {
5372
+ const r = this._data[t][i];
5373
+ if (r !== " ") {
5374
+ const n = Number.parseInt(r);
5375
+ return [n, n, n, 255];
5376
+ } else
5377
+ return [0, 0, 0, 0];
5378
+ }
5379
+ }
5380
+ const Bo = function(t) {
5381
+ Object.entries(So).forEach(([i, r]) => {
5382
+ t.component(i, r);
5383
+ });
5384
+ };
5351
5385
  export {
5352
- Mo as default
5386
+ se as BatchLoadTracker,
5387
+ Y as BuildingMap,
5388
+ Me as BuildingPickerResourceProvider,
5389
+ pt as BuildingViewerModel,
5390
+ Q as CanvasRaster,
5391
+ Z as DayOfYearSelector,
5392
+ U as I18N,
5393
+ At as QiApartmentChooser,
5394
+ Se as QiApartmentChooserNavigation,
5395
+ ie as QiApartmentChooserRaster,
5396
+ Ae as QiApartmentChooserRotator,
5397
+ ne as QiApartmentChooserSvg,
5398
+ li as QiBuildingChooser,
5399
+ re as QiBuildingChooserRaster,
5400
+ xe as QiBuildingChooserRasterOverlay,
5401
+ he as QiBuildingChooserSceneImageStack,
5402
+ ue as QiBuildingChooserSunSimControl,
5403
+ oe as QiBuildingChooserSvg,
5404
+ J as QiFloatingCard,
5405
+ N as QiHoverProbe,
5406
+ X as QiNorthDirection,
5407
+ G as QiZoomBox,
5408
+ H as ResourceLoader,
5409
+ xo as SampleRaster,
5410
+ Je as SceneRotator,
5411
+ Io as VirtualTourV2,
5412
+ Bo as default,
5413
+ Ie as throttle
5353
5414
  };