diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8f9d799
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules/*
+dist/*
\ No newline at end of file
diff --git a/builddate.js b/builddate.js
deleted file mode 100644
index 784550d..0000000
--- a/builddate.js
+++ /dev/null
@@ -1 +0,0 @@
-var CONF_builddate="20250317-222603"
diff --git a/compile b/compile
deleted file mode 100755
index 690ab80..0000000
--- a/compile
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-cd src
-
-tsc # Uses the tsconfig.json file
-
-cat GPL3.js swap.js > eendraadschema.js
-mv eendraadschema.js ..
-rm swap.js
-
-cd ..
-
-echo "var CONF_builddate=\""`date +%Y%m%d-%H%M%S`"\"" > builddate.js
diff --git a/css/about.css b/css/about.css
index 554035c..ac381ad 100644
--- a/css/about.css
+++ b/css/about.css
@@ -1,9 +1,9 @@
body {
-# background-color: white;
+/* background-color: white; */
}
html {
- # background: url(bg.jpg) no-repeat center center fixed;
+ /* background: url(bg.jpg) no-repeat center center fixed; */
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
diff --git a/eendraadschema.js b/eendraadschema.js
deleted file mode 100644
index 87c6cad..0000000
--- a/eendraadschema.js
+++ /dev/null
@@ -1,10935 +0,0 @@
-/*** Eendraadschema ***
-
-=== Community edition ===
-
-Copyright (C) 2019-2025 Ivan Goethals GPLv3
-
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation, either version 3 of the License, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see http://www.gnu.org/licenses/.
-
-The source code of this community edition is hosted on Github at
-https://github.com/igoethal/eendraadschema.
-
-=== Exclusive license ===
-
-Notwithstanding the above, the original and sole author of this edition,
-Ivan Goethals, reserves the exclusive right to create derivative works of
-this software and distribute them under different licensing terms, including
-but not limited to proprietary licenses. This includes the ability to develop
-and offer a hosted edition with additional features not available in the
-community edition. This right does not extend to derivative works produced by
-others based on this community edition.
-
-=== Embedded content ===
-
-== Pako.js ==
-
-This program uses the Pako.js entropy coding library. Pako is released under
-an MIT license by Andrey Tupitsin and Vitaly Puzrin. For more information on
-Pako and the full license text, please visit https://github.com/nodeca/pako
-
-== Zlib ==
-
-Pako implements ZLib in javascript. Zlib is released under the ZLIB License.
-See https://www.zlib.net/zlib_license.html
-
-== jsPDF ==
-
-This program uses the jsPDF library to transform SVG images into PDF files.
-The jsPDF license is as follows
-
-Copyright
-(c) 2010-2021 James Hall, https://github.com/MrRio/jsPDF
-(c) 2015-2021 yWorks GmbH, https://www.yworks.com/
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-};
-var __generator = (this && this.__generator) || function (thisArg, body) {
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
- function verb(n) { return function (v) { return step([n, v]); }; }
- function step(op) {
- if (f) throw new TypeError("Generator is already executing.");
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
- if (y = 0, t) op = [op[0] & 2, t.value];
- switch (op[0]) {
- case 0: case 1: t = op; break;
- case 4: _.label++; return { value: op[1], done: false };
- case 5: _.label++; y = op[1]; op = [0]; continue;
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
- default:
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
- if (t[2]) _.ops.pop();
- _.trys.pop(); continue;
- }
- op = body.call(thisArg, _);
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
- }
-};
-var __assign = (this && this.__assign) || function () {
- __assign = Object.assign || function(t) {
- for (var s, i = 1, n = arguments.length; i < n; i++) {
- s = arguments[i];
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
- t[p] = s[p];
- }
- return t;
- };
- return __assign.apply(this, arguments);
-};
-var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- if (typeof b !== "function" && b !== null)
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
-})();
-var __rest = (this && this.__rest) || function (s, e) {
- var t = {};
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
- t[p] = s[p];
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
- t[p[i]] = s[p[i]];
- }
- return t;
-};
-function deepClone(obj) {
- var _out = new obj.constructor;
- var getType = function (n) {
- return Object.prototype.toString.call(n).slice(8, -1);
- };
- for (var _key in obj) {
- if (obj.hasOwnProperty(_key)) {
- _out[_key] = getType(obj[_key]) === 'Object' || getType(obj[_key]) === 'Array' ? deepClone(obj[_key]) : obj[_key];
- }
- }
- return _out;
-}
-/**
- * Returns true if the current mode is a development mode.
- * This is determined by the presence of a 'dev' parameter in the URL.
- *
- * @returns {boolean} True if this is a development mode, false otherwise.
- */
-function isDevMode() {
- try {
- var urlParams = new URLSearchParams(window.location.search);
- return urlParams.has('dev');
- }
- catch (error) {
- console.error('Error checking for dev mode:', error);
- return false;
- }
-}
-// Function for length of a string in 8 bit bytes
-var byteSize = function (str) { return new Blob([str]).size; };
-function contains(a, obj) {
- for (var i = 0; i < a.length; i++) {
- if (a[i] === obj) {
- return true;
- }
- }
- return false;
-}
-function isInt(value) {
- return !isNaN(value) &&
- parseInt(value) == value &&
- !isNaN(parseInt(value, 10));
-}
-function svgTextWidth(input, fontsize, options) {
- if (fontsize === void 0) { fontsize = 10; }
- if (options === void 0) { options = ''; }
- var div = document.createElement('div');
- div.innerHTML = '';
- var tryoutdiv = document.body;
- /*if (document.getElementById("configsection").style.display === 'block') {
- tryoutdiv = document.getElementById("configsection") as HTMLElement;
- } else if (document.getElementById("outerdiv").style.display === 'block') {
- tryoutdiv = document.getElementById("outerdiv") as HTMLElement;
- } else {
- tryoutdiv = document.getElementById("right_col_inner") as HTMLElement;
- }*/
- tryoutdiv.appendChild(div);
- var width = div.children[0].children[0].getBBox().width;
- tryoutdiv.removeChild(div);
- return (Math.ceil(width));
-}
-function flattenSVG(SVGstruct, shiftx, shifty, node, overflowright) {
- if (overflowright === void 0) { overflowright = 0; }
- if (node == 0)
- structure.print_table.pagemarkers.clear();
- var str = "";
- var X = new XMLSerializer();
- var parser = new DOMParser();
- var outstruct = SVGstruct;
- if (SVGstruct.localName == "svg") {
- if (outstruct.attributes.getNamedItem("x")) { // make SVG a 0,0 element
- shiftx += parseFloat(outstruct.attributes.getNamedItem("x").nodeValue);
- outstruct.attributes.getNamedItem("x").nodeValue = 0;
- }
- if (outstruct.attributes.getNamedItem("y")) { // make SVG a 0,0 element
- shifty += parseFloat(outstruct.attributes.getNamedItem("y").nodeValue);
- outstruct.attributes.getNamedItem("y").nodeValue = 0;
- }
- for (var i = 0; i < SVGstruct.children.length; i++) {
- str = str.concat(flattenSVG(SVGstruct.children[i], shiftx, shifty, node + 1), "\n");
- }
- if (node <= 0) {
- if (outstruct.attributes.getNamedItem("width")) { // make SVG a 0,0 element
- str = '';
- }
- else {
- str = '';
- }
- }
- }
- else {
- if (SVGstruct.localName == "line") {
- if (shiftx != 0) {
- outstruct.attributes.getNamedItem("x1").nodeValue = parseFloat(outstruct.attributes.getNamedItem("x1").nodeValue) + shiftx;
- outstruct.attributes.getNamedItem("x2").nodeValue = parseFloat(outstruct.attributes.getNamedItem("x2").nodeValue) + shiftx;
- }
- if (shifty != 0) {
- outstruct.attributes.getNamedItem("y1").nodeValue = parseFloat(outstruct.attributes.getNamedItem("y1").nodeValue) + shifty;
- outstruct.attributes.getNamedItem("y2").nodeValue = parseFloat(outstruct.attributes.getNamedItem("y2").nodeValue) + shifty;
- }
- }
- if (SVGstruct.localName == "use") {
- if (shiftx != 0) {
- outstruct.attributes.getNamedItem("x").nodeValue = parseFloat(outstruct.attributes.getNamedItem("x").nodeValue) + shiftx;
- }
- if (shifty != 0) {
- outstruct.attributes.getNamedItem("y").nodeValue = parseFloat(outstruct.attributes.getNamedItem("y").nodeValue) + shifty;
- }
- }
- if (SVGstruct.localName == "rect") {
- if (shiftx != 0) {
- outstruct.attributes.getNamedItem("x").nodeValue = parseFloat(outstruct.attributes.getNamedItem("x").nodeValue) + shiftx;
- }
- if (shifty != 0) {
- outstruct.attributes.getNamedItem("y").nodeValue = parseFloat(outstruct.attributes.getNamedItem("y").nodeValue) + shifty;
- }
- }
- if (SVGstruct.localName == "circle") {
- if (shiftx != 0) {
- outstruct.attributes.getNamedItem("cx").nodeValue = parseFloat(outstruct.attributes.getNamedItem("cx").nodeValue) + shiftx;
- }
- if (shifty != 0) {
- outstruct.attributes.getNamedItem("cy").nodeValue = parseFloat(outstruct.attributes.getNamedItem("cy").nodeValue) + shifty;
- }
- }
- if (SVGstruct.localName == "text") {
- outstruct.attributes.getNamedItem("x").nodeValue = parseFloat(outstruct.attributes.getNamedItem("x").nodeValue) + shiftx;
- outstruct.attributes.getNamedItem("y").nodeValue = parseFloat(outstruct.attributes.getNamedItem("y").nodeValue) + shifty;
- if (outstruct.attributes.getNamedItem("transform")) {
- if (outstruct.attributes.getNamedItem("transform").value.includes('rotate')) {
- outstruct.attributes.getNamedItem("transform").value = "rotate(-90 " +
- outstruct.attributes.getNamedItem("x").nodeValue + "," +
- outstruct.attributes.getNamedItem("y").nodeValue + ")";
- }
- else {
- outstruct.attributes.getNamedItem("transform").value = "scale(-1,1) translate(-" +
- outstruct.attributes.getNamedItem("x").nodeValue * 2 + ",0)";
- }
- }
- }
- if (SVGstruct.localName == "polygon") {
- var polystr_out = "";
- var polystr_in = outstruct.attributes.getNamedItem("points").nodeValue;
- var splitted_in = polystr_in.split(" ");
- for (var countstr = 0; countstr < splitted_in.length; countstr++) {
- var points_in = splitted_in[countstr].split(",");
- polystr_out += (points_in[0] * 1 + shiftx) + ',' + (points_in[1] * 1 + shifty);
- if (countstr < splitted_in.length - 1) {
- polystr_out += ' ';
- }
- }
- outstruct.attributes.getNamedItem("points").nodeValue = polystr_out;
- }
- str = X.serializeToString(outstruct);
- //remove all the xmlns tags
- var regex = /xmlns="[^"]+"/g;
- str = str.replace(regex, '');
- }
- structure.print_table.pagemarkers.addMarker(node, shiftx);
- return str;
-}
-function flattenSVGfromString(xmlstr, overflowright) {
- if (overflowright === void 0) { overflowright = 0; }
- var str = "";
- var parser = new DOMParser();
- var xmlDoc = parser.parseFromString(xmlstr, "text/xml"); //important to use "text/xml"
- str = flattenSVG(xmlDoc.childNodes[0], 0, 0, 0, overflowright);
- return str;
-}
-function htmlspecialchars(my_input) {
- var returnstr;
- if (typeof (my_input) == 'undefined')
- returnstr = "";
- else
- returnstr = my_input.toString();
- var map = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
- };
- return returnstr.replace(/[&<>"']/g, function (m) { return map[m]; });
-}
-function browser_ie_detected() {
- var ua = window.navigator.userAgent;
- var msie = ua.indexOf("MSIE ");
- var trident = ua.indexOf('Trident/');
- if ((msie > 0) || (trident > 0))
- return true;
- else
- return false;
-}
-var randomId = (function () {
- var counters = {};
- return function (prefix) {
- if (prefix === void 0) { prefix = "Rnd_"; }
- if (!(prefix in counters)) {
- counters[prefix] = 0;
- }
- var value = counters[prefix];
- counters[prefix]++;
- return "".concat(prefix).concat(value.toString());
- };
-})();
-var Session = /** @class */ (function () {
- function Session() {
- this.sessionKey = 'SessionJS';
- this.newUser = false;
- var storedSessionId = localStorage.getItem(this.sessionKey);
- if (storedSessionId) {
- this.sessionId = storedSessionId;
- }
- else {
- this.sessionId = this.generateRandomBase64String(22);
- localStorage.setItem(this.sessionKey, this.sessionId);
- this.newUser = true;
- }
- }
- Session.prototype.generateRandomBase64String = function (length) {
- var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
- var result = '';
- var charactersLength = characters.length;
- for (var i = 0; i < length; i++) {
- var randomIndex = Math.floor(Math.random() * charactersLength);
- result += characters[randomIndex];
- }
- return result;
- };
- Session.prototype.getSessionId = function () {
- return this.sessionId;
- };
- Session.prototype.isNewUser = function () {
- return this.newUser;
- };
- return Session;
-}());
-var SVGelement = /** @class */ (function () {
- function SVGelement() {
- this.data = "";
- this.xleft = 0;
- this.xright = 0;
- this.xrightmin = 0;
- this.yup = 0;
- this.ydown = 0;
- }
- return SVGelement;
-}());
-/**
- * Manages the addition and removal of event listeners on HTML elements.
- */
-var EventManager = /** @class */ (function () {
- function EventManager() {
- this.listeners = [];
- }
- /**
- * Adds an event listener to a specified HTML element. If a listener of the same
- * type already exists on the element, it is removed before adding the new one.
- *
- * @param element - The HTML element to attach the event listener to.
- * @param type - The type of the event.
- * @param listener - The event listener function or object.
- */
- EventManager.prototype.addEventListener = function (element, type, listener) {
- var existingListenerIndex = this.listeners.findIndex(function (l) { return l.element === element && l.type === type; });
- if (existingListenerIndex !== -1) {
- var existingListener = this.listeners[existingListenerIndex];
- element.removeEventListener(type, existingListener.listener);
- this.listeners.splice(existingListenerIndex, 1);
- }
- this.listeners.push({ element: element, type: type, listener: listener });
- element.addEventListener(type, listener);
- this.cleanup(); // Before we proceed, remove all listeners for elements that no longer exist
- };
- /**
- * Removes all event listeners managed by this EventManager instance.
- */
- EventManager.prototype.removeAllEventListeners = function () {
- this.listeners.forEach(function (_a) {
- var element = _a.element, type = _a.type, listener = _a.listener;
- element.removeEventListener(type, listener);
- });
- this.listeners = [];
- };
- /**
- * Disposes of the EventManager by removing all event listeners.
- */
- EventManager.prototype.dispose = function () {
- this.removeAllEventListeners();
- };
- /**
- * Removes all listeners for which the HTML element no longer exists.
- */
- EventManager.prototype.cleanup = function () {
- this.listeners = this.listeners.filter(function (_a) {
- var element = _a.element, type = _a.type, listener = _a.listener;
- if (!document.contains(element)) {
- element.removeEventListener(type, listener);
- return false;
- }
- return true;
- });
- };
- return EventManager;
-}());
-/**
- * A class to handle a list of potential page breaks or markers in the form {depth,xpos} with depth how nested
- * they are (lower depth is better to include a page break) and xpos the location in pixels in the SVG where
- * the break could be added
- */
-var MarkerList = /** @class */ (function () {
- function MarkerList() {
- this.markers = [];
- }
- /**
- * Clear the list of markers
- */
- MarkerList.prototype.clear = function () {
- this.markers = [];
- };
- /**
- * Add a marker to the markerlist.
- * If the same marker already exists, no new one will be added.
- * @param depth - The depth of the marker, or how nested it is (lower depth is better for page breaks).
- * @param xpos - The x-coordinate position of the marker.
- */
- MarkerList.prototype.addMarker = function (depth, xpos) {
- // Check if the marker already exists
- var exists = this.markers.some(function (marker) { return marker.depth === depth && marker.xpos === xpos; });
- if (!exists) {
- this.markers.push({ depth: depth, xpos: xpos });
- }
- };
- /**
- * Sorts the markers by their x-coordinate position in ascending order.
- */
- MarkerList.prototype.sort = function () {
- this.markers.sort(function (a, b) { return a.xpos - b.xpos; });
- };
- /**
- * Looks for the marker in the half-open internal (minx, maxx] with the lowest possible depth.
- * If multiple markers exist with the same depth, the one with the highest xpos is returned.
- * If no suitable marker is found, a dummy {depth=null, xpos=maxx} is returned.
- * @param minx - Minimal x for any markers that will be considered.
- * @param maxx - Maximal x for any markers that will be considered.
- * @returns The marker with the lowest depth (and highest xpos if multiple exist) or a dummy marker if none are found.
- */
- MarkerList.prototype.findMinDepth = function (minx, maxx) {
- // Filter markers within the range
- var filteredMarkers = this.markers.filter(function (marker) { return marker.xpos > minx && marker.xpos <= maxx; });
- if (filteredMarkers.length === 0) {
- return { depth: null, xpos: maxx }; // No markers in the specified range so we just take the maximum
- }
- // Find the marker with the lowest depth, if multiple exist with the same depth, take the one with the highest xpos
- return filteredMarkers.reduce(function (minDepthMarker, marker) {
- if (marker.depth < minDepthMarker.depth ||
- (marker.depth === minDepthMarker.depth && marker.xpos > minDepthMarker.xpos)) {
- return marker;
- }
- return minDepthMarker;
- }, filteredMarkers[0]);
- };
- return MarkerList;
-}());
-/**
- * Store information on what part of the SVG lands on one specific page
- * The height is the final height in number of pixels
- * The start and stop are the x-locations in pixels of the part of the total SVG that needs to land on this particular page
- */
-var Page_Info = /** @class */ (function () {
- function Page_Info() {
- this.height = 0;
- this.start = 0;
- this.stop = 0;
- }
- return Page_Info;
-}());
-/**
- * Stores all information about pagination and how pages will be printed.
- * Can perform automatic pagination or ask the user to paginate.
- *
- * We don't use private variables in this class as we want to serialize it (JSON)
- */
-var Print_Table = /** @class */ (function () {
- /**
- * Initialize list of pages (foresee at least 1 page) and pagemarkers
- */
- function Print_Table() {
- this.height = 0; //How high is the SVG that will be printed in pixels
- this.maxwidth = 0; //What is the width of the SVG that will be printed in pixels and therefore the maximum printing width
- this.displaypage = 0;
- this.enableAutopage = true; //Flag to indicate if automatic pagination is used or not
- this.pages = new Array();
- this.pages.push(new Page_Info());
- this.pagemarkers = new MarkerList;
- }
- /**
- * Set papersize to either "A4" or "A3"
- * @param papersize - A string, if it is neither "A4" or "A3", the papersize will default to "A4".
- */
- Print_Table.prototype.setPaperSize = function (papersize) {
- this.papersize = (papersize === "A3" ? "A3" : "A4");
- };
- /**
- * Get papersize. If papersize was not yet defined, it is forced to "A4"
- * @returns The papersize, either "A3" or "A4"
- */
- Print_Table.prototype.getPaperSize = function () {
- if (!this.papersize)
- this.papersize = "A4";
- return (this.papersize);
- };
- /**
- * Set displayheight of all pages to height
- * @param height - Height in pixels
- */
- Print_Table.prototype.setHeight = function (height) {
- this.height = height;
- this.pages.forEach(function (page) { page.height = height; });
- };
- /**
- * Get displayheight
- * @returns Height in pixels
- */
- Print_Table.prototype.getHeight = function () {
- return (this.height);
- };
- /**
- * Set modevertical to either "alles" (meaning we show the full height of the page) or "kies" meaning the user can choose
- * @param more - Either "alles" or "kies"
- */
- Print_Table.prototype.setModeVertical = function (mode) {
- this.modevertical = (mode === "kies" ? "kies" : "alles");
- this.forceCorrectFigures();
- };
- /**
- * Get modevertical
- * @returns either "alles" or "kies"
- */
- Print_Table.prototype.getModeVertical = function () {
- this.forceCorrectFigures();
- return (this.modevertical);
- };
- /**
- * Checks that all start and stop position of pages are valid
- * For instance, the startx position should never be higher than the stopx.
- * In addition, the SVG always goes from left to right over the pages so the startx
- * of a new page cannot be lower than the stopx of the page before.
- */
- Print_Table.prototype.forceCorrectFigures = function () {
- var _this = this;
- if (!this.modevertical) {
- this.modevertical = "alles";
- }
- switch (this.modevertical) {
- case "kies":
- this.starty = Math.min(Math.max(0, this.starty), this.height);
- this.stopy = Math.min(Math.max(this.starty, this.stopy), this.height);
- break;
- default:
- this.starty = 0;
- this.stopy = this.height;
- }
- this.pages[this.pages.length - 1].stop = this.maxwidth;
- this.pages.forEach(function (page, index) {
- if (page.stop < 0)
- page.stop = 0;
- if (page.start < 0)
- page.start = 0;
- if (index > 0) {
- page.start = _this.pages[index - 1].stop;
- }
- if (page.stop > _this.maxwidth) {
- _this.pages[_this.pages.length - 1].stop = _this.maxwidth;
- }
- if (page.start > page.stop) {
- page.start = page.stop;
- }
- });
- };
- /**
- * Sets the maximum width of the SVG to be displayed.
- * As a general rule this equals the width of the SVG itself in pixels
- * @param maxwidth
- */
- Print_Table.prototype.setMaxWidth = function (maxwidth) {
- this.maxwidth = maxwidth;
- this.forceCorrectFigures();
- };
- /**
- * Gets the maximum width that can be displayed or printed
- * @returns maxwidth, as a general rule this equals the width of the SVG itsef in pixels
- */
- Print_Table.prototype.getMaxWidth = function () {
- return (this.maxwidth);
- };
- /**
- * Returns the starty position of the page that will be displayed or printed
- * @returns starty
- */
- Print_Table.prototype.getstarty = function () {
- this.forceCorrectFigures();
- return (this.starty);
- };
- /**
- * Returns the stopy position of the page that will be displayed or printed
- * @returns stopy
- */
- Print_Table.prototype.getstopy = function () {
- this.forceCorrectFigures();
- return (this.stopy);
- };
- /**
- * Sets the starty position of the page that will be displayed or printed
- * @param starty
- */
- Print_Table.prototype.setstarty = function (starty) {
- this.starty = starty;
- this.forceCorrectFigures;
- };
- /**
- * Sets the stopy position of the page that will be displayed or printed
- * @param starty
- */
- Print_Table.prototype.setstopy = function (stopy) {
- this.stopy = stopy;
- this.forceCorrectFigures;
- };
- /**
- * Sets the stopx position of one specific page to a desired value.
- * The function calls forceCorrectFigures() afterwards to ensure the natural flow of pages (left to right)
- * is respected. Note that stopx in the underlying Page_Info object is called stop and we cannot change that
- * anymore as the classes are used for serialization.
- * @param page - page number for which we want to set the stopx (starts counting at zero)
- * @param stop - stopx position to set
- */
- Print_Table.prototype.setStop = function (page, stop) {
- if (page > 0) {
- if (stop < this.pages[page - 1].stop)
- stop = this.pages[page - 1].stop;
- }
- if (page < this.pages.length - 1) {
- if (stop > this.pages[page + 1].stop)
- stop = this.pages[page + 1].stop;
- }
- if (stop > this.maxwidth)
- stop = this.maxwidth;
- this.pages[page].stop = stop;
- this.forceCorrectFigures();
- };
- /**
- * Automatically create pages based on pagemarkers
- */
- Print_Table.prototype.autopage = function () {
- /* Autopage uses some ratio's determined by the useful SVG drawing size on the PDF. This depends on the margins configured in print.js
- At present all of this is still hard-coded. Should become a function of print.js
-
- A4
-
- Height: 210-20-30-5-5 --> 150
- Width: 297-20 --> 277
- Ratio: 1.8467
-
- A3
-
- Height: 297-20-30-5-5 --> 237
- Width: 420-20 --> 400
- Ratio: 1.6878
- */
- var _this = this;
- //First set all pages to maximum to avoid that we bump into boundaries
- this.pages.forEach(function (page, index) {
- page.stop = _this.maxwidth;
- });
- var height = this.getstopy() - this.getstarty();
- var maxsvgwidth = height * (this.getPaperSize() == "A3" ? 1.6878 : 1.8467);
- var minsvgwidth = 3 / 4 * maxsvgwidth;
- var page = 0;
- var pos = 0;
- if (maxsvgwidth > 0) {
- while ((this.maxwidth - pos) > maxsvgwidth) { // The undivided part still does not fit on a page
- pos = this.pagemarkers.findMinDepth(pos + minsvgwidth, pos + maxsvgwidth).xpos;
- while (this.pages.length < page + 2)
- this.addPage();
- this.setStop(page, pos);
- page++;
- }
- }
- // The last page stops at the maximum size of the SVG
- this.setStop(page, this.maxwidth);
- // Delete unneeded pages at the end
- for (var i = this.pages.length - 1; i > page; i--) {
- this.deletePage(i);
- }
- };
- /**
- * Add a page
- */
- Print_Table.prototype.addPage = function () {
- var page_info;
- page_info = new Page_Info();
- page_info.height = this.height;
- page_info.start = this.pages[this.pages.length - 1].stop;
- page_info.stop = this.maxwidth;
- this.pages.push(page_info);
- };
- /**
- * Remove a page
- * @param page - number of the page to be removed, starting at 0
- */
- Print_Table.prototype.deletePage = function (page) {
- if (page == 0) {
- this.pages[1].start = 0;
- }
- else {
- this.pages[page - 1].stop = this.pages[page].stop;
- }
- this.pages.splice(page, 1);
- };
- /**
- * Display a Select box to choose papersize (A3 or A4)
- * The table is displayed in the HTMLElement div that is given as a parameter to the function.
- * If any manipulation is done by the user that would require redrawing the print preview, the redrawCallBack function is executed
- * from within this function
- * @param div - Existing HTMLElement where the table will be inserted
- * @param redrawCallBack - Callback function that ensures everything that needs to be redrawn is redrawn
- */
- Print_Table.prototype.insertHTMLselectPaperSize = function (div, redrawCallBack) {
- var _this = this;
- var select = document.createElement('select');
- select.id = 'select_papersize_input';
- var optionA4 = document.createElement('option');
- optionA4.value = 'A4';
- optionA4.textContent = 'A4';
- var optionA3 = document.createElement('option');
- optionA3.value = 'A3';
- optionA3.textContent = 'A3';
- if (this.papersize == "A3")
- optionA3.selected = true;
- else
- optionA4.selected = true;
- select.appendChild(optionA4);
- select.appendChild(optionA3);
- select.onchange = function (event) {
- _this.setPaperSize(event.target.value);
- redrawCallBack();
- };
- div.appendChild(select);
- };
- /**
- * Display a Select box to choose dpi (300 or 600)
- * The table is displayed in the HTMLElement div that is given as a parameter to the function.
- * If any manipulation is done by the user that would require redrawing the print preview, the redrawCallBack function is executed
- * from within this function
- * @param div - Existing HTMLElement where the table will be inserted
- * @param redrawCallBack - Callback function that ensures everything that needs to be redrawn is redrawn
- */
- Print_Table.prototype.insertHTMLselectdpi = function (div, redrawCallBack) {
- var select = document.createElement('select');
- select.id = "select_dpi_input";
- var option300 = document.createElement('option');
- option300.value = '300';
- option300.textContent = '300dpi (standaard)';
- var option600 = document.createElement('option');
- option600.value = '600';
- option600.textContent = '600dpi (beter maar trager)';
- if (typeof (structure.properties.dpi) == 'undefined')
- structure.properties.dpi = 300;
- if (structure.properties.dpi == 600)
- option600.selected = true;
- else
- option300.selected = true;
- select.appendChild(option300);
- select.appendChild(option600);
- select.onchange = function (event) {
- structure.properties.dpi = parseInt(event.target.value, 0);
- };
- div.appendChild(select);
- };
- /**
- * Display a Check box to decide if one wants to use autopage or not.
- * If autopage is enabled, we also recalculate the page boundaries
- * The checkbox is displayed in the HTMLElement div that is given as a parameter to the function.
- * If any manipulation is done by the user that would require redrawing the print preview, the redrawCallBack function is executed
- * from within this function
- * @param div - Existing HTMLElement where the table will be inserted
- * @param redrawCallBack - Callback function that ensures everything that needs to be redrawn is redrawn
- */
- Print_Table.prototype.insertHTMLcheckAutopage = function (div, redrawCallBack) {
- var _this = this;
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.id = 'autopage';
- checkbox.name = 'autopage';
- var label = document.createElement('label');
- label.htmlFor = 'autopage';
- label.textContent = "Handmatig over pagina's verdelen";
- if (this.enableAutopage) {
- this.setModeVertical("alles");
- this.autopage();
- }
- else {
- checkbox.checked = true;
- }
- div.append(checkbox);
- div.append(label);
- checkbox.onchange = function (event) {
- _this.enableAutopage = !event.target.checked;
- redrawCallBack();
- };
- };
- /**
- * Display a select box to choose the vertical mode.
- * If vertical mode is "kies", we also display input boxes to choose the starty and stopy positions.
- * The checkbox is displayed in the HTMLElement div that is given as a parameter to the function.
- * If any manipulation is done by the user that would require redrawing the print preview, the redrawCallBack function is executed
- * from within this function
- * @param div - Existing HTMLElement where the table will be inserted
- * @param redrawCallBack - Callback function that ensures everything that needs to be redrawn is redrawn
- */
- Print_Table.prototype.insertHTMLchooseVerticals = function (div, redrawCallBack) {
- var _this = this;
- var outstr = "";
- switch (this.modevertical) {
- case "kies":
- outstr += 'Hoogte ';
- outstr += ' StartY ';
- outstr += '';
- outstr += ' StopY ';
- outstr += '';
- break;
- case "alles":
- default:
- outstr += 'Hoogte ';
- }
- div.insertAdjacentHTML('beforeend', outstr);
- document.getElementById('select_modeVertical').onchange = function (event) {
- _this.setModeVertical(event.target.value);
- redrawCallBack();
- };
- if (this.modevertical == "kies") {
- document.getElementById('input_starty').onchange = function (event) {
- var starty = parseInt(event.target.value);
- if (isNaN(starty))
- starty = 0;
- _this.setstarty(starty);
- _this.forceCorrectFigures();
- redrawCallBack();
- };
- document.getElementById('input_stopy').onchange = function (event) {
- var stopy = parseInt(event.target.value);
- if (isNaN(stopy))
- stopy = _this.getHeight();
- ;
- _this.setstopy(stopy);
- _this.forceCorrectFigures();
- redrawCallBack();
- };
- }
- };
- /**
- * Display a button to force auto-pagination even when in manual mode
- * @param div - Existing HTMLElement where the table will be inserted
- * @param redrawCallBack - Callback function that ensures everything that needs to be redrawn is redrawn
- */
- Print_Table.prototype.insertHTMLsuggestXposButton = function (div, redrawCallBack) {
- var _this = this;
- var button = document.createElement('button');
- button.innerText = 'Suggereer X-posities';
- div.append(button);
- button.onclick = function () {
- _this.autopage();
- redrawCallBack();
- };
- };
- /**
- * Display a table where the user can choose start and stop positions for the x-coordinates in the SVG of each individual page
- * The table is displayed in the HTMLElement div that is given as a parameter to the function.
- * If any manipulation is done by the user that would require redrawing the print preview, the redrawCallBack function is executed
- * from within this function
- * @param div - Existing HTMLElement where the table will be inserted
- * @param redrawCallBack - Callback function that ensures everything that needs to be redrawn is redrawn
- */
- Print_Table.prototype.insertHTMLposxTable = function (div, redrawCallBack) {
- var _this = this;
- if (structure.print_table.enableAutopage)
- this.autopage();
- var outstr = "";
- var pagenum;
- outstr += '
";
- div.insertAdjacentHTML('beforeend', outstr);
- document.getElementById('Btn_Addpage').onclick = function () {
- _this.addPage();
- redrawCallBack();
- };
- document.querySelectorAll('button[id^="Btn_Deletepage_"]').forEach(function (button) {
- var match = button.id.match(/Btn_Deletepage_(\d+)/);
- if (match) {
- var page_1 = parseInt(match[1]);
- button.onclick = function () {
- _this.deletePage(page_1);
- redrawCallBack();
- };
- }
- });
- document.querySelectorAll('input[id^="input_stop_"]').forEach(function (input) {
- input.addEventListener('change', function (event) {
- var match = event.target.id.match(/input_stop_(\d+)/);
- if (match) {
- var page = parseInt(match[1]);
- var stop_1 = parseInt(event.target.value);
- _this.setStop(page, stop_1);
- redrawCallBack();
- }
- });
- });
- };
- return Print_Table;
-}());
-function HLDisplayPage() {
- structure.print_table.displaypage = parseInt(document.getElementById("id_select_page").value) - 1;
- printsvg();
-}
-function dosvgdownload() {
- var prtContent = document.getElementById("printsvgarea").innerHTML;
- var filename = document.getElementById("dosvgname").value;
- download_by_blob(prtContent, filename, 'data:image/svg+xml;charset=utf-8'); //Was text/plain
-}
-function getPrintSVGWithoutAddress(outSVG, page) {
- if (page === void 0) { page = structure.print_table.displaypage; }
- var scale = 1;
- var startx = structure.print_table.pages[page].start;
- var width = structure.print_table.pages[page].stop - startx;
- var starty = structure.print_table.getstarty();
- var height = structure.print_table.getstopy() - starty;
- var viewbox = '' + startx + ' ' + starty + ' ' + width + ' ' + height;
- var outstr = '';
- return (outstr);
-}
-function printsvg() {
- function generatePdf() {
- if (typeof (structure.properties.dpi) == 'undefined')
- structure.properties.dpi = 300;
- var svg = flattenSVGfromString(structure.toSVG(0, "horizontal").data);
- var pages = Array.from({ length: structure.print_table.pages.length }, function (_, i) { return i + 1; });
- var sitplanprint = structure.sitplan.toSitPlanPrint();
- printPDF(svg, structure.print_table, structure.properties, pages, document.getElementById("dopdfname").value, //filename
- document.getElementById("progress_pdf"), //HTML element where callback status can be given
- sitplanprint);
- }
- function renderPrintSVG(outSVG) {
- document.getElementById("printarea").innerHTML = '
' +
- getPrintSVGWithoutAddress(outSVG) +
- '
';
- }
- // First we generate an SVG image. We do this first because we need the size
- // We will display it at the end of this function
- var outSVG = new SVGelement();
- outSVG = structure.toSVG(0, "horizontal");
- var height = outSVG.yup + outSVG.ydown;
- var width = outSVG.xleft + outSVG.xright;
- structure.print_table.setHeight(height);
- structure.print_table.setMaxWidth(width + 10);
- // Then we display all the print options
- var outstr = "";
- var strleft = "";
- document.getElementById("configsection").innerHTML
- = '
'
- + ' ' // Generate PDF button comes here
- + ' ' // Selector to choose "A3" and "A4" comes here
- + ' ' // Selector for dpi 300 or 600 comes here
- + ' ' // Input box for filename of pdf document
- + ' ' // Area where status of pdf generation can be displayed
- + '
'
- + ' ' // Checkbox to choose if we want to auto paginate or not comes here
- + ' ' // An optional area to choose what part of the y-space of the image is shown
- + ' ' // A button to force auto pagination comes here
- + '
'
- + ' ' // Table with all startx and stopx comes here
- + '
'
- + '
'
- + '
Klik op de groene pijl om het schema over meerdere pagina\'s te printen en kies voor elke pagina de start- en stop-positie in het schema (in pixels).
'
- + '
Onderaan kan je bekijken welk deel van het schema op welke pagina belandt.
'
- + '
'
- + '
'
- + '
'
- + ' ';
- document.getElementById("configsection").insertAdjacentHTML('beforeend', outstr);
- structure.print_table.insertHTMLposxTable(document.getElementById('id_print_table'), printsvg);
- }
- strleft += '';
- strleft += 'Printvoorbeeld: Pagina (Enkel tekening, kies "Genereer PDF" om ook de tekstuele gegevens te zien)';
- strleft += '
';
- strleft += '
Sla tekening hieronder op als SVG en converteer met een ander programma naar PDF (bvb Inkscape).
';
- strleft += displayButtonPrintToPdf(); // This is only for the online version
- strleft += '';
- document.getElementById("configsection").insertAdjacentHTML('beforeend', strleft);
- // Finally we show the actual SVG
- renderPrintSVG(outSVG);
- toggleAppView('config');
-}
-var importExportUsingFileAPI = /** @class */ (function () {
- function importExportUsingFileAPI() {
- this.clear();
- //this.updateButtons();
- }
- importExportUsingFileAPI.prototype.clear = function () {
- this.saveNeeded = false;
- this.fileHandle = null;
- this.filename = null;
- };
- importExportUsingFileAPI.prototype.updateLastSaved = function () {
- var currentdate = new Date();
- this.lastsaved = currentdate.getHours().toString().padStart(2, '0') + ":" +
- currentdate.getMinutes().toString().padStart(2, '0') + ":" +
- currentdate.getSeconds().toString().padStart(2, '0');
- ;
- //If there is an object on the screen that needs updating, do it
- if (document.getElementById('exportscreen')) {
- showFilePage(); // Update the export screen if we are actually on the export screen
- }
- };
- importExportUsingFileAPI.prototype.setSaveNeeded = function (input) {
- var lastSaveNeeded = this.saveNeeded;
- this.saveNeeded = input;
- //if (input !== lastSaveNeeded) this.updateButtons();
- };
- importExportUsingFileAPI.prototype.readFile = function () {
- return __awaiter(this, void 0, void 0, function () {
- var _a, file, contents;
- return __generator(this, function (_b) {
- switch (_b.label) {
- case 0:
- _a = this;
- return [4 /*yield*/, window.showOpenFilePicker({
- types: [{
- description: 'Eendraadschema (.eds)',
- accept: { 'application/eds': ['.eds'] },
- }],
- })];
- case 1:
- _a.fileHandle = (_b.sent())[0];
- return [4 /*yield*/, this.fileHandle.getFile()];
- case 2:
- file = _b.sent();
- return [4 /*yield*/, file.text()];
- case 3:
- contents = _b.sent();
- this.filename = file.name;
- structure.properties.filename = file.name;
- this.setSaveNeeded(false);
- this.updateLastSaved(); // Needed because EDStoStructure whipes everything
- return [2 /*return*/, contents];
- }
- });
- });
- };
- importExportUsingFileAPI.prototype.saveAs = function (content) {
- return __awaiter(this, void 0, void 0, function () {
- var options, _a;
- return __generator(this, function (_b) {
- switch (_b.label) {
- case 0:
- options = {
- suggestedName: structure.properties.filename,
- types: [{
- description: 'Eendraadschema (.eds)',
- accept: { 'application/eds': ['.eds'] },
- }],
- startIn: 'documents' // Suggests the Documents folder
- };
- _a = this;
- return [4 /*yield*/, window.showSaveFilePicker(options)];
- case 1:
- _a.fileHandle = _b.sent();
- return [4 /*yield*/, this.saveFile(content, this.fileHandle)];
- case 2:
- _b.sent();
- return [2 /*return*/];
- }
- });
- });
- };
- ;
- importExportUsingFileAPI.prototype.saveFile = function (content, handle) {
- return __awaiter(this, void 0, void 0, function () {
- var writable;
- return __generator(this, function (_a) {
- switch (_a.label) {
- case 0: return [4 /*yield*/, handle.createWritable()];
- case 1:
- writable = _a.sent();
- return [4 /*yield*/, writable.write(content)];
- case 2:
- _a.sent();
- return [4 /*yield*/, writable.close()];
- case 3:
- _a.sent();
- this.filename = handle.name;
- structure.properties.filename = handle.name;
- this.setSaveNeeded(false);
- this.updateLastSaved();
- return [2 /*return*/];
- }
- });
- });
- };
- ;
- importExportUsingFileAPI.prototype.save = function (content) {
- return __awaiter(this, void 0, void 0, function () {
- return __generator(this, function (_a) {
- switch (_a.label) {
- case 0: return [4 /*yield*/, this.saveFile(content, this.fileHandle)];
- case 1:
- _a.sent();
- return [2 /*return*/];
- }
- });
- });
- };
- ;
- return importExportUsingFileAPI;
-}());
-var fileAPIobj = new importExportUsingFileAPI();
-/* FUNCTION importjson
-
- This is the callback function for the legacy filepicker if the file API is not available in the browser */
-var importjson = function (event) {
- var input = event.target;
- var reader = new FileReader();
- var text = "";
- reader.onload = function () {
- EDStoStructure(reader.result.toString());
- };
- reader.readAsText(input.files[0]);
-};
-var appendjson = function (event) {
- var input = event.target;
- var reader = new FileReader();
- var text = "";
- reader.onload = function () {
- importToAppend(reader.result.toString());
- };
- reader.readAsText(input.files[0]);
-};
-/* FUNCTION loadClicked()
-
- Gets called when a user wants to open a file. Checks if the fileAPI is available in the browser.
- If so, the fileAPI is used. If not, the legacy function importjson is called */
-function loadClicked() {
- return __awaiter(this, void 0, void 0, function () {
- var data;
- return __generator(this, function (_a) {
- switch (_a.label) {
- case 0:
- if (!window.showOpenFilePicker) return [3 /*break*/, 2];
- return [4 /*yield*/, fileAPIobj.readFile()];
- case 1:
- data = _a.sent();
- EDStoStructure(data);
- return [3 /*break*/, 3];
- case 2:
- document.getElementById('importfile').click();
- document.getElementById('importfile').value = "";
- _a.label = 3;
- case 3: return [2 /*return*/];
- }
- });
- });
-}
-/**
- * function importToAppendClicked()
- *
- * Vraagt om een EDS bestand op de machine te kiezen en voegt de inhoud toe aan het reeds geopende schema.
- * We gebruiken hier bewust niet de fileAPI aangezien die reeds gebruikt wordt voor het reeds geopende schema.
- */
-function importToAppendClicked() {
- return __awaiter(this, void 0, void 0, function () {
- return __generator(this, function (_a) {
- document.getElementById('appendfile').click();
- document.getElementById('appendfile').value = "";
- return [2 /*return*/];
- });
- });
-}
-/* FUNCTION upgrade_version
-
- Takes a structure, usually imported from json into javascript object, and performs a version upgrade if needed.
- as mystructure is passed by reference, all upgrades are done in-line.
-
-*/
-function upgrade_version(mystructure, version) {
- // At a certain moment (2023-01-11 to 2023-01-13) there was a bug in the systen so that files where accidentally outputed with props, without keys, but with version 1.
- // We correct for this below. If there are props and not keys but it still reads version 1, it should be interpreted as version 3.
- if ((version == 1) && (mystructure.length > 0) && (typeof (mystructure.data[0].keys) == 'undefined') && (typeof (mystructure.data[0].props) != 'undefined')) {
- version = 3;
- }
- /* Indien versie 1 moeten we vrije tekst elementen die niet leeg zijn 30 pixels breder maken.
- * Merk ook op dat versie 1 nog een key based systeem had met keys[0][2] het type
- * en keys[16][2] die aangeeft of vrije tekst al dan niet een kader bevat (verbruiker) of niet (zonder kader)
- */
- if (version < 2) {
- for (var i = 0; i < mystructure.length; i++) {
- // Breedte van Vrije tekst velden zonder kader met 30 verhogen sinds 16/12/2023
- if ((mystructure.data[i].keys[0][2] === "Vrije tekst") && (mystructure.data[i].keys[16][2] != "verbruiker")) {
- if (Number(mystructure.data[i].keys[22][2]) > 0)
- mystructure.data[i].keys[22][2] = String(Number(mystructure.data[i].keys[22][2]) + 30);
- else
- mystructure.data[i].keys[18][2] = "automatisch";
- if (mystructure.data[i].keys[16][2] != "zonder kader")
- mystructure.data[i].keys[16][2] = "verbruiker";
- }
- }
- }
- // In versie 2 heetten Contactdozen altijd nog Stopcontacten
- if (version < 3) {
- for (var i = 0; i < mystructure.length; i++) {
- if (mystructure.data[i].keys[0][2] === "Stopcontact")
- mystructure.data[i].keys[0][2] = "Contactdoos";
- if (mystructure.data[i].keys[0][2] === "Leeg")
- mystructure.data[i].keys[0][2] = "Aansluitpunt";
- }
- }
- // In versie 3 heetten Contactdozen ook soms nog Stopcontacten, maar niet altijd
- if (version == 3) {
- for (var i = 0; i < mystructure.length; i++) {
- if (mystructure.data[i].props.type === "Stopcontact")
- mystructure.data[i].props.type = "Contactdoos";
- }
- }
- //Vanaf versie 4 staan niet automatisch meer haakjes <> rond de benaming van borden. Indien kleiner dan versie 4 moeten we deze toevoegen
- if (version < 4) {
- if (version < 3) {
- for (var i = 0; i < mystructure.length; i++) {
- if ((mystructure.data[i].keys[0][2] === "Bord") && (mystructure.data[i].keys[10][2] !== ""))
- mystructure.data[i].keys[10][2] = '<' + mystructure.data[i].keys[10][2] + '>';
- }
- }
- else {
- for (var i = 0; i < mystructure.length; i++) {
- if ((mystructure.data[i].props.type === "Bord") && (mystructure.data[i].props.naam !== ""))
- mystructure.data[i].props.naam = '<' + mystructure.data[i].props.naam + '>';
- }
- }
- }
- //Algemene upgrade voor versies 3 tot en met 4
- if ((version >= 3) && (version <= 4)) {
- for (var i = 0; i < mystructure.length; i++) {
- if (mystructure.data[i].props.type === "Leeg")
- mystructure.data[i].props.type = "Aansluitpunt";
- }
- }
-}
-/* FUNCTION json_to_structure
-
- Takes a string in pure json and puts the content in a hierarchical list that is returned.
- The function can take an old structure that is to be cleaned as input (optional)
-
- Will perform a version upgrade in case the json is from an earlier version of the eendraadschema tool but this version upgrade will not be performed
- if version is set to 0. If version is not set to 0 it should be set to the verson of the json.
-
-*/
-function json_to_structure(text, oldstruct, version) {
- if (oldstruct === void 0) { oldstruct = null; }
- if (version === void 0) { version = 0; }
- // If a structure exists, clear it
- if (oldstruct != null)
- oldstruct.dispose(); // Clear the structure
- /* Read all data from disk in a javascript structure mystructure.
- * Afterwards we will gradually copy elements from this one into the official outstruct
- */
- var mystructure = JSON.parse(text);
- // upgrade if needed
- if (version != 0)
- upgrade_version(mystructure, version);
- /* We starten met het kopieren van data naar de eigenlijke outstruct.
- * Ook hier houden we er rekening mee dat in oude saves mogelijk niet alle info voorhanden was */
- var outstruct = new Hierarchical_List();
- // Kopieren van hoofd-eigenschappen
- if (typeof mystructure.properties != 'undefined') {
- if (typeof mystructure.properties.filename != "undefined")
- outstruct.properties.filename = mystructure.properties.filename;
- if (typeof mystructure.properties.owner != "undefined")
- outstruct.properties.owner = mystructure.properties.owner;
- if (typeof mystructure.properties.control != "undefined")
- outstruct.properties.control = mystructure.properties.control;
- if (typeof mystructure.properties.installer != "undefined")
- outstruct.properties.installer = mystructure.properties.installer;
- if (typeof mystructure.properties.info != "undefined")
- outstruct.properties.info = mystructure.properties.info;
- if (typeof mystructure.properties.info != "undefined")
- outstruct.properties.dpi = mystructure.properties.dpi;
- if (typeof mystructure.properties.currentView != "undefined")
- outstruct.properties.currentView = mystructure.properties.currentView;
- }
- // Kopieren van de paginatie voor printen
- if (typeof mystructure.print_table != "undefined") {
- outstruct.print_table.setHeight(mystructure.print_table.height);
- outstruct.print_table.setMaxWidth(mystructure.print_table.maxwidth);
- outstruct.print_table.setPaperSize(mystructure.print_table.papersize);
- outstruct.print_table.setModeVertical(mystructure.print_table.modevertical);
- outstruct.print_table.setstarty(mystructure.print_table.starty);
- outstruct.print_table.setstopy(mystructure.print_table.stopy);
- if (typeof mystructure.print_table.enableAutopage != "undefined") {
- outstruct.print_table.enableAutopage = mystructure.print_table.enableAutopage;
- }
- else {
- outstruct.print_table.enableAutopage = false;
- }
- for (var i = 0; i < mystructure.print_table.pages.length; i++) {
- if (i != 0)
- outstruct.print_table.addPage();
- outstruct.print_table.pages[i].height = mystructure.print_table.pages[i].height;
- outstruct.print_table.pages[i].start = mystructure.print_table.pages[i].start;
- outstruct.print_table.pages[i].stop = mystructure.print_table.pages[i].stop;
- }
- }
- // Kopieren van de situatieplannen
- if (typeof mystructure.sitplanjson != "undefined") {
- outstruct.sitplan = new SituationPlan();
- outstruct.sitplan.fromJsonObject(mystructure.sitplanjson);
- }
- /* Kopieren van de eigenschappen van elk element.
- * Keys voor versies 1 en 2 en props voor versie 3
- */
- for (var i = 0; i < mystructure.length; i++) {
- if ((version != 0) && (version < 3)) {
- outstruct.addItem(mystructure.data[i].keys[0][2]);
- outstruct.data[i].convertLegacyKeys(mystructure.data[i].keys);
- }
- else {
- outstruct.addItem(mystructure.data[i].props.type);
- Object.assign(outstruct.data[i].props, mystructure.data[i].props);
- }
- outstruct.data[i].parent = mystructure.data[i].parent;
- outstruct.active[i] = mystructure.active[i];
- outstruct.id[i] = mystructure.id[i];
- outstruct.data[i].id = mystructure.data[i].id;
- outstruct.data[i].indent = mystructure.data[i].indent;
- outstruct.data[i].collapsed = mystructure.data[i].collapsed;
- }
- // As we re-read the structure and it might be shorter then it once was (due to deletions) but we might still have the old high ID's, always take over the curid from the file
- outstruct.curid = mystructure.curid;
- // Sort the entire new structure
- outstruct.reSort();
- // Return the result
- return outstruct;
-}
-function loadFromText(text, version, redraw) {
- if (redraw === void 0) { redraw = true; }
- structure = json_to_structure(text, structure, version);
- if (redraw == true)
- topMenu.selectMenuItemByName('Eéndraadschema'); // Ga naar het bewerken scherm, dat zal automatisch voor hertekenen zorgen.
-}
-/**
- * Converteert een string in EDS formaat naar een json string.
- * De string kan eventueel eerst entropy gecodeerd en base64 encoded zijn.
- * De string kan ook een header hebben met een versie en een identificatie.
- *
- * @param {string} mystring - De string die uit een bestand of een json string is geladen.
- * @returns {Object} - Een object met twee attributen: text en version. Text is de json string en version is de versie van de string.
- */
-function EDStoJson(mystring) {
- var text = "";
- var version;
- /* If first 3 bytes read "EDS", it is an entropy coded file
- * The first 3 bytes are EDS, the next 3 bytes indicate the version
- * The next 4 bytes are decimal zeroes "0000"
- * thereafter is a base64 encoded data-structure
- *
- * If the first 3 bytes read "TXT", it is not entropy coded, nor base64
- * The next 7 bytes are the same as above.
- *
- * If there is no identifier, it is treated as a version 1 TXT
- * */
- if ((mystring.charCodeAt(0) == 69) && (mystring.charCodeAt(1) == 68) && (mystring.charCodeAt(2) == 83)) { //recognize as EDS
- /* Determine versioning
- * < 16/12/2023: Version 1, original key based implementation
- * 16/12/2023: Version 2, Introductie van automatische breedte voor bepaalde SVG-tekst
- * Vrije tekst van Version 1 moet 30 pixels groter gemaakt worden om nog mooi in het schema te passen
- * XX/01/2024: Version 3, Overgang van key based implementation naar props based implementation
- * functies convertLegacyKeys ingevoerd om oude files nog te lezen.
- */
- version = Number(mystring.substring(3, 6));
- if (isNaN(version))
- version = 1; // Hele oude files bevatten geen versie, ze proberen ze te lezen als versie 1
- mystring = atob(mystring.substring(10, mystring.length));
- var buffer = new Uint8Array(mystring.length);
- for (var i = 0; i < mystring.length; i++) {
- buffer[i - 0] = mystring.charCodeAt(i);
- }
- try { //See if the text decoder works, if not, we will do it manually (slower)
- var decoder = new TextDecoder("utf-8");
- text = decoder.decode(pako.inflate(buffer));
- }
- catch (error) { //Continue without the text decoder (old browsers)
- var inflated = pako.inflate(buffer);
- text = "";
- for (var i = 0; i < inflated.length; i++) {
- text += String.fromCharCode(inflated[i]);
- }
- }
- }
- else if ((mystring.charCodeAt(0) == 84) && (mystring.charCodeAt(1) == 88) && (mystring.charCodeAt(2) == 84)) { //recognize as TXT
- version = Number(mystring.substring(3, 6));
- if (isNaN(version))
- version = 3;
- text = mystring.substring(10, mystring.length);
- }
- else { // Very old file without header
- text = mystring;
- version = 1;
- }
- //Return an object with the text and the version
- return { text: text, version: version };
-}
-/* FUNCTION EDStoStructure
-
- Starts from a string that can be loaded from disk or from a file and is in EDS-format.
- puts the content in the javascript structure called "structure".
- Will redraw everything if the redraw flag is set.
-
-*/
-function EDStoStructure(mystring, redraw) {
- if (redraw === void 0) { redraw = true; }
- var JSONdata = EDStoJson(mystring);
- // Dump the json in into the structure and redraw if needed
- loadFromText(JSONdata.text, JSONdata.version, redraw);
- // Clear the undo stack and push this one on top
- undostruct.clear();
- undostruct.store();
- // Scroll to top left for the SVG and HTML, this can only be done at the end because "right col" has to actually be visible
- var leftelem = document.getElementById("left_col");
- if (leftelem != null) {
- leftelem.scrollTop = 0;
- leftelem.scrollLeft = 0;
- }
- var rightelem = document.getElementById("right_col");
- if (rightelem != null) {
- rightelem.scrollTop = 0;
- rightelem.scrollLeft = 0;
- }
-}
-function importToAppend(mystring, redraw) {
- if (redraw === void 0) { redraw = true; }
- var JSONdata = EDStoJson(mystring);
- var structureToAppend = json_to_structure(JSONdata.text, null, JSONdata.version);
- //get the Maximal ID in array structure.id and call it maxID
- var maxID = 0;
- for (var i = 0; i < structure.id.length; i++) {
- if (structure.id[i] > maxID)
- maxID = structure.id[i];
- }
- //then increase the ID's in structureToAppend accordingly
- for (var i = 0; i < structureToAppend.id.length; i++) {
- structureToAppend.id[i] += maxID;
- structureToAppend.data[i].id += maxID;
- if (structureToAppend.data[i].parent != 0) {
- structureToAppend.data[i].parent += maxID;
- }
- }
- structure.curid += structureToAppend.curid;
- //then merge information for the eendraadschema
- structure.length = structure.length + structureToAppend.length;
- structure.active = structure.active.concat(structureToAppend.active);
- structure.id = structure.id.concat(structureToAppend.id);
- structure.data = structure.data.concat(structureToAppend.data);
- //update the sourcelist
- structure.data.forEach(function (item) {
- item.sourcelist = structure;
- });
- //then set the printer to autopage
- structure.print_table.enableAutopage = true;
- //then merge the situation plans but only if both exist
- if (structure.sitplan != null) {
- if (structureToAppend.sitplan != null) {
- // Eerst oude situationplanview leeg maken, anders blijven oude div's hangen
- if (structure.sitplanview != null)
- structure.sitplanview.dispose();
- // dan nieuw situationplan maken en bij openen van het schema zal automatisch een nieuw situationplanview gecreëerd wordne
- structure.sitplanjson = structure.sitplan.toJsonObject();
- structureToAppend.sitplanjson = structureToAppend.sitplan.toJsonObject();
- for (var i = 0; i < structureToAppend.sitplanjson.elements.length; i++) {
- if (structureToAppend.sitplanjson.elements[i].electroItemId != null)
- structureToAppend.sitplanjson.elements[i].electroItemId += maxID;
- structureToAppend.sitplanjson.elements[i].page += structure.sitplanjson.numPages;
- }
- if ((structure.sitplanjson != null) && (structureToAppend.sitplanjson != null)) {
- structure.sitplanjson.numPages += structureToAppend.sitplanjson.numPages;
- structure.sitplanjson.elements = structure.sitplanjson.elements.concat(structureToAppend.sitplanjson.elements);
- }
- structure.sitplan.fromJsonObject(structure.sitplanjson);
- structure.sitplanjson = null;
- }
- }
- structure.reSort();
- undostruct.store();
- //then remove the pointer from structureToAppend and let the garbage collector do its work
- structureToAppend = null;
- //redraw if needed
- if (redraw)
- topMenu.selectMenuItemByName('Eéndraadschema');
-}
-function structure_to_json() {
- // Remove some unneeded data members that would only inflate the size of the output file
- for (var _i = 0, _a = structure.data; _i < _a.length; _i++) {
- var listitem = _a[_i];
- listitem.sourcelist = null;
- }
- var swap = structure.print_table.pagemarkers;
- var swap2 = structure.sitplan;
- var swap3 = structure.sitplanview;
- structure.print_table.pagemarkers = null;
- if (structure.sitplan != null)
- structure.sitplanjson = structure.sitplan.toJsonObject();
- structure.sitplan = null;
- structure.sitplanview = null;
- // Create the output structure in uncompressed form
- var text = JSON.stringify(structure);
- // Put the removed data members back
- for (var _b = 0, _c = structure.data; _b < _c.length; _b++) {
- var listitem = _c[_b];
- listitem.sourcelist = structure;
- }
- structure.print_table.pagemarkers = swap;
- structure.sitplan = swap2;
- structure.sitplanview = swap3;
- // Remove sitplanjson again
- structure.sitplanjson = null;
- return (text);
-}
-/** FUNCTION download_by_blob
- *
- * Downloads an EDS file to the user's PC
- *
- */
-function download_by_blob(text, filename, mimeType) {
- var element = document.createElement('a');
- if (navigator.msSaveBlob) {
- navigator.msSaveBlob(new Blob([text], {
- type: mimeType
- }), filename);
- }
- else if (URL && 'download' in element) {
- var uriContent = URL.createObjectURL(new Blob([text], { type: mimeType }));
- element.setAttribute('href', uriContent);
- element.setAttribute('download', filename);
- element.style.display = 'none';
- document.body.appendChild(element);
- element.click();
- setTimeout(function () { return document.body.removeChild(element); }, 1000); // 1-second delay
- }
- else {
- this.location.go("".concat(mimeType, ",").concat(encodeURIComponent(text)));
- }
-}
-/* FUNCTION showFilePage
-
- Shows the File-Page. It will look different depending on whether the browser supports the file API or not
-
-*/
-function showFilePage() {
- var strleft = ''; //We need the id to check elsewhere that the screen is open
- strleft += "\n
\n
\n
\n Openen\n
\n
\n
\n
\n
\n
\n
\n \n
\n
\n Click op \"openen\" en selecteer een eerder opgeslagen EDS bestand.\n
\n
\n
\n
\n
\n
\n
\n
\n
\n Opslaan\n
\n
\n
\n
\n ";
- if (window.showOpenFilePicker) { // Use fileAPI
- strleft += '
';
- strleft += 'U kan het schema opslaan op uw lokale harde schijf voor later gebruik. De standaard-naam is eendraadschema.eds. U kan deze wijzigen door links op "wijzigen" te klikken. ';
- strleft += 'Klik vervolgens op "opslaan" en volg de instructies van uw browser. ';
- strleft += 'In de meeste gevallen zal uw browser het bestand automatisch plaatsen in de Downloads-folder tenzij u uw browser instelde dat die eerst een locatie moet vragen.
';
- strleft += 'Eens opgeslagen kan het schema later opnieuw geladen worden door in het menu "openen" te kiezen en vervolgens het bestand op uw harde schijf te selecteren.';
- strleft += '
';
- strleft += PROP_GDPR(); //Function returns empty for GIT version, returns GDPR notice when used online.
- strleft += '
';
- }
- strleft += "\n
\n
\n
\n ";
- strleft += "\n
\n
\n
\n Samenvoegen\n
\n
\n
\n
\n
\n
\n
\n \n
\n
\n Open een tweede EDS bestand en voeg de inhoud toe aan het huidige EDS bestand. \n Voegt de \u00E9\u00E9ndraadschema's samen en voegt eveneens pagina's toe aan het situatieschema als dat nodig is.
\n Opgelet! Het is aanbevolen uw werk op te slaan alvorens deze functie te gebruiken!\n
\n Een volledige handleiding is beschikbaar in PDF formaat.\n Klik links om deze in een ander venster te openen.\n \n Het programma is in volle ontwikkeling dus delen van de handleiding zijn\n mogelijk ietwat verouderd. \n
\n
\n
\n
\n \n
\n
\n Specifiek voor het werken met het situatieschema werd een ander korter document opgesteld.\n Klik link om deze in een ander venster te openen.\n
\n
\n
\n
\n
\n
";
- document.getElementById("configsection").innerHTML = strleft;
- toggleAppView('config');
- document.getElementById('Btn_downloadManual').onclick = function () { window.open('Documentation/edsdoc.pdf', '_blank'); };
- document.getElementById('Btn_downloadSitPlanManual').onclick = function () { window.open('Documentation/sitplandoc.pdf', '_blank'); };
-}
-var ContextMenu = /** @class */ (function () {
- /**
- * Constructor voor het initialiseren van het contextmenu-element.
- * @param div - Het HTML-element waaraan het contextmenu wordt toegevoegd.
- */
- function ContextMenu(div) {
- if (div === void 0) { div = document.body; }
- this.menuItems = [];
- this.menuElement = null;
- this.menuElement = document.createElement('div');
- this.menuElement.className = 'context-menu';
- div.appendChild(this.menuElement);
- }
- /**
- * Wis alle menu-items.
- */
- ContextMenu.prototype.clearMenu = function () {
- this.menuItems = [];
- if (this.menuElement) {
- this.menuElement.innerHTML = '';
- }
- };
- /**
- * Voeg een menu-item toe met een optionele sneltoets.
- * @param label - De tekstlabel van het menu-item.
- * @param callback - De functie die wordt aangeroepen bij het klikken op het menu-item.
- * @param shortcut - De optionele sneltoets voor het menu-item.
- */
- ContextMenu.prototype.addMenuItem = function (label, callback, shortcut) {
- this.menuItems.push({ label: label, shortcut: shortcut, callback: callback });
- };
- /**
- * Voeg een scheidingslijn toe aan het menu.
- */
- ContextMenu.prototype.addLine = function () {
- this.menuItems.push({ label: 'separator', callback: function () { } });
- };
- /**
- * Render de menu-items.
- */
- ContextMenu.prototype.renderMenu = function () {
- var _this = this;
- if (this.menuElement) {
- this.menuElement.innerHTML = '';
- this.menuItems.forEach(function (item, index) {
- if (item.label === 'separator') {
- var separator = document.createElement('hr');
- separator.className = 'context-menu-separator';
- _this.menuElement.appendChild(separator);
- }
- else {
- var menuItem = document.createElement('div');
- menuItem.className = 'context-menu-item';
- var labelElement = document.createElement('span');
- labelElement.textContent = item.label;
- var shortcutElement = document.createElement('span');
- shortcutElement.textContent = item.shortcut || '';
- shortcutElement.className = 'context-menu-shortcut';
- menuItem.appendChild(labelElement);
- menuItem.appendChild(shortcutElement);
- menuItem.addEventListener('click', function () {
- item.callback();
- _this.hide();
- });
- _this.menuElement.appendChild(menuItem);
- }
- });
- }
- };
- /**
- * Toon het contextmenu op de locatie van de muisklik.
- * @param event - Het muisgebeurtenisobject.
- */
- ContextMenu.prototype.show = function (event) {
- if (this.menuElement) {
- this.renderMenu();
- this.menuElement.style.display = 'block';
- var clientX = event.clientX, clientY = event.clientY;
- var innerWidth_1 = window.innerWidth, innerHeight_1 = window.innerHeight;
- var _a = this.menuElement, offsetWidth = _a.offsetWidth, offsetHeight = _a.offsetHeight;
- var left = clientX;
- var top_1 = clientY;
- if (left + offsetWidth > innerWidth_1) {
- left = innerWidth_1 - offsetWidth;
- }
- if (top_1 + offsetHeight > innerHeight_1) {
- top_1 = innerHeight_1 - offsetHeight;
- }
- this.menuElement.style.left = "".concat(left, "px");
- this.menuElement.style.top = "".concat(top_1, "px");
- }
- };
- /**
- * Verberg het contextmenu.
- */
- ContextMenu.prototype.hide = function () {
- if (this.menuElement) {
- this.menuElement.style.display = 'none';
- }
- };
- return ContextMenu;
-}());
-/**
- * Class gebruikt in SituationPlanView om te zoeken naar electroitems op basis van de kringnaam.
- * Dit laat toe items to selecteren uit het volledige eendraadschema en ze te plaatsen op het situatieschema.
- *
- * Deze class refereert naar de volgende globale variabelen:
- * - structure
- */
-var ElectroItemZoeker = /** @class */ (function () {
- /**
- * Constructor van de ElectroItemZoeker.
- *
- * Initialiseert de lijst van alle toegestane ElectroItems in het situatieplan.
- */
- function ElectroItemZoeker() {
- this.excludedTypes = ['Aansluiting', 'Bord', 'Kring', 'Domotica', 'Domotica module (verticaal)',
- 'Domotica gestuurde verbruiker', 'Leiding', 'Splitsing', 'Verlenging',
- 'Vrije ruimte', 'Meerdere verbruikers'];
- this.data = [];
- this.borden = [];
- this.reCalculate();
- }
- /**
- * Geeft de lijst van alle toegestane ElectroItems in het situatieplan retour.
- * @returns {Object[]} een lijst van objecten met de volgende structuur:
- * {id: number, kringnaam: string, adres: string, type: string}
- */
- ElectroItemZoeker.prototype.getData = function () {
- return this.data;
- };
- /**
- * Geeft de lijst van alle Borden in het eendraadschema.
- * @returns {Object[]} een lijst van objecten met de volgende structuur:
- * {id: number, naam: string}
- *
- * Indien de originele naam null is of enkel uit spaties bestaat wordt als naam "Bord" meegegeven
- */
- ElectroItemZoeker.prototype.getBorden = function () {
- return this.borden;
- };
- /**
- * Geeft een lijst van alle unieke kringnamen retour uit de lijst van ElectroItems.
- * @returns {string[]} een lijst van unieke kringnamen.
- */
- ElectroItemZoeker.prototype.getUniqueKringnaam = function () {
- return Array.from(new Set(this.data.map(function (x) { return x.kringnaam; })));
- };
- /**
- * Geeft een lijst van alle ElectroItems retour die behoren tot de kring met de naam 'kringnaam'.
- * @param {string} kringnaam - de naam van de kring.
- * @returns {Object[]} een lijst van objecten met de volgende structuur:
- * {id: number, adres: string, type: string}
- */
- ElectroItemZoeker.prototype.getElectroItemsByKring = function (kringnaam) {
- return this.data.filter(function (x) { return x.kringnaam === kringnaam; }).map(function (x) { return ({ id: x.id, adres: x.adres, type: x.type }); });
- };
- /**
- * Rekent de lijst van alle toegestane ElectroItems opnieuw uit.
- *
- * Deze methode wordt gebruikt om de lijst van ElectroItems te vullen die in het situatieplan gebruikt mogen worden.
- * De lijst wordt opnieuw uitgerekend door de volgende stappen:
- * 1. Doorlopen alle actieve ElectroItems in de structuur.
- * 2. Voor elke ElectroItem worden de kringnaam en het type bepaald.
- * 3. Als de kringnaam niet leeg is en het type niet voorkomt in de lijst van uitgesloten types, dan wordt de ElectroItem toegevoegd aan de lijst.
- * 4. De ElectroItem wordt toegevoegd met de volgende structuur: {id: number, kringnaam: string, adres: string, type: string}
- *
- * Er wordt eveneens een lijst van borden gemaakt.
- */
- ElectroItemZoeker.prototype.reCalculate = function () {
- this.data = [];
- this.borden = [];
- for (var i = 0; i < structure.length; i++) {
- if (structure.active[i]) {
- var id = structure.id[i];
- var electroItem = structure.data[i];
- if (electroItem == null)
- continue;
- var type = electroItem.getType();
- if (type == 'Bord') {
- var myName = electroItem.props.naam;
- if ((myName == null) || (myName.trim() == ''))
- myName = 'Bord';
- this.borden.push({ id: id, naam: myName });
- }
- else {
- var kringnaam = structure.findKringName(id).trim();
- if (kringnaam != '') {
- if ((type != null) && (this.excludedTypes.indexOf(type) === -1)) {
- var adres = electroItem.getReadableAdres();
- this.data.push({ id: id, kringnaam: kringnaam, adres: adres, type: type });
- }
- }
- }
- }
- }
- };
- return ElectroItemZoeker;
-}());
-/**
- * Functie die de breedte en hoogte van een rechthoek als invoer neemt, evenals een rotatie rond het midden van de rechthoek.
- * De functie retourneert de breedte en hoogte van de kleinste rechthoek die de geroteerde rechthoek omsluit met zijden langs de X- en Y-assen.
- */
-function getRotatedRectangleSize(width, height, rotation) {
- var rotationInRadians = rotation * Math.PI / 180;
- var cos = Math.cos(rotationInRadians);
- var sin = Math.sin(rotationInRadians);
- var rotatedWidth = Math.abs(width * cos) + Math.abs(height * sin);
- var rotatedHeight = Math.abs(width * sin) + Math.abs(height * cos);
- return { width: rotatedWidth, height: rotatedHeight };
-}
-/**
- * Functie die de breedte en hoogte van een rechthoek als invoer neemt, evenals een rotatie rond het midden van de rechthoek.
- * De functie retourneert de breedte en hoogte van de rechthoek die voldoet aan de volgende eigenschappen:
- * - De zijden zijn parallel aan de X-as en de Y-as.
- * - De rechthoek snijdt de X-as en Y-as in dezelfde punten als de originele geroteerde rechthoek
- *
- * Deze functie kan gebruikt worden om de locatie van labels te bepalen.
- */
-function getXYRectangleSize(width, height, rotation) {
- rotation = Math.abs(rotation) % 180;
- if (rotation > 90)
- rotation = 180 - rotation;
- var rotationInRadians = rotation * Math.PI / 180;
- var cos = Math.cos(rotationInRadians);
- var sin = Math.sin(rotationInRadians);
- return { width: Math.min(width / cos, height / sin), height: Math.min(width / sin, height / cos) };
-}
-/**
- * Cache het resultaat van getPixelsPerMillimeter() om de overhead van het maken en verwijderen van een DOM-element bij elke oproep te voorkomen.
- */
-var cachedPixelsPerMillimeter = null;
-/**
- * Berekent het aantal pixels in een millimeter op het huidige scherm.
- * Maakt gebruik van een cache om de overhead van het maken en verwijderen van een DOM-element bij elke oproep te voorkomen.
- * @returns {number} Het aantal pixels in een millimeter.
- */
-function getPixelsPerMillimeter() {
- if (cachedPixelsPerMillimeter === null) {
- var div = document.createElement('div');
- div.style.width = '10mm';
- div.style.position = 'absolute';
- document.body.appendChild(div);
- var widthInPixels = div.offsetWidth;
- document.body.removeChild(div);
- cachedPixelsPerMillimeter = widthInPixels / 10;
- }
- return cachedPixelsPerMillimeter;
-}
-/**
- * Class that helps with dragging a box on the situation plan view.
- * It keeps track of the start position of the drag and the zoomfactor.
- */
-var MouseDrag = /** @class */ (function () {
- function MouseDrag() {
- this.startOffsetLeft = 0;
- this.startOffsetTop = 0;
- this.hassMoved = false;
- }
- /**
- * Start the drag.
- * @param mouseX The x position of the mouse when the drag starts.
- * @param mouseY The y position of the mouse when the drag starts.
- * @param startOffsetLeft The left position of the box when the drag starts.
- * @param startOffsetTop The top position of the box when the drag starts.
- */
- MouseDrag.prototype.startDrag = function (mouseX, mouseY, startOffsetLeft, startOffsetTop) {
- if (mouseX === void 0) { mouseX = 0; }
- if (mouseY === void 0) { mouseY = 0; }
- if (startOffsetLeft === void 0) { startOffsetLeft = 0; }
- if (startOffsetTop === void 0) { startOffsetTop = 0; }
- this.startOffsetLeft = startOffsetLeft;
- this.startOffsetTop = startOffsetTop;
- this.hassMoved = false;
- var menuHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--menu-height'));
- var ribbonHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--ribbon-height'));
- var sideBarWidth = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--sideBarWidth'));
- this.startPaperPos = structure.sitplanview.canvasPosToPaperPos(mouseX - sideBarWidth, mouseY - menuHeight - ribbonHeight);
- };
- /**
- * Return the new left and top position of the box based on the current mouse position.
- * @param mouseX The current x position of the mouse.
- * @param mouseY The current y position of the mouse.
- * @returns An object with the new left and top position of the box.
- */
- MouseDrag.prototype.returnNewLeftTop = function (mousex, mousey) {
- if (mousex === void 0) { mousex = 0; }
- if (mousey === void 0) { mousey = 0; }
- var menuHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--menu-height'));
- var ribbonHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--ribbon-height'));
- var sideBarWidth = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--sideBarWidth'));
- var stopPaperPos = structure.sitplanview.canvasPosToPaperPos(mousex - sideBarWidth, mousey - menuHeight - ribbonHeight);
- if (stopPaperPos.x != this.startPaperPos.x || stopPaperPos.y != this.startPaperPos.y)
- this.hassMoved = true;
- return ({
- left: (stopPaperPos.x - this.startPaperPos.x) + this.startOffsetLeft,
- top: (stopPaperPos.y - this.startPaperPos.y) + this.startOffsetTop
- });
- };
- return MouseDrag;
-}());
-/**
- * Volledig overzicht van een situatieplan.
- * Werd gebouwd voor gebruik in de browser maar is redelijk browser-agnostic.
- * De effectieve code om te interageren met de browser zelf zit in class SituationPlanView.
- *
- * Deze class refereert naar de volgende globale variabelen:
- * - structure
- */
-var SituationPlan = /** @class */ (function () {
- function SituationPlan() {
- this.activePage = 1; // We houden deze bij in situationplan zodat ook wijzigingen van pagina's worden opgeslagen
- this.numPages = 1;
- this.elements = [];
- this.defaults = {
- fontsize: 11,
- scale: SITPLANVIEW_DEFAULT_SCALE,
- rotate: 0
- };
- }
- /**
- * Reset alle waarden van het situatieplan naar hun default waarde.
- * Gebruik deze functie om alle data te wissen en het situatieplan opnieuw te beginnen.
- */
- SituationPlan.prototype.dispose = function () {
- this.elements = [];
- this.numPages = 1;
- this.activePage = 1;
- this.defaults = {
- fontsize: 11,
- scale: SITPLANVIEW_DEFAULT_SCALE,
- rotate: 0
- };
- };
- /**
- * Workaround om de private variabele elements te kunnen gebruiken in friend classs
- * @returns {SituationPlanElement[]} De elementen van het situatieplan
- */
- SituationPlan.prototype.getElements = function () {
- return this.elements;
- };
- /**
- * SituationPlanElement toevoegen aan het situatieplan
- * @param element
- * @returns {void}
- */
- SituationPlan.prototype.addElement = function (element) {
- this.elements.push(element);
- };
- /**
- * Laad een SVG-inhoud vanuit een bestand en voegt deze toe aan het situatieplan.
- * De SVG werd geselecteerd in een fileInput HTML element en komt binnen via het event in de functie header.
- *
- * @param {any} event Het event dat aangaf dat er een bestand was gekozen om te uploaden.
- * @param {number} page Het pagina-nummer van het element in het situatieplan.
- * @param {number} posx De x-coordinaat van het element in het situatieplan.
- * @param {number} posy De y-coordinaat van het element in het situatieplan.
- * @param {() => void} callback Een callback-functie die wordt aangeroepen wanneer het element is toegevoegd.
- * @returns {SituationPlanElement} Het element dat is toegevoegd.
- */
- SituationPlan.prototype.addElementFromFile = function (event, page, posx, posy, callback) {
- var element = new SituationPlanElement();
- element.setVars({ page: page, posx: posx, posy: posy, labelfontsize: this.defaults.fontsize, scale: this.defaults.scale, rotate: this.defaults.rotate });
- element.importFromFile(event, callback);
- this.elements.push(element);
- return element;
- };
- /**
- * Creëer een nieuw element in het situatieplan dat gelinkt is aan een Electro_Item
- *
- * @param {number} electroItemId Het ID van de Electro_Item.
- * @param {number} page Het pagina-nummer van het element in het situatieplan.
- * @param {number} posx De x-coordinaat van het element in het situatieplan.
- * @param {number} posy De y-coordinaat van het element in het situatieplan.
- * @param {AdresType} adrestype Het type van het adres, bijvoorbeeld 'manueel'.
- * AdresType wordt definieerd in SituationPlanElement.ts
- * @param {string} adres Het adres.
- * @param {AdresLocation} adreslocation De locatie van het adres in het label ('boven' of 'onder' of 'rechts' of 'links').
- * AdresLocation wordt definieerd in SituationPlanElement.ts
- * @param {number} labelfontsize De lettergrootte van het label.
- * @param {number} scale De schaal van het element.
- * @param {number} rotate De rotatie van het element.
- * @returns {SituationPlanElement} Het element dat is toegevoegd.
- */
- SituationPlan.prototype.addElementFromElectroItem = function (electroItemId, page, posx, posy, adrestype, adres, adreslocation, labelfontsize, scale, rotate) {
- var electroItem = structure.getElectroItemById(electroItemId);
- if (!electroItem)
- return null;
- var element = electroItem.toSituationPlanElement();
- Object.assign(element, { page: page, posx: posx, posy: posy, labelfontsize: labelfontsize, scale: scale, rotate: rotate });
- element.setElectroItemId(electroItemId);
- element.setAdres(adrestype, adres, adreslocation);
- this.elements.push(element);
- return element;
- };
- /**
- * Verwijder een element van het situatieplan.
- * In principe is er altijd maar één maar de functie gebruikt recursie in het geval er meerdere zouden zijn
- * om ze allemaal te verwijderen.
- *
- * @param {SituationPlanElement} element Het element dat verwijderd moet worden.
- * @returns {void}
- */
- SituationPlan.prototype.removeElement = function (element) {
- var index = this.elements.indexOf(element);
- if (index === -1)
- return;
- this.elements.splice(index, 1);
- if (element.boxref != null)
- element.boxref.remove();
- if (element.boxlabelref != null)
- element.boxlabelref.remove();
- this.removeElement(element); // Recurse in het geval er meerdere zouden zijn maar dit zou niet mogen gebeuren
- };
- /**
- * Zorgt ervoor dat alle elementen in het situatieplan een link hebben naar
- * het eendraadschema.
- *
- * Als een element in het situatieplan verwijst naar een symbool dat niet langer in
- * het eendraadschema zit, wordt het element verwijderd uit het situatieplan.
- */
- SituationPlan.prototype.syncToEendraadSchema = function () {
- for (var _i = 0, _a = this.elements; _i < _a.length; _i++) {
- var element = _a[_i];
- //Indien een symbool niet langer in het eendraadschema zit moet het ook uit het situatieplan verwijderd worden
- //We kunnen hier niet de functie isEendraadSchemaSymbool of getElectroItemById gebruiken want die zorgen
- //ervoor dat onderstaande altijd false geeft als de symbolen niet langer in het eendraadschema zitten waardoor
- //de cleanup die nodig is niet gebeurd.
- if ((element.electroItemId != null) && (structure.getElectroItemById(element.getElectroItemId()) == null)) {
- this.removeElement(element);
- this.syncToEendraadSchema();
- return; // Start opnieuw en stop na recursie
- }
- }
- };
- /**
- * Sorteer de elementen in het situatieplan op basis van de z-index van hun boxref elementen in de DOM.
- * Elementen met een `null` `boxref` worden naar het einde van de lijst verplaatst.
- *
- * Het sorteren is nodig om ervoor te zorgen dat bij het printen wanneer lineair door de elementen wordt gegaan
- * de elementen in de juiste volgorde worden gestacked.
- *
- * @returns {void}
- */
- SituationPlan.prototype.orderByZIndex = function () {
- //if (structure.sitplanview == null) return;
- this.elements.sort(function (a, b) {
- var asort = (((a.boxref == null) || (a.boxref.style.zIndex === "")) ? 0 : parseInt(a.boxref.style.zIndex));
- var bsort = (((b.boxref == null) || (b.boxref.style.zIndex === "")) ? 0 : parseInt(b.boxref.style.zIndex));
- return asort - bsort;
- });
- };
- /**
- * Initialiseer het situatieplan vanuit een json-object.
- *
- * @param {Object} json Het json-object dat het situatieplan bevat.
- * Het object bevat een 'numPages' property dat het aantal pagina's in het situatieplan aangeeft.
- * Verder bevat het een 'elements' property dat een array is van json-objecten die elk een element in het situatieplan vertegenwoordigen.
- * Elke json-object in de array bevat de properties van een SituationPlanElement.
- * @returns {void}
- */
- SituationPlan.prototype.fromJsonObject = function (json) {
- this.dispose();
- if (json.numPages !== undefined) {
- this.numPages = json.numPages;
- }
- else {
- this.numPages = 1;
- }
- if (json.activePage !== undefined) {
- this.activePage = json.activePage;
- }
- else {
- this.activePage = 1;
- }
- if (json.defaults !== undefined) {
- Object.assign(this.defaults, json.defaults);
- }
- if (Array.isArray(json.elements)) {
- this.elements = json.elements.map(function (element) {
- var newElement = new SituationPlanElement();
- newElement.fromJsonObject(element);
- return newElement;
- });
- }
- else {
- this.elements = [];
- }
- };
- /**
- * Converteer het situatieplan naar een JSON-object dat gebruikt kan worden
- * voor opslaan in lokale storage of voor versturen naar de server.
- *
- * @returns {any} Het JSON-object dat het situatieplan bevat.
- */
- SituationPlan.prototype.toJsonObject = function () {
- this.orderByZIndex();
- var elements = [];
- for (var _i = 0, _a = this.elements; _i < _a.length; _i++) {
- var element = _a[_i];
- elements.push(element.toJsonObject());
- }
- return { numPages: this.numPages, activePage: this.activePage, defaults: this.defaults, elements: elements };
- };
- /**
- * Converteer het situatieplan naar een formaat dat gebruikt kan worden voor printen.
- *
- * @param {boolean} fitToPage Indien `true` dan wordt de pagina automatisch aangepast om alle elementen te laten passen.
- * Als `false` dan wordt de pagina in de originele grootte gebruikt.
- * @returns {any} Het formaat van het situatieplan dat gebruikt kan worden voor printen.
- * Dit is een javascript object met structuur
- * {
- * numpages: number,
- * pages: [
- * {
- * svg: string,
- * minx: number,
- * miny: number,
- * maxx: number,
- * maxy: number
- * }
- * ]
- * }
- */
- SituationPlan.prototype.toSitPlanPrint = function (fitToPage) {
- if (fitToPage === void 0) { fitToPage = false; }
- this.syncToEendraadSchema(); // Om zeker te zijn dat we geen onbestaande elementen meer hebben
- this.orderByZIndex(); // Sorteer de elementen op basis van de z-index zodat ze in de juiste volgorde worden geprint
- var outstruct = {};
- outstruct.numpages = (this.elements.length > 0 ? structure.sitplan.numPages : 0);
- outstruct.pages = [];
- for (var i = 0; i < outstruct.numpages; i++) {
- var svgstr = '';
- var maxx = getPixelsPerMillimeter() * 277;
- var maxy = getPixelsPerMillimeter() * 150;
- var minx = 0;
- var miny = 0;
- for (var _i = 0, _a = this.elements; _i < _a.length; _i++) {
- var element = _a[_i];
- if (element.page == (i + 1)) {
- var fontsize = (element.labelfontsize != null) ? element.labelfontsize : 11;
- svgstr += element.getScaledSVG(true);
- if (fitToPage) {
- var boundingbox = getRotatedRectangleSize(element.sizex * element.getscale(), element.sizey * element.getscale(), element.rotate);
- maxx = Math.max(maxx, element.posx + boundingbox.width / 2);
- maxy = Math.max(maxy, element.posy + boundingbox.height / 2);
- minx = Math.min(minx, element.posx - boundingbox.width / 2);
- miny = Math.min(miny, element.posy - boundingbox.height / 2);
- }
- var str = element.getAdres();
- svgstr += "").concat(htmlspecialchars(str), "");
- }
- }
- svgstr = "");
- outstruct.pages.push({ sizex: maxx - minx, sizey: maxy - miny, svg: svgstr });
- }
- return outstruct;
- };
- return SituationPlan;
-}());
-/**
- * Class SituationPlanElement
- *
- * Deze class refereert naar de volgende globale variabelen:
- * - structure
- * - SITPLANVIEW_DEFAULT_SCALE
- */
-var SituationPlanElement = /** @class */ (function () {
- /**
- * Constructor
- */
- function SituationPlanElement() {
- this.electroItemId = null; // Referentie naar het electro-element in de datastructuur indien van toepassing
- // -- Basis eigenschappen van het element zelf --
- this.boxref = null; // Referentie naar het DIV document in de browser waar het element wordt afgebeeld
- this.svg = ''; /* SVG content van het element indien van toepassing
- Indien electroItemId == null dan is dit de SVG content van het element zelf
- Indien electroItemId != null dan is dit de laatste geladen SVG content van het electro-element
- Altijd te verifiëren dat deze niet leeg is en evenueel een update forceren */
- // -- Basis eigenschappen van het label --
- // adres gegevens zijn private gedefinieerd omwille van consistentie (bvb adres kan leeg gelaten worden als het type auto is)
- this.boxlabelref = null; // Referentie naar het DIV document in de browser waar het label wordt afgebeeld
- this.adrestype = null;
- this.adres = null;
- this.adreslocation = 'rechts';
- // -- Positionering van het element zelf --
- this.page = 1; //pagina waarop het element zich bevindt
- this.posx = 0; //center positie-x in het schema
- this.posy = 0; //center positie-y in het schema
- this.sizex = 0; //breedte
- this.sizey = 0; //hoogte
- this.rotate = 0;
- this.scale = SITPLANVIEW_DEFAULT_SCALE;
- // -- Positionering van het label --
- this.labelposx = 0;
- this.labelposy = 0;
- this.labelfontsize = 11;
- // -- Een vlag om de situationplanview te laten weten dat de box content moet geupdated worden
- this.needsViewUpdate = false;
- // -- Een vlag voor verplaatsbaarheid
- this.movable = true;
- this.id = randomId("SP_");
- }
- SituationPlanElement.prototype.setscale = function (scale) {
- this.scale = scale;
- this.needsViewUpdate = true;
- };
- SituationPlanElement.prototype.getscale = function () {
- return this.scale;
- };
- /**
- * isEendraadschemaSymbool
- *
- * Controleer of het element een geldig electro-element is
- * Hiervoor is een geldige electroItemId nodig en moet het element in de datastructuur voorkomen.
- *
- * @returns boolean
- */
- SituationPlanElement.prototype.isEendraadschemaSymbool = function () {
- if (this.electroItemId != null) {
- return (structure.getElectroItemById(this.electroItemId) != null);
- }
- return false;
- };
- SituationPlanElement.prototype.isEDSSymbolAndRotates360degrees = function () {
- if (this.isEendraadschemaSymbool()) {
- var electroElement = structure.getElectroItemById(this.electroItemId);
- if (electroElement != null) {
- var type = electroElement.getType();
- return SituationPlanElement.ROTATES_360_DEGREES_TYPES.has(type);
- }
- return false;
- }
- return false;
- };
- /**
- * setAdres
- *
- * @param adrestype string : 'auto' of 'manueel'
- * @param adres string : Indien manueel, het adres. Indien auto wordt deze genegeerd en this.adres altijd op null gezet.
- * @param adreslocation string: 'rechts' of 'links' of 'boven' of 'onder'
- */
- SituationPlanElement.prototype.setAdres = function (adrestype, adres, adreslocation) {
- this.adrestype = adrestype;
- this.adreslocation = adreslocation;
- if (this.adrestype === 'manueel')
- this.adres = adres;
- else
- this.adres = null;
- };
- /**
- * setAdresLocation
- *
- * @param adreslocation string: 'rechts' of 'links' of 'boven' of 'onder'
- */
- SituationPlanElement.prototype.setAdresLocation = function (adreslocation) {
- this.adreslocation = adreslocation;
- };
- /**
- * getAdresType
- *
- * @returns string : 'auto' of 'manueel'
- */
- SituationPlanElement.prototype.getAdresType = function () {
- return this.adrestype;
- };
- /**
- * getAdres
- *
- * @returns string : adres
- */
- SituationPlanElement.prototype.getAdres = function () {
- var _a;
- if (!this.isEendraadschemaSymbool())
- return ''; // Geen adres voor niet-elektro-elementen
- var element = structure.getElectroItemById(this.electroItemId);
- if (element == null)
- return ''; // zou redundant moeten zijn want we controleerden al in isEendraadschemaSymbool
- if (this.adrestype === 'auto') {
- return element.getReadableAdres();
- }
- else {
- return (_a = this.adres) !== null && _a !== void 0 ? _a : '';
- }
- };
- /**
- * getAdresLocation
- *
- * @returns 'rechts'|'links'|'boven'|'onder'
- */
- SituationPlanElement.prototype.getAdresLocation = function () {
- return this.adreslocation;
- };
- /**
- * setElectroItemId
- *
- * @param electroItemId number : id van het electroitem in structure
- *
- * TODO: zou beter een private functie zijn en niet worden aangeroepen vanuit SituationPlan en SituationPlanView
- */
- SituationPlanElement.prototype.setElectroItemId = function (electroItemId) {
- this.electroItemId = electroItemId;
- };
- /**
- * getElectroItemId
- *
- * @returns number : id van het electroitem in structure
- */
- SituationPlanElement.prototype.getElectroItemId = function () {
- if (this.isEendraadschemaSymbool())
- return this.electroItemId;
- else
- return null;
- };
- /**
- * updateElectroItemSVG
- *
- * @param svg string : nieuwe gegenereerde SVG door het electro-element
- * @param width number : breedte van de SVG zonder schaling en rotatie, indien niet gegeven wordt de breedte gezocht met functie getSizeFromString
- * @param height number : hoogte van de SVG zonder schaling en rotatie
- */
- SituationPlanElement.prototype.updateElectroItemSVG = function (svg, width, height) {
- if (width === void 0) { width = undefined; }
- if (height === void 0) { height = undefined; }
- if (this.isEendraadschemaSymbool()) {
- if (this.svg !== svg) { // This works because when saving to a file, svg is set to '' so an update will be triggered here
- this.needsViewUpdate = true;
- this.svg = svg;
- if (width != null)
- this.sizex = width;
- if (height != null)
- this.sizey = height;
- if (width == null || height == null)
- this.getSizeFromString();
- }
- }
- };
- /**
- * getUnscaledSVGifNotElectroItem
- *
- * @returns string : SVG content van het element op voorwaarde dat het geen electro-element is
- */
- SituationPlanElement.prototype.getUnscaledSVGifNotElectroItem = function () {
- // cleanSVG(): Deze functie is nodig omdat gebleken is dat de print SVG commando's in jsPDF niet overweg kunnen met SVG's die niet dadelijk beginnen met '