@nextcloud/calendar-js
Version:
Small library that wraps ICAL.js and provide more convenient means for editing
1 lines • 423 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/parsers/abstractParser.js","../src/errors/modificationNotAllowedError.js","../src/traits/lockable.js","../src/errors/expectedICalJSError.js","../src/helpers/stringHelper.js","../src/config.js","../src/factories/icalFactory.js","../src/traits/observer.js","../src/parameters/parameter.js","../src/values/abstractValue.js","../src/values/binaryValue.js","../src/values/durationValue.js","../src/values/dateTimeValue.js","../src/values/periodValue.js","../src/values/recurValue.js","../src/values/utcOffsetValue.js","../src/errors/unknownICALTypeError.js","../src/values/index.js","../src/properties/property.js","../src/properties/attachmentProperty.js","../src/properties/attendeeProperty.js","../src/properties/conferenceProperty.js","../src/properties/freeBusyProperty.js","../src/properties/geoProperty.js","../src/properties/imageProperty.js","../src/properties/relationProperty.js","../src/properties/requestStatusProperty.js","../src/properties/textProperty.js","../src/properties/triggerProperty.js","../src/properties/index.js","../src/components/abstractComponent.js","../src/factories/dateFactory.js","../src/errors/recurringWithoutDtStartError.js","../src/recurrence/recurrenceManager.js","../src/helpers/cryptoHelper.js","../src/components/nested/alarmComponent.js","../src/components/nested/index.js","../src/components/root/abstractRecurringComponent.js","../src/helpers/birthdayHelper.js","../src/components/root/eventComponent.js","../src/components/root/freeBusyComponent.js","../src/components/root/journalComponent.js","../src/components/root/timezoneComponent.js","../src/components/root/toDoComponent.js","../src/components/root/index.js","../src/components/calendarComponent.js","../src/parsers/repairsteps/abstractRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarAddMissingUIDRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarAddMissingValueDateDoubleColonRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarAddMissingValueDateRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarEmptyTriggerRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarIllegalCreatedRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarMultipleVCalendarBlocksRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarRemoveXNCGroupIdRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarRemoveUnicodeSpecialNoncharactersRepairStep.js","../src/parsers/repairsteps/icalendar/icalendarConvertInvalidDateTimeValuesRepairStep.js","../src/parsers/repairsteps/icalendar/index.js","../src/parsers/icalendarParser.js","../src/parsers/parserManager.js","../src/errors/illegalValueError.js","../src/index.js"],"sourcesContent":["/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/**\n * @class AbstractParser\n * @classdesc\n */\nexport default class AbstractParser {\n\n\t/**\n\t * @class\n\t *\n\t * @param {object=} options Object of options\n\t * @param {boolean=} options.extractGlobalProperties Whether or not to preserve properties from the VCALENDAR component (defaults to false)\n\t * @param {boolean=} options.removeRSVPForAttendees Whether or not to remove RSVP from attendees (defaults to false)\n\t * @param {boolean=} options.includeTimezones Whether or not to include timezones (defaults to false)\n\t * @param {boolean=} options.preserveMethod Whether or not to preserve the iCalendar method (defaults to false)\n\t * @param {boolean=} options.processFreeBusy Whether or not to process VFreeBusy components (defaults to false)\n\t */\n\tconstructor(options = {}) {\n\t\tif (new.target === AbstractParser) {\n\t\t\tthrow new TypeError('Cannot instantiate abstract class AbstractParser')\n\t\t}\n\n\t\t/**\n\t\t * Options for the parser\n\t\t *\n\t\t * @type {{removeRSVPForAttendees: boolean}}\n\t\t * @private\n\t\t */\n\t\tthis._options = Object.assign({}, options)\n\n\t\t/**\n\t\t * A name extracted from the calendar-data\n\t\t *\n\t\t * @type {string | null}\n\t\t * @protected\n\t\t */\n\t\tthis._name = null\n\n\t\t/**\n\t\t * A color extracted from the calendar-data\n\t\t *\n\t\t * @type {string | null}\n\t\t * @protected\n\t\t */\n\t\tthis._color = null\n\n\t\t/**\n\t\t * Gets the url that this icalendar file can be updated from\n\t\t *\n\t\t * @type {string}\n\t\t * @protected\n\t\t */\n\t\tthis._sourceURL = null\n\n\t\t/**\n\t\t * Gets the update interval if this icalendar file can be updated from a source\n\t\t *\n\t\t * @type {string}\n\t\t * @protected\n\t\t */\n\t\tthis._refreshInterval = null\n\n\t\t/**\n\t\t * Gets the default timezone of this calendar\n\t\t *\n\t\t * @type {string}\n\t\t * @protected\n\t\t */\n\t\tthis._calendarTimezone = null\n\n\t\t/**\n\t\t * Error count during parsing\n\t\t *\n\t\t * @type {Array}\n\t\t * @protected\n\t\t */\n\t\tthis._errors = []\n\t}\n\n\t/**\n\t * Gets the name extracted from the calendar-data\n\t *\n\t * @return {string | null}\n\t */\n\tgetName() {\n\t\treturn this._name\n\t}\n\n\t/**\n\t * Gets the color extracted from the calendar-data\n\t *\n\t * @return {string | null}\n\t */\n\tgetColor() {\n\t\treturn this._color\n\t}\n\n\t/**\n\t * Gets whether this import can be converted into a webcal subscription\n\t *\n\t * @return {boolean}\n\t */\n\toffersWebcalFeed() {\n\t\treturn this._sourceURL !== null\n\t}\n\n\t/**\n\t * Gets the url pointing to the webcal source\n\t *\n\t * @return {string | null}\n\t */\n\tgetSourceURL() {\n\t\treturn this._sourceURL\n\t}\n\n\t/**\n\t * Gets the recommended refresh rate to update this subscription\n\t *\n\t * @return {string | null}\n\t */\n\tgetRefreshInterval() {\n\t\treturn this._refreshInterval\n\t}\n\n\t/**\n\t * Gets the default timezone of this calendar\n\t *\n\t * @return {string}\n\t */\n\tgetCalendarTimezone() {\n\t\treturn this._calendarTimezone\n\t}\n\n\t/**\n\t * {String|Object} data\n\t *\n\t * @param {any} data The data to parse\n\t * @throws TypeError\n\t */\n\tparse(data) {\n\t\tthrow new TypeError('Abstract method not implemented by subclass')\n\t}\n\n\t/**\n\t * Returns one CalendarComponent at a time\n\t */\n\t* getItemIterator() { // eslint-disable-line require-yield\n\t\tthrow new TypeError('Abstract method not implemented by subclass')\n\t}\n\n\t/**\n\t * Get an array of all items\n\t *\n\t * @return {CalendarComponent[]}\n\t */\n\tgetAllItems() {\n\t\treturn Array.from(this.getItemIterator())\n\t}\n\n\t/**\n\t * Returns a boolean whether or not the parsed data contains vevents\n\t *\n\t * @return {boolean}\n\t */\n\tcontainsVEvents() {\n\t\treturn false\n\t}\n\n\t/**\n\t * Returns a boolean whether or not the parsed data contains vjournals\n\t *\n\t * @return {boolean}\n\t */\n\tcontainsVJournals() {\n\t\treturn false\n\t}\n\n\t/**\n\t * Returns a boolean whether or not the parsed data contains vtodos\n\t *\n\t * @return {boolean}\n\t */\n\tcontainsVTodos() {\n\t\treturn false\n\t}\n\n\t/**\n\t * Returns a boolean whether or not the parsed data contains vfreebusys\n\t *\n\t * @return {boolean}\n\t */\n\tcontainsVFreeBusy() {\n\t\treturn false\n\t}\n\n\t/**\n\t * Returns a boolean whether\n\t *\n\t * @return {boolean}\n\t */\n\thasErrors() {\n\t\treturn this._errors.length !== 0\n\t}\n\n\t/**\n\t * Get a list of all errors that occurred\n\t *\n\t * @return {*[]}\n\t */\n\tgetErrorList() {\n\t\treturn this._errors.slice()\n\t}\n\n\t/**\n\t * Returns the number of calendar-objects in parser\n\t *\n\t * @return {number}\n\t */\n\tgetItemCount() {\n\t\treturn 0\n\t}\n\n\t/**\n\t * Gets an option provided\n\t *\n\t * @param {string} name The name of the option to get\n\t * @param {*} defaultValue The default value to return if option not provided\n\t * @return {any}\n\t * @protected\n\t */\n\t_getOption(name, defaultValue) {\n\t\treturn Object.prototype.hasOwnProperty.call(this._options, name)\n\t\t\t? this._options[name]\n\t\t\t: defaultValue\n\t}\n\n\t/**\n\t * Return list of supported mime types\n\t *\n\t * @static\n\t */\n\tstatic getMimeTypes() {\n\t\tthrow new TypeError('Abstract method not implemented by subclass')\n\t}\n\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nexport default class ModificationNotAllowedError extends Error {}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\nimport ModificationNotAllowedError from '../errors/modificationNotAllowedError.js'\n\n/**\n *\n * @param baseClass\n */\nexport default function lockableTrait(baseClass) {\n\n\t/**\n\t * @class LockableTrait\n\t */\n\treturn class extends baseClass {\n\n\t\t/**\n\t\t * Constructor\n\t\t *\n\t\t * @param {...any} args\n\t\t */\n\t\tconstructor(...args) {\n\t\t\tsuper(...args)\n\n\t\t\t/**\n\t\t\t * Indicator whether this value was locked for changes\n\t\t\t *\n\t\t\t * @type {boolean}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._mutable = true\n\t\t}\n\n\t\t/**\n\t\t * Returns whether or not this object is locked\n\t\t *\n\t\t * @return {boolean}\n\t\t */\n\t\tisLocked() {\n\t\t\treturn !this._mutable\n\t\t}\n\n\t\t/**\n\t\t * Marks this object is immutable\n\t\t * locks it against further modification\n\t\t */\n\t\tlock() {\n\t\t\tthis._mutable = false\n\t\t}\n\n\t\t/**\n\t\t * Marks this object as mutable\n\t\t * allowing further modification\n\t\t */\n\t\tunlock() {\n\t\t\tthis._mutable = true\n\t\t}\n\n\t\t/**\n\t\t * Check if modifications are allowed\n\t\t *\n\t\t * @throws {ModificationNotAllowedError} if this object is locked for modification\n\t\t * @protected\n\t\t */\n\t\t_modify() {\n\t\t\tif (!this._mutable) {\n\t\t\t\tthrow new ModificationNotAllowedError()\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Check if modification of content is allowed\n\t\t *\n\t\t * @throws {ModificationNotAllowedError} if this object is locked for modification\n\t\t * @protected\n\t\t */\n\t\t_modifyContent() {\n\t\t\tthis._modify()\n\t\t}\n\n\t}\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nexport default class ExpectedICalJSError extends Error {}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/**\n * Turns the entire string lowercase\n *\n * @param {string} str The string to turn lowercase\n * @return {string}\n */\nexport function lc(str) {\n\treturn str.toLowerCase()\n}\n\n/**\n * Compares two strings, It is case-insensitive.\n *\n * @param {string} str1 String 1 to compare\n * @param {string} str2 String 2 to compare\n * @return {boolean}\n */\nexport function strcasecmp(str1, str2) {\n\treturn uc(str1) === uc(str2)\n}\n\n/**\n * Turns the entire string uppercase\n *\n * @param {string} str The string to turn uppercase\n * @return {string}\n */\nexport function uc(str) {\n\treturn str.toUpperCase()\n}\n\n/**\n * Capitalizes the string\n *\n * @param {string} str The string of which the first character will be turned uppercase\n * @return {string}\n */\nexport function ucFirst(str) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1)\n}\n\n/**\n * Makes sure that a string starts with a certain other string\n * This is mostly used in the attendeeProperty to assure the uri starts with mailto:\n *\n * @param {string} str The string to check for the prefix and prepend if necessary\n * @param {string} startWith The prefix to be added if necessary\n * @return {string}\n */\nexport function startStringWith(str, startWith) {\n\tif (!str.startsWith(startWith)) {\n\t\tstr = startWith + str\n\t}\n\n\treturn str\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/**\n * @type {Map<string, *>}\n */\nconst GLOBAL_CONFIG = new Map()\n\n/**\n * Sets a new config key\n *\n * @param {string} key The config-key to set\n * @param {*} value The value to set for given config-key\n */\nexport function setConfig(key, value) {\n\tGLOBAL_CONFIG.set(key, value)\n}\n\n/**\n * Checks if a config for a certain key is present\n *\n * @param {string} key The config-key to check\n * @return {boolean}\n */\nexport function hasConfig(key) {\n\treturn GLOBAL_CONFIG.has(key)\n}\n\n/**\n * gets value of a config key\n *\n * @param {string} key The config-key to get\n * @param {*} defaultValue Default value of config does not exist\n * @return {*}\n */\nexport function getConfig(key, defaultValue) {\n\treturn GLOBAL_CONFIG.get(key) || defaultValue\n}\n\n/**\n * deletes a config key\n *\n * @param {string} key The config-key to delete\n */\nexport function deleteConfig(key) {\n\tGLOBAL_CONFIG.delete(key)\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { lc } from '../helpers/stringHelper.js'\nimport { getConfig } from '../config.js'\nimport ICAL from 'ical.js'\n\n/**\n * creates a new ICAL.Component object\n *\n * @param {string} componentName The name of the component to create\n * @return {ICAL.Component}\n */\nexport function createComponent(componentName) {\n\treturn new ICAL.Component(lc(componentName))\n}\n\n/**\n * creates a new ICAL.Property object\n *\n * @param {string} propertyName The name of the property to create\n * @return {ICAL.Property}\n */\nexport function createProperty(propertyName) {\n\treturn new ICAL.Property(lc(propertyName))\n}\n\n/**\n * creates a new calendar component\n *\n * @param {string=} method Name of the method to include in VCALENDAR component\n * @return {ICAL.Component}\n */\nexport function createCalendarComponent(method = null) {\n\tconst calendarComp = createComponent('VCALENDAR')\n\n\tcalendarComp.addPropertyWithValue('prodid', getConfig('PRODID', '-//IDN georgehrke.com//calendar-js//EN'))\n\tcalendarComp.addPropertyWithValue('calscale', 'GREGORIAN')\n\tcalendarComp.addPropertyWithValue('version', '2.0')\n\n\tif (method) {\n\t\tcalendarComp.addPropertyWithValue('method', method)\n\t}\n\n\treturn calendarComp\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\n/**\n *\n * @param baseClass\n */\nexport default function observerTrait(baseClass) {\n\n\t/**\n\t * @class ObserverTrait\n\t */\n\treturn class extends baseClass {\n\n\t\t/**\n\t\t * Constructor\n\t\t *\n\t\t * @param {...any} args\n\t\t */\n\t\tconstructor(...args) {\n\t\t\tsuper(...args)\n\n\t\t\t/**\n\t\t\t * List of subscribers\n\t\t\t *\n\t\t\t * @type {Function[]}\n\t\t\t * @private\n\t\t\t */\n\t\t\tthis._subscribers = []\n\t\t}\n\n\t\t/**\n\t\t * Adds a new subscriber\n\t\t *\n\t\t * @param {Function} handler - Handler to be called when modification happens\n\t\t */\n\t\tsubscribe(handler) {\n\t\t\tthis._subscribers.push(handler)\n\t\t}\n\n\t\t/**\n\t\t * Removes a subscriber\n\t\t *\n\t\t * @param {Function} handler - Handler to be no longer called when modification happens\n\t\t */\n\t\tunsubscribe(handler) {\n\t\t\tconst index = this._subscribers.indexOf(handler)\n\t\t\tif (index === -1) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis._subscribers.splice(index, 1)\n\t\t}\n\n\t\t/**\n\t\t * Notify all subscribed handlers\n\t\t *\n\t\t * @param {...any} args\n\t\t * @protected\n\t\t */\n\t\t_notifySubscribers(...args) {\n\t\t\tfor (const handler of this._subscribers) {\n\t\t\t\thandler(...args)\n\t\t\t}\n\t\t}\n\n\t}\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\n\nimport { uc } from '../helpers/stringHelper.js'\nimport lockableTrait from '../traits/lockable.js'\nimport observerTrait from '../traits/observer.js'\n\n/**\n * @class Parameter\n * @classdesc This class represents a property parameters as defined in RFC 5545 Section 3.2\n *\n * @url https://tools.ietf.org/html/rfc5545#section-3.2\n * @url\n */\nexport default class Parameter extends observerTrait(lockableTrait(class {})) {\n\n\t/**\n\t * Constructor\n\t *\n\t * @param {string} name The name of the parameter\n\t * @param {string|Array|null} value The value of the parameter\n\t */\n\tconstructor(name, value = null) {\n\t\tsuper()\n\n\t\t/**\n\t\t * Name of the parameter\n\t\t *\n\t\t * @type {string}\n\t\t * @private\n\t\t */\n\t\tthis._name = uc(name)\n\n\t\t/**\n\t\t * Value of the parameter\n\t\t *\n\t\t * @type {string|Array|null}\n\t\t * @private\n\t\t */\n\t\tthis._value = value\n\t}\n\n\t/**\n\t * Get parameter name\n\t *\n\t * @readonly\n\t * @return {string}\n\t */\n\tget name() {\n\t\treturn this._name\n\t}\n\n\t/**\n\t * Get parameter value\n\t *\n\t * @return {string | Array}\n\t */\n\tget value() {\n\t\treturn this._value\n\t}\n\n\t/**\n\t * Set new parameter value\n\t *\n\t * @throws {ModificationNotAllowedError} if parameter is locked for modification\n\t * @param {string | Array} value The new value to set\n\t */\n\tset value(value) {\n\t\tthis._modifyContent()\n\t\tthis._value = value\n\t}\n\n\t/**\n\t * Gets the first value of this parameter\n\t *\n\t * @return {string | null}\n\t */\n\tgetFirstValue() {\n\t\tif (!this.isMultiValue()) {\n\t\t\treturn this.value\n\t\t} else {\n\t\t\tif (this.value.length > 0) {\n\t\t\t\treturn this.value[0]\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n\n\t/**\n\t * Gets an iterator for all values\n\t */\n\t* getValueIterator() {\n\t\tif (this.isMultiValue()) {\n\t\t\tyield * this.value.slice()[Symbol.iterator]()\n\t\t} else {\n\t\t\tyield this.value\n\t\t}\n\t}\n\n\t/**\n\t * Returns whether or not the value is a multivalue\n\t *\n\t * @return {boolean}\n\t */\n\tisMultiValue() {\n\t\treturn Array.isArray(this._value)\n\t}\n\n\t/**\n\t * Creates a copy of this parameter\n\t *\n\t * @return {Parameter}\n\t */\n\tclone() {\n\t\tconst parameter = new this.constructor(this._name)\n\t\tif (this.isMultiValue()) {\n\t\t\t// only copy array values, don't copy array reference\n\t\t\tparameter.value = this._value.slice()\n\t\t} else {\n\t\t\tparameter.value = this._value\n\t\t}\n\n\t\t// cloned parameters are always mutable\n\t\treturn parameter\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_modifyContent() {\n\t\tsuper._modifyContent()\n\t\tthis._notifySubscribers()\n\t}\n\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\nimport lockableTrait from '../traits/lockable.js'\nimport observerTrait from '../traits/observer.js'\n\n/**\n * @class AbstractValue\n * @classdesc BaseClass for all values\n */\nexport default class AbstractValue extends observerTrait(lockableTrait(class {})) {\n\n\t/**\n\t * Constructor\n\t *\n\t * @param {ICAL.Binary|ICAL.Duration|ICAL.Period|ICAL.Recur|ICAL.Time|ICAL.UtcOffset} icalValue The ICAL.JS object to wrap\n\t */\n\tconstructor(icalValue) {\n\t\tif (new.target === AbstractValue) {\n\t\t\tthrow new TypeError('Cannot instantiate abstract class AbstractValue')\n\t\t}\n\t\tsuper()\n\n\t\t/**\n\t\t * Wrapped ICAL.js value\n\t\t *\n\t\t * @type {ICAL.Binary|ICAL.Duration|ICAL.Period|ICAL.Recur|ICAL.Time|ICAL.UtcOffset}\n\t\t */\n\t\tthis._innerValue = icalValue\n\t}\n\n\t/**\n\t * Gets wrapped ICAL.JS object\n\t *\n\t * @return {*}\n\t */\n\ttoICALJs() {\n\t\treturn this._innerValue\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_modifyContent() {\n\t\tsuper._modifyContent()\n\t\tthis._notifySubscribers()\n\t}\n\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\nimport AbstractValue from './abstractValue.js'\nimport ICAL from 'ical.js'\n\n/**\n * @class BinaryValue\n * @classdesc Wrapper for ICAL.Binary\n *\n * @url https://tools.ietf.org/html/rfc5545#section-3.1.3\n * @url https://github.com/mozilla-comm/ical.js/blob/master/lib/ical/binary.js\n */\nexport default class BinaryValue extends AbstractValue {\n\n\t/**\n\t * Sets the raw b64 encoded value\n\t *\n\t * @return {string}\n\t */\n\tget rawValue() {\n\t\treturn this._innerValue.value\n\t}\n\n\t/**\n\t * Gets the raw b64 encoded value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {string} value - The new raw value\n\t */\n\tset rawValue(value) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue.value = value\n\t}\n\n\t/**\n\t * Gets the decoded value\n\t *\n\t * @return {string}\n\t */\n\tget value() {\n\t\treturn this._innerValue.decodeValue()\n\t}\n\n\t/**\n\t * Sets the decoded Value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {string} decodedValue - The new encoded value\n\t */\n\tset value(decodedValue) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue.setEncodedValue(decodedValue)\n\t}\n\n\t/**\n\t * clones this value\n\t *\n\t * @return {BinaryValue}\n\t */\n\tclone() {\n\t\treturn BinaryValue.fromRawValue(this._innerValue.value)\n\t}\n\n\t/**\n\t * Create a new BinaryValue object from an ICAL.Binary object\n\t *\n\t * @param {ICAL.Binary} icalValue - The ICAL.Binary object\n\t * @return {BinaryValue}\n\t */\n\tstatic fromICALJs(icalValue) {\n\t\treturn new BinaryValue(icalValue)\n\t}\n\n\t/**\n\t * Create a new BinaryValue object from a raw b64 encoded value\n\t *\n\t * @param {string} rawValue - The raw value\n\t * @return {BinaryValue}\n\t */\n\tstatic fromRawValue(rawValue) {\n\t\tconst icalBinary = new ICAL.Binary(rawValue)\n\t\treturn BinaryValue.fromICALJs(icalBinary)\n\t}\n\n\t/**\n\t * Create a new BinaryValue object from decoded value\n\t *\n\t * @param {string} decodedValue - The encoded value\n\t * @return {BinaryValue}\n\t */\n\tstatic fromDecodedValue(decodedValue) {\n\t\tconst icalBinary = new ICAL.Binary()\n\t\ticalBinary.setEncodedValue(decodedValue)\n\t\treturn BinaryValue.fromICALJs(icalBinary)\n\t}\n\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\nimport AbstractValue from './abstractValue.js'\nimport ICAL from 'ical.js'\n\n/**\n * @class DurationValue\n * @classdesc Wrapper for ICAL.Duration\n *\n * @url https://tools.ietf.org/html/rfc5545#section-3.3.6\n * @url https://github.com/mozilla-comm/ical.js/blob/master/lib/ical/duration.js\n */\nexport default class DurationValue extends AbstractValue {\n\n\t/**\n\t * Gets the weeks of the stored duration-value\n\t *\n\t * @return {number}\n\t */\n\tget weeks() {\n\t\treturn this._innerValue.weeks\n\t}\n\n\t/**\n\t * Sets the weeks of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if value is negative\n\t * @param {number} weeks Amount of weeks\n\t */\n\tset weeks(weeks) {\n\t\tthis._modifyContent()\n\t\tif (weeks < 0) {\n\t\t\tthrow new TypeError('Weeks cannot be negative, use isNegative instead')\n\t\t}\n\n\t\tthis._innerValue.weeks = weeks\n\t}\n\n\t/**\n\t * Gets the days of the stored duration-value\n\t *\n\t * @return {number}\n\t */\n\tget days() {\n\t\treturn this._innerValue.days\n\t}\n\n\t/**\n\t * Sets the days of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if value is negative\n\t * @param {number} days Amount of days\n\t */\n\tset days(days) {\n\t\tthis._modifyContent()\n\t\tif (days < 0) {\n\t\t\tthrow new TypeError('Days cannot be negative, use isNegative instead')\n\t\t}\n\n\t\tthis._innerValue.days = days\n\t}\n\n\t/**\n\t * Gets the hours of the stored duration-value\n\t *\n\t * @return {number}\n\t */\n\tget hours() {\n\t\treturn this._innerValue.hours\n\t}\n\n\t/**\n\t * Sets the weeks of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if value is negative\n\t * @param {number} hours Amount of hours\n\t */\n\tset hours(hours) {\n\t\tthis._modifyContent()\n\t\tif (hours < 0) {\n\t\t\tthrow new TypeError('Hours cannot be negative, use isNegative instead')\n\t\t}\n\n\t\tthis._innerValue.hours = hours\n\t}\n\n\t/**\n\t * Gets the minutes of the stored duration-value\n\t *\n\t * @return {number}\n\t */\n\tget minutes() {\n\t\treturn this._innerValue.minutes\n\t}\n\n\t/**\n\t * Sets the minutes of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if value is negative\n\t * @param {number} minutes Amount of minutes\n\t */\n\tset minutes(minutes) {\n\t\tthis._modifyContent()\n\t\tif (minutes < 0) {\n\t\t\tthrow new TypeError('Minutes cannot be negative, use isNegative instead')\n\t\t}\n\n\t\tthis._innerValue.minutes = minutes\n\t}\n\n\t/**\n\t * Gets the seconds of the stored duration-value\n\t *\n\t * @return {number}\n\t */\n\tget seconds() {\n\t\treturn this._innerValue.seconds\n\t}\n\n\t/**\n\t * Sets the seconds of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if value is negative\n\t * @param {number} seconds Amount of seconds\n\t */\n\tset seconds(seconds) {\n\t\tthis._modifyContent()\n\t\tif (seconds < 0) {\n\t\t\tthrow new TypeError('Seconds cannot be negative, use isNegative instead')\n\t\t}\n\n\t\tthis._innerValue.seconds = seconds\n\t}\n\n\t/**\n\t * Gets the negative-indicator of the stored duration-value\n\t *\n\t * @return {boolean}\n\t */\n\tget isNegative() {\n\t\treturn this._innerValue.isNegative\n\t}\n\n\t/**\n\t * Gets the negative-indicator of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {boolean} isNegative Whether or not the duration is negative\n\t */\n\tset isNegative(isNegative) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue.isNegative = !!isNegative\n\t}\n\n\t/**\n\t * Gets the amount of total seconds of the stored duration-value\n\t *\n\t * @return {* | number}\n\t */\n\tget totalSeconds() {\n\t\treturn this._innerValue.toSeconds()\n\t}\n\n\t/**\n\t * Sets the amount of total seconds of the stored duration-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {number} totalSeconds The total amounts of seconds to set\n\t */\n\tset totalSeconds(totalSeconds) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue.fromSeconds(totalSeconds)\n\t}\n\n\t/**\n\t * Compares this duration to another one\n\t *\n\t * @param {DurationValue} otherDuration The duration to compare to\n\t * @return {number} -1, 0 or 1 for less/equal/greater\n\t */\n\tcompare(otherDuration) {\n\t\treturn this._innerValue.compare(otherDuration.toICALJs())\n\t}\n\n\t/**\n\t * Adds the value of another duration to this one\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {DurationValue} otherDuration The duration to add\n\t */\n\taddDuration(otherDuration) {\n\t\tthis._modifyContent()\n\t\tthis.totalSeconds += otherDuration.totalSeconds\n\t\tthis._innerValue.normalize()\n\t}\n\n\t/**\n\t * Subtract the value of another duration from this one\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {DurationValue} otherDuration The duration to subtract\n\t */\n\tsubtractDuration(otherDuration) {\n\t\tthis._modifyContent()\n\t\tthis.totalSeconds -= otherDuration.totalSeconds\n\t\tthis._innerValue.normalize()\n\t}\n\n\t/**\n\t * clones this value\n\t *\n\t * @return {DurationValue}\n\t */\n\tclone() {\n\t\treturn DurationValue.fromICALJs(this._innerValue.clone())\n\t}\n\n\t/**\n\t * Create a new DurationValue object from an ICAL.Duration object\n\t *\n\t * @param {ICAL.Duration} icalValue The ical.js duration value\n\t * @return {DurationValue}\n\t */\n\tstatic fromICALJs(icalValue) {\n\t\treturn new DurationValue(icalValue)\n\t}\n\n\t/**\n\t * Create a new DurationValue object from a number of seconds\n\t *\n\t * @param {number} seconds Total amount of seconds\n\t * @return {DurationValue}\n\t */\n\tstatic fromSeconds(seconds) {\n\t\tconst icalDuration = ICAL.Duration.fromSeconds(seconds)\n\t\treturn new DurationValue(icalDuration)\n\n\t}\n\n\t/**\n\t * Create a new DurationValue object from data\n\t *\n\t * @param {object} data The destructuring object\n\t * @param {number=} data.weeks Number of weeks to set\n\t * @param {number=} data.days Number of days to set\n\t * @param {number=} data.hours Number of hours to set\n\t * @param {number=} data.minutes Number of minutes to set\n\t * @param {number=} data.seconds Number of seconds to set\n\t * @param {boolean=} data.isNegative Whether or not duration is negative\n\t * @return {DurationValue}\n\t */\n\tstatic fromData(data) {\n\t\tconst icalDuration = ICAL.Duration.fromData(data)\n\t\treturn new DurationValue(icalDuration)\n\t}\n\n}\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke <georg-nextcloud@ehrke.email>\n *\n * @license AGPL-3.0-or-later\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as\n * published by the Free Software Foundation, either version 3 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n *\n */\nimport AbstractValue from './abstractValue.js'\nimport DurationValue from './durationValue.js'\nimport ICAL from 'ical.js'\n\n/**\n * @class DateTimeValue\n * @classdesc Wrapper for ICAL.Time\n *\n * @url https://tools.ietf.org/html/rfc5545#section-3.3.4\n * @url https://tools.ietf.org/html/rfc5545#section-3.3.5\n * @url https://tools.ietf.org/html/rfc5545#section-3.3.12\n * @url https://github.com/mozilla-comm/ical.js/blob/master/lib/ical/time.js\n */\nexport default class DateTimeValue extends AbstractValue {\n\n\t/**\n\t * Gets the year of the stored date-time-value\n\t *\n\t * @return {number}\n\t */\n\tget year() {\n\t\treturn this._innerValue.year\n\t}\n\n\t/**\n\t * Sets the year of the stored date-time-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {number} year Number of years to set\n\t */\n\tset year(year) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue.year = year\n\t}\n\n\t/**\n\t * Gets the month of the stored date-time-value\n\t *\n\t * @return {number}\n\t */\n\tget month() {\n\t\treturn this._innerValue.month\n\t}\n\n\t/**\n\t * Sets the month of the stored date-time-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {number} month Number of months to set\n\t */\n\tset month(month) {\n\t\tthis._modifyContent()\n\t\tif (month < 1 || month > 12) {\n\t\t\tthrow new TypeError('Month out of range')\n\t\t}\n\n\t\tthis._innerValue.month = month\n\t}\n\n\t/**\n\t * Gets the day of the stored date-time-value\n\t *\n\t * @return {number}\n\t */\n\tget day() {\n\t\treturn this._innerValue.day\n\t}\n\n\t/**\n\t * Sets the day of the stored date-time-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if out of range\n\t * @param {number} day Number of days to set\n\t */\n\tset day(day) {\n\t\tthis._modifyContent()\n\t\tif (day < 1 || day > 31) {\n\t\t\tthrow new TypeError('Day out of range')\n\t\t}\n\n\t\tthis._innerValue.day = day\n\t}\n\n\t/**\n\t * Gets the hour of the stored date-time-value\n\t *\n\t * @return {number}\n\t */\n\tget hour() {\n\t\treturn this._innerValue.hour\n\t}\n\n\t/**\n\t * Sets the hour of the stored date-time-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if out of range\n\t * @param {number} hour Number of hours to set\n\t */\n\tset hour(hour) {\n\t\tthis._modifyContent()\n\t\tif (hour < 0 || hour > 23) {\n\t\t\tthrow new TypeError('Hour out of range')\n\t\t}\n\n\t\tthis._innerValue.hour = hour\n\t}\n\n\t/**\n\t * Gets the minute of the stored date-time-value\n\t *\n\t * @return {number}\n\t */\n\tget minute() {\n\t\treturn this._innerValue.minute\n\t}\n\n\t/**\n\t * Sets the minute of the stored date-time-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if out of range\n\t * @param {number} minute Number of minutes to set\n\t */\n\tset minute(minute) {\n\t\tthis._modifyContent()\n\t\tif (minute < 0 || minute > 59) {\n\t\t\tthrow new TypeError('Minute out of range')\n\t\t}\n\n\t\tthis._innerValue.minute = minute\n\t}\n\n\t/**\n\t * Gets the second of the stored date-time-value\n\t *\n\t * @return {number}\n\t */\n\tget second() {\n\t\treturn this._innerValue.second\n\t}\n\n\t/**\n\t * Sets the second of the stored date-time-value\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @throws {TypeError} if out of range\n\t * @param {number} second Number of seconds to set\n\t */\n\tset second(second) {\n\t\tthis._modifyContent()\n\t\tif (second < 0 || second > 59) {\n\t\t\tthrow new TypeError('Second out of range')\n\t\t}\n\n\t\tthis._innerValue.second = second\n\t}\n\n\t/**\n\t * Gets the timezone of this date-time-value\n\t *\n\t * @return {string | null}\n\t */\n\tget timezoneId() {\n\t\t// If zone.tzid is set and it's not 'floating' nor 'UTC', then it's a proper\n\t\t// timezone that we also have a timezone id for\n\t\tif (this._innerValue.zone.tzid && this._innerValue.zone.tzid !== 'floating' && this._innerValue.zone.tzid === 'UTC') {\n\t\t\treturn this._innerValue.zone.tzid\n\t\t}\n\n\t\t// If there is a timezone set, but we didn't have a zone.tzid in the previous if,\n\t\t// this means that the tzid does not have a definition stored along it.\n\t\t// we will keep this information anyway to not lose it\n\t\tif (this._innerValue.timezone) {\n\t\t\treturn this._innerValue.timezone\n\t\t}\n\n\t\t// this is the case when it's floating / UTC\n\t\treturn this._innerValue.zone.tzid || null\n\t}\n\n\t/**\n\t * Gets whether this date-time-value is a date or date-time\n\t *\n\t * @return {boolean}\n\t */\n\tget isDate() {\n\t\treturn this._innerValue.isDate\n\t}\n\n\t/**\n\t * Sets whether this date-time-value is a date or date-time\n\t *\n\t * @throws {ModificationNotAllowedError} if value is locked for modification\n\t * @param {boolean} isDate Whether this is a date or date-time value\n\t */\n\tset isDate(isDate) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue.isDate = !!isDate\n\n\t\tif (isDate) {\n\t\t\tthis._innerValue.hour = 0\n\t\t\tthis._innerValue.minute = 0\n\t\t\tthis._innerValue.second = 0\n\t\t}\n\t}\n\n\t/**\n\t * Gets the unix-time\n\t *\n\t * @return {number}\n\t */\n\tget unixTime() {\n\t\treturn this._innerValue.toUnixTime()\n\t}\n\n\t/**\n\t * returns vanilla javascript date object\n\t *\n\t * @return {Date}\n\t */\n\tget jsDate() {\n\t\treturn this._innerValue.toJSDate()\n\t}\n\n\t/**\n\t * Adds a duration to this date-time-value\n\t *\n\t * @param {DurationValue} duration The duration to ad\n\t */\n\taddDuration(duration) {\n\t\tthis._innerValue.addDuration(duration.toICALJs())\n\t}\n\n\t/**\n\t * Subtract another date excluding timezones\n\t *\n\t * @param {DateTimeValue} other The date-time value to subtract\n\t * @return {DurationValue}\n\t */\n\tsubtractDateWithoutTimezone(other) {\n\t\tconst icalDuration = this._innerValue.subtractDate(other.toICALJs())\n\t\treturn DurationValue.fromICALJs(icalDuration)\n\t}\n\n\t/**\n\t * Subtract another date, taking timezones into account\n\t *\n\t * @param {DateTimeValue} other The date-time value to subtract\n\t * @return {DurationValue}\n\t */\n\tsubtractDateWithTimezone(other) {\n\t\tconst icalDuration = this._innerValue.subtractDateTz(other.toICALJs())\n\t\treturn DurationValue.fromICALJs(icalDuration)\n\t}\n\n\t/**\n\t * Compares this DateTimeValue object with another one\n\t *\n\t * @param {DateTimeValue} other The date-time to compare to\n\t * @return {number} -1, 0 or 1 for less/equal/greater\n\t */\n\tcompare(other) {\n\t\treturn this._innerValue.compare(other.toICALJs())\n\t}\n\n\t/**\n\t * Compares only the date part in a given timezone\n\t *\n\t * @param {DateTimeValue} other The date-time to compare to\n\t * @param {Timezone} timezone The timezone to compare in\n\t * @return {number} -1, 0 or 1 for less/equal/greater\n\t */\n\tcompareDateOnlyInGivenTimezone(other, timezone) {\n\t\treturn this._innerValue.compareDateOnlyTz(other.toICALJs(), timezone.toICALTimezone())\n\t}\n\n\t/**\n\t * Returns a clone of this object which was converted to a different timezone\n\t *\n\t * @param {Timezone} timezone TimezoneId to convert to\n\t * @return {DateTimeValue}\n\t */\n\tgetInTimezone(timezone) {\n\t\tconst clonedICALTime = this._innerValue.convertToZone(timezone.toICALTimezone())\n\t\treturn DateTimeValue.fromICALJs(clonedICALTime)\n\t}\n\n\t/**\n\t * Get the inner ICAL.Timezone\n\t *\n\t * @return {ICAL.Timezone}\n\t * @package\n\t */\n\tgetICALTimezone() {\n\t\treturn this._innerValue.zone\n\t}\n\n\t/**\n\t * Returns a clone of this object which was converted to a different timezone\n\t *\n\t * @param {ICAL.Timezone} timezone TimezoneId to convert to\n\t * @return {DateTimeValue}\n\t * @package\n\t */\n\tgetInICALTimezone(timezone) {\n\t\tconst clonedICALTime = this._innerValue.convertToZone(timezone)\n\t\treturn DateTimeValue.fromICALJs(clonedICALTime)\n\t}\n\n\t/**\n\t * Returns a clone of this object which was converted to UTC\n\t *\n\t * @return {DateTimeValue}\n\t */\n\tgetInUTC() {\n\t\tconst clonedICALTime = this._innerValue.convertToZone(ICAL.Timezone.utcTimezone)\n\t\treturn DateTimeValue.fromICALJs(clonedICALTime)\n\t}\n\n\t/**\n\t * This silently replaces the inner timezone without converting the actual time\n\t *\n\t * @param {ICAL.Timezone} timezone The timezone to replace with\n\t * @package\n\t */\n\tsilentlyReplaceTimezone(timezone) {\n\t\tthis._modify()\n\t\tthis._innerValue = new ICAL.Time({\n\t\t\tyear: this.year,\n\t\t\tmonth: this.month,\n\t\t\tday: this.day,\n\t\t\thour: this.hour,\n\t\t\tminute: this.minute,\n\t\t\tsecond: this.second,\n\t\t\tisDate: this.isDate,\n\t\t\ttimezone,\n\t\t})\n\t}\n\n\t/**\n\t * Replaces the inner timezone without converting the actual time\n\t *\n\t * @param {Timezone} timezone The timezone to replace with\n\t */\n\treplaceTimezone(timezone) {\n\t\tthis._modifyContent()\n\t\tthis._innerValue = ICAL.Time.fromData({\n\t\t\tyear: this.year,\n\t\t\tmonth: this.month,\n\t\t\tday: this.day,\n\t\t\thour: this.hour,\n\t\t\tminute: this.minute,\n\t\t\tsecond: this.second,\n\t\t\tisDate: this.isDate,\n\t\t}, timezone.toICALTimezone())\n\t}\n\n\t/**\n\t * Calculates the UTC offset of the date-time-value in its timezone\n\t *\n\t * @return {number}\n\t */\n\tutcOffset() {\n\t\treturn this._innerValue.utcOffset()\n\t}\n\n\t/**\n\t * Check if this is an event with floating time\n\t *\n\t * @return {boolean}\n\t */\n\tisFloatingTime() {\n\t\treturn this._innerValue.zone.tzid === 'floating'\n\t}\n\n\t/**\n\t * clones this value\n\t *\n\t * @return {DateTimeValue}\n\t */\n\tclone() {\n\t\treturn DateTimeValue.fromICALJs(this._innerValue.clone())\n\t}\n\n\t/**\n\t * Create a new DateTimeValue object from an ICAL.Time object\n\t *\n\t * @param {ICAL.Time} icalValue The ical.js Date value to initialise from\n\t * @return {DateTimeValue}\n\t */\n\tstatic fromICALJs(icalValue) {\n\t\treturn new DateTimeValue(icalValue)\n\t}\n\n\t/**\n\t * Creates a new DateTimeValue object based on a vanilla javascript object\n\t *\n\t * @param {Date} jsDate The JavaScript date to initialise from\n\t * @param {boolean=} useUTC Whether or not to treat it as UTC\n\t * @return {DateTimeValue}\n\t */\n\tstatic fromJSDate(jsDate, useUTC = false) {\n\t\tconst icalValue = ICAL.Time.fromJSDate(jsDate, useUTC)\n\t\treturn DateTimeValue.fromICALJs(icalValue)\n\t}\n\n\t/**\n\t * Creates a new DateTimeValue object based on simple parameters\n\t *\n\t * @param {object} data The destructuring object\n\t * @param {number=} data.year Amount of years to set\n\t * @param {number=} data.month Amount of month to set (1-based)\n\t * @param {number=} data.day Amount of days to set\n\t * @param {number=} data.hour Amount of hours to set\n\t * @param {number=} data.minute Amount of minutes to set\n\t * @param {number=} data.second Amount of seconds to set\n\t * @param {boolean=} data.isDate Whether this is a date or date-time\n\t * @param {Timezone=} timezone The timezone of the DateTimeValue\n\t * @return {DateTimeValue}\n\t */\n\tstatic fromData(data, timezone) {\n\t\tconst icalValue = ICAL.Time.fromData(data, timezone\n\t\t\t? timezone.toICALTimezone()\n\t\t\t: undefined)\n\t\treturn DateTimeValue.fromICALJs(icalValue)\n\t}\n\n}\n\nDateTimeValue.SUNDAY = ICAL.Time.SUNDAY\nDateTimeValue.MONDAY = ICAL.Time.MONDAY\nDateTimeValue.TUESDAY = ICAL.Time.TUESDAY\nDateTimeValue.WEDNESDAY = ICAL.Time.WEDNESDAY\nDateTimeValue.THURSDAY = ICAL.Time.THURSDAY\nDateTimeValue.FRIDAY = ICAL.Time.FRIDAY\nDateTimeValue.SATURDAY = ICAL.Time.SATURDAY\n\nDateTimeValue.DEFAULT_WEEK_START = DateTimeValue.MONDAY\n","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n