diff --git a/calendar/js/calendar-dashboard.js b/calendar/js/calendar-dashboard.js index 9ebe17c..b77136e 100644 --- a/calendar/js/calendar-dashboard.js +++ b/calendar/js/calendar-dashboard.js @@ -1322,7 +1322,7 @@ function b(n) { /******/ // This function allow to reference async chunks /******/ __webpack_require__.u = (chunkId) => { /******/ // return url for filenames based on template -/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"273df538e0dc19672feb","vendors-node_modules_nextcloud_vue-dashboard_dist_vue-dashboard_js-node_modules_css-loader_di-9e6f3d":"86eaa619747854c0da61","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"94fac30d128df46a89a6","src_store_index_js":"2c493e91e10998374f26","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"740a2859d1f364b508c1","dashboard-lazy":"0dd354a2fd4b9e38ddcf","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + ""; +/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"273df538e0dc19672feb","vendors-node_modules_nextcloud_vue-dashboard_dist_vue-dashboard_js-node_modules_css-loader_di-9e6f3d":"86eaa619747854c0da61","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"d2880e4c429713e99f7b","src_store_index_js":"ec20095566748d2f9a12","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"4ec4f960e50da6a1f2cd","dashboard-lazy":"0dd354a2fd4b9e38ddcf","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + ""; /******/ }; /******/ })(); /******/ diff --git a/calendar/js/calendar-main.js b/calendar/js/calendar-main.js index 2c68cd1..d0d6f2e 100644 --- a/calendar/js/calendar-main.js +++ b/calendar/js/calendar-main.js @@ -22395,6 +22395,16 @@ var render = function render() { "add-single-value": _vm.addArticle, "remove-single-value": _vm.removeArticle } + }), _vm._v(" "), _c("PropertyText", { + attrs: { + "is-read-only": _vm.isReadOnly, + "prop-model": _vm.rfcProps.comment, + value: _vm.comment, + "linkify-links": false + }, + on: { + "update:value": _vm.updateComment + } }), _vm._v(" "), _vm.isViewedByAttendee ? _c("InvitationResponseButtons", { attrs: { attendee: _vm.userAsAttendee, @@ -22954,6 +22964,16 @@ var render = function render() { "add-single-value": _vm.addArticle, "remove-single-value": _vm.removeArticle } + }), _vm._v(" "), _c("PropertyText", { + attrs: { + "is-read-only": _vm.isReadOnly, + "prop-model": _vm.rfcProps.comment, + value: _vm.comment, + "linkify-links": false + }, + on: { + "update:value": _vm.updateComment + } }), _vm._v(" "), _c("InviteesList", { staticClass: "event-popover__invitees", attrs: { @@ -26281,7 +26301,7 @@ __webpack_require__.r(__webpack_exports__); * Returns an object with properties from RFCs including * their displayName, a description, options, etc. * - * @return {{geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}} + * @return {{comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}} */ rfcProps() { return (0,_models_rfcProps_js__WEBPACK_IMPORTED_MODULE_0__.getRFCProperties)(); @@ -26543,6 +26563,17 @@ __webpack_require__.r(__webpack_exports__); location }); }, + /** + * Updates the comments of this event + * + * @param {string} comment New comments + */ + updateComment(comment) { + this.$store.commit('changeComment', { + calendarObjectInstance: this.calendarObjectInstance, + comment + }); + }, /** * Updates the client of the event * @@ -28283,6 +28314,7 @@ const mapEventComponentToEventObject = eventComponent => { location: eventComponent.location, client: "CLIENT", embalmer: "TEST", + comment: "", description: eventComponent.description, accessClass: eventComponent.accessClass, status: eventComponent.status, @@ -28374,6 +28406,9 @@ const mapEventComponentToEventObject = eventComponent => { if (eventComponent.hasProperty('EMBALMER')) { eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER'); } + if (eventComponent.hasProperty('COMMENT')) { + eventObject.comment = eventComponent.getFirstPropertyFirstValue('COMMENT'); + } return eventObject; }; @@ -29225,6 +29260,15 @@ const getRFCProperties = () => { placeholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Choisir les soins'), tagPlaceholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Choisir les soins'), options: [] + }, + comment: { + readableName: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Comment'), + icon: 'TextBoxOutline', + info: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Commentaires.'), + placeholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Commentaires'), + tagPlaceholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Commentaires'), + options: [], + defaultNumberOfRows: 4 } }; }; @@ -31543,6 +31587,22 @@ const mutations = { calendarObjectInstance.eventComponent.location = location; calendarObjectInstance.location = location; }, + /** + * Change the comment of an event + * + * @param {object} state The Vuex state + * @param {object} data The destructuring object + * @param {object} data.calendarObjectInstance The calendarObjectInstance object + * @param {string} data.comment New comment to set + */ + changeComment(state, _ref11) { + let { + calendarObjectInstance, + comment + } = _ref11; + calendarObjectInstance.eventComponent.comment = comment; + calendarObjectInstance.comment = comment; + }, /** * Change the client of an event * @@ -33955,7 +34015,31 @@ const actions = { if (eventComponent != null) { if (eventComponent.client != null) { let newClientKeyValue = "CLIENT:" + eventComponent.client; - icsValue = icsValue.replace(/CLIENT:\d+/, newClientKeyValue); + let regexEmptyClient = /CLIENT:(?!\d)(?=\s*[\r\n])/g; + if (regexEmptyClient.test(icsValue)) { + icsValue = icsValue.replace(regexEmptyClient, newClientKeyValue); + } + let regex = /CLIENT:\d+/; + if (regex.test(icsValue)) { + icsValue = icsValue.replace(regex, newClientKeyValue); + } else { + const customKeyValue = { + "CLIENT": eventComponent.client + }; + icsValue = (0,_models_calendarObject_js__WEBPACK_IMPORTED_MODULE_0__.setCustomKeyValuesArrayToIcsAndReturnIcs)(icsValue, customKeyValue); + } + } + if (eventComponent.comment != null) { + let newCommentKeyValue = "COMMENT:" + eventComponent.comment; + let regex = /^COMMENT:.*$/m; + if (regex.test(icsValue)) { + icsValue = icsValue.replace(regex, newCommentKeyValue); + } else { + const customKeyValue = { + "COMMENT": eventComponent.comment + }; + icsValue = (0,_models_calendarObject_js__WEBPACK_IMPORTED_MODULE_0__.setCustomKeyValuesArrayToIcsAndReturnIcs)(icsValue, customKeyValue); + } } if (eventComponent.isPrivate != null) { let isPrivateValue = eventComponent.isPrivate ? "1" : "0"; diff --git a/calendar/js/calendar-reference.js b/calendar/js/calendar-reference.js index 29cd3db..8d24385 100644 --- a/calendar/js/calendar-reference.js +++ b/calendar/js/calendar-reference.js @@ -8865,7 +8865,7 @@ window._registerCustomPickerElement = _; /******/ // This function allow to reference async chunks /******/ __webpack_require__.u = (chunkId) => { /******/ // return url for filenames based on template -/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"273df538e0dc19672feb","vendors-node_modules_autosize_dist_autosize_esm_js-node_modules_html-entities_lib_index_js-no-4072c5":"56373f2063898525e8de","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"94fac30d128df46a89a6","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"740a2859d1f364b508c1","src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254":"925781d9db1ffc96ba17","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","src_store_index_js":"2c493e91e10998374f26","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","public-calendar-subscription-picker":"9168fca99a878d4c37e3","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + ""; +/******/ return "calendar-" + chunkId + ".js?v=" + {"vendors-node_modules_vue_dist_vue_runtime_esm_js":"7e3171593bdc0f62040b","vendors-node_modules_nextcloud_capabilities_dist_index_js-node_modules_nextcloud_vue-select_d-877981":"7bde6f386631234ba146","vendors-node_modules_nextcloud_cdav-library_dist_dist_js-node_modules_nextcloud_logger_dist_i-36c16b":"c3b3db23da041c717fc1","vendors-node_modules_vue-material-design-icons_CalendarBlank_vue-node_modules_vue-material-de-e2c1f8":"2e0b0e8bc0e8488c397c","vendors-node_modules_vue-material-design-icons_CalendarBlankOutline_vue-node_modules_nextclou-4adead":"273df538e0dc19672feb","vendors-node_modules_autosize_dist_autosize_esm_js-node_modules_html-entities_lib_index_js-no-4072c5":"56373f2063898525e8de","src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790":"d2880e4c429713e99f7b","src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258":"4ec4f960e50da6a1f2cd","src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254":"cd8a0993186cf9d527b6","vendors-node_modules_webdav_dist_web_index_js":"454da8f908d41b47c607","src_store_index_js":"ec20095566748d2f9a12","vendors-node_modules_path-browserify_index_js-node_modules_nextcloud_dialogs_dist_chunks_Dial-e0595f":"728c782d2751f8e6150a","node_modules_nextcloud_dialogs_dist_legacy_mjs":"8be838e4c6e9aae56c87","vendors-node_modules_nextcloud_dialogs_dist_chunks_FilePicker-8ibBgPg__mjs":"ea54a36450de178d1141","public-calendar-subscription-picker":"9168fca99a878d4c37e3","vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96":"ce1bed825f57dd1d117a","node_modules_moment_locale_sync_recursive_":"4bc2c39c5e0ff182c2e3"}[chunkId] + ""; /******/ }; /******/ })(); /******/ diff --git a/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js b/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js index 9624305..5df3613 100644 --- a/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js +++ b/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js @@ -1054,4 +1054,4 @@ module.exports = "data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/sv /***/ }) }]); -//# sourceMappingURL=calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map?v=b5a1f8246e3d20bdaf6b \ No newline at end of file +//# sourceMappingURL=calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map?v=b5a1f8246e3d20bdaf6b diff --git a/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map b/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map index da90ffc..15b2821 100644 --- a/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map +++ b/calendar/js/calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js.map @@ -1 +1 @@ -{"version":3,"file":"calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js?v=b5a1f8246e3d20bdaf6b","mappings":";;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACtKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///calendar/src\\fullcalendar\\eventSources\\eventSourceFunction.js","webpack:///calendar/src\\utils\\moment.js","webpack:///calendar/node_modules\\moment\\locale|lazy|\\^\\.*\\.js$\\|groupOptions: {}|namespace object"],"sourcesContent":["/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke \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 .\n *\n */\nimport { translate as t } from '@nextcloud/l10n';\nimport { hexToRGB, isLight, generateTextColorForHex, getHexForColorName } from '../../utils/color.js';\nimport logger from '../../utils/logger.js';\nimport { getAllObjectsInTimeRange } from '../../utils/calendarObject.js';\n\n/**\n * convert an array of calendar-objects to events\n *\n * @param {CalendarObject[]} calendarObjects Array of calendar-objects to turn into fc events\n * @param {object} calendar The calendar object\n * @param {Date} start Start of time-range\n * @param {Date} end End of time-range\n * @param {Timezone} timezone Desired time-zone\n * @return {object}[]\n */\nexport function eventSourceFunction(calendarObjects, calendar, start, end, timezone) {\n const fcEvents = [];\n const authUser = OC.currentUser;\n for (const calendarObject of calendarObjects) {\n let allObjectsInTimeRange;\n try {\n allObjectsInTimeRange = getAllObjectsInTimeRange(calendarObject, start, end);\n } catch (error) {\n logger.error(error.message);\n continue;\n }\n for (const object of allObjectsInTimeRange) {\n const classNames = [];\n if (object.status === 'CANCELLED') {\n classNames.push('fc-event-nc-cancelled');\n } else if (object.status === 'TENTATIVE') {\n classNames.push('fc-event-nc-tentative');\n }\n if (object.hasComponent('VALARM')) {\n classNames.push('fc-event-nc-alarms');\n }\n\n // For now, we only display\n if (object.name === 'VTODO' && object.endDate === null) {\n continue;\n }\n let jsStart, jsEnd;\n if (object.name === 'VEVENT') {\n jsStart = object.startDate.getInTimezone(timezone).jsDate;\n jsEnd = object.endDate.getInTimezone(timezone).jsDate;\n } else if (object.name === 'VTODO') {\n // For tasks, we only want to display when it is due,\n // not for how long it has been in progress already\n jsStart = object.endDate.getInTimezone(timezone).jsDate;\n jsEnd = object.endDate.getInTimezone(timezone).jsDate;\n } else {\n // We do not want to display anything that's neither\n // an event nor a task\n continue;\n }\n\n // Technically, an event's end is not allowed to be equal to it's start,\n // because the event's end is exclusive. Most calendar applications\n // (including all big ones) allow creating such events anyway (we do too).\n // If the event's start is equal to it's end, fullcalendar is giving\n // the event a default length of one hour. We are preventing that by\n // adding one second to the end in that case.\n if (jsStart.getTime() === jsEnd.getTime()) {\n jsEnd.setSeconds(jsEnd.getSeconds() + 1);\n }\n if (object.name === 'VTODO') {\n classNames.push('fc-event-nc-task');\n if (object.percent === 100 || object.status === 'COMPLETED') {\n classNames.push('fc-event-nc-task-completed');\n }\n }\n let title;\n if (object.name === 'VEVENT') {\n if (object.title) {\n title = object.title.replace(/\\n/g, ' ');\n } else {\n title = t('calendar', 'Untitled event');\n }\n } else {\n if (object.title) {\n title = object.title.replace(/\\n/g, ' ');\n } else {\n title = t('calendar', 'Untitled task');\n }\n if (object.percent !== null) {\n title += \" (\".concat(object.percent, \"%)\");\n }\n }\n let isPrivateEvent = false;\n let objectProperties = object._properties.get('ISPRIVATE');\n if (objectProperties && objectProperties.length > 0) {\n isPrivateEvent = objectProperties[0]._value == \"1\" ? true : false;\n }\n\n //Get owen object's user\n let owenUrl = calendarObject.dav._parent.owner;\n let owenUser = owenUrl.replace('/remote.php/dav/principals/users/', '').split('/')[0];\n if (!owenUser) {\n //Get from url shared calendar\n owenUrl = calendarObject.dav._parent.url;\n owenUser = owenUrl.replace('/remote.php/dav/calendars/' + authUser + '/personal_shared_by_', '').split('/')[0];\n }\n const isOwenOfEvent = owenUser == authUser;\n if (isPrivateEvent && !isOwenOfEvent) {\n title = t('calendar', \"Absent (\".concat(owenUser, \")\"));\n }\n const fcEvent = {\n id: [calendarObject.id, object.id].join('###'),\n title,\n allDay: object.isAllDay(),\n start: jsStart,\n end: jsEnd,\n // start: formatLocal(jsStart, object.isAllDay()),\n // end: formatLocal(jsEnd, object.isAllDay()),\n classNames,\n extendedProps: {\n objectId: calendarObject.id,\n recurrenceId: object.getReferenceRecurrenceId() ? object.getReferenceRecurrenceId().unixTime : null,\n canModifyAllDay: object.canModifyAllDay(),\n calendarOrder: calendar.order,\n calendarName: calendar.displayName,\n calendarId: calendar.id,\n darkText: isLight(hexToRGB(calendar.color)),\n objectType: object.name,\n percent: object.percent || null,\n davUrl: calendarObject.dav.url,\n location: object.location,\n description: object.description,\n isPrivate: isPrivateEvent,\n calendarObjectOwen: owenUser,\n calendarObjectIsOwen: isOwenOfEvent\n }\n };\n if (object.color) {\n const customColor = getHexForColorName(object.color);\n if (customColor) {\n fcEvent.backgroundColor = customColor;\n fcEvent.borderColor = customColor;\n fcEvent.textColor = generateTextColorForHex(customColor);\n }\n }\n fcEvents.push(fcEvent);\n }\n }\n return fcEvents;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @copyright Copyright (c) 2018 John Molakvoæ\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getFirstDay, getLanguage, getLocale } from '@nextcloud/l10n';\nimport moment from '@nextcloud/moment';\n\n/**\r\n *\r\n * @return {Promise}\r\n */\nexport default async function loadMomentLocalization() {\n const locale = getLocale().replace('_', '-').toLowerCase();\n const language = getLanguage().replace('_', '-').toLowerCase();\n if (locale === language) {\n return getLocaleFor(locale);\n }\n const [realLocale, realLanguage] = await Promise.all([getLocaleFor(locale), getLocaleFor(language)]);\n if (realLocale === realLanguage) {\n return realLocale;\n }\n const name = \"nextcloud-calendar-fake-locale-\".concat(realLocale, \"-\").concat(realLanguage);\n moment.defineLocale(name, {\n parentLocale: realLanguage,\n longDateFormat: {\n LT: moment.localeData(realLocale).longDateFormat('LT'),\n LTS: moment.localeData(realLocale).longDateFormat('LTS'),\n L: moment.localeData(realLocale).longDateFormat('L'),\n LL: moment.localeData(realLocale).longDateFormat('LL'),\n LLL: moment.localeData(realLocale).longDateFormat('LLL'),\n LLLL: moment.localeData(realLocale).longDateFormat('LLLL'),\n l: moment.localeData(realLocale).longDateFormat('l'),\n ll: moment.localeData(realLocale).longDateFormat('ll'),\n lll: moment.localeData(realLocale).longDateFormat('lll'),\n llll: moment.localeData(realLocale).longDateFormat('llll')\n },\n week: {\n dow: getFirstDay(),\n doy: moment.localeData(realLocale).firstDayOfYear()\n }\n });\n return name;\n}\n\n/**\r\n * Dynamically loads the requested locale and returns the actually loaded locale\r\n *\r\n * @param {string} locale Name of locale to load\r\n * @return {Promise}\r\n */\nasync function getLocaleFor(locale) {\n // IMPORTANT: Keep each '/moment/local/...' string as is. Otherwise, webpack might not bundle\n // locale data because the contentRegExp fails to detect any files.\n try {\n // default load e.g. en-de\n await import(\"moment/locale/\".concat(locale, \".js\"));\n return locale;\n } catch (error) {\n const splitLocale = locale.split('-');\n try {\n // failure: fallback to first part of locale, which\n // should be language\n locale = splitLocale[0];\n await import(\"moment/locale/\".concat(locale, \".js\"));\n return locale;\n } catch (e) {\n // failure, fallback to english\n console.debug('Fallback to locale', 'en');\n // English is the default locale and doesn't need to imported.\n // It is already included in moment.js.\n }\n }\n return 'en';\n}","var map = {\n\t\"./af.js\": [\n\t\t\"./node_modules/moment/locale/af.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-dz.js\": [\n\t\t\"./node_modules/moment/locale/ar-dz.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-kw.js\": [\n\t\t\"./node_modules/moment/locale/ar-kw.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-ly.js\": [\n\t\t\"./node_modules/moment/locale/ar-ly.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-ma.js\": [\n\t\t\"./node_modules/moment/locale/ar-ma.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-ps.js\": [\n\t\t\"./node_modules/moment/locale/ar-ps.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-sa.js\": [\n\t\t\"./node_modules/moment/locale/ar-sa.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-tn.js\": [\n\t\t\"./node_modules/moment/locale/ar-tn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar.js\": [\n\t\t\"./node_modules/moment/locale/ar.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./az.js\": [\n\t\t\"./node_modules/moment/locale/az.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./be.js\": [\n\t\t\"./node_modules/moment/locale/be.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bg.js\": [\n\t\t\"./node_modules/moment/locale/bg.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bm.js\": [\n\t\t\"./node_modules/moment/locale/bm.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bn-bd.js\": [\n\t\t\"./node_modules/moment/locale/bn-bd.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bn.js\": [\n\t\t\"./node_modules/moment/locale/bn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bo.js\": [\n\t\t\"./node_modules/moment/locale/bo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./br.js\": [\n\t\t\"./node_modules/moment/locale/br.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bs.js\": [\n\t\t\"./node_modules/moment/locale/bs.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ca.js\": [\n\t\t\"./node_modules/moment/locale/ca.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./cs.js\": [\n\t\t\"./node_modules/moment/locale/cs.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./cv.js\": [\n\t\t\"./node_modules/moment/locale/cv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./cy.js\": [\n\t\t\"./node_modules/moment/locale/cy.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./da.js\": [\n\t\t\"./node_modules/moment/locale/da.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./de-at.js\": [\n\t\t\"./node_modules/moment/locale/de-at.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./de-ch.js\": [\n\t\t\"./node_modules/moment/locale/de-ch.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./de.js\": [\n\t\t\"./node_modules/moment/locale/de.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./dv.js\": [\n\t\t\"./node_modules/moment/locale/dv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./el.js\": [\n\t\t\"./node_modules/moment/locale/el.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-au.js\": [\n\t\t\"./node_modules/moment/locale/en-au.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-ca.js\": [\n\t\t\"./node_modules/moment/locale/en-ca.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-gb.js\": [\n\t\t\"./node_modules/moment/locale/en-gb.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-ie.js\": [\n\t\t\"./node_modules/moment/locale/en-ie.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-il.js\": [\n\t\t\"./node_modules/moment/locale/en-il.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-in.js\": [\n\t\t\"./node_modules/moment/locale/en-in.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-nz.js\": [\n\t\t\"./node_modules/moment/locale/en-nz.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-sg.js\": [\n\t\t\"./node_modules/moment/locale/en-sg.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./eo.js\": [\n\t\t\"./node_modules/moment/locale/eo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es-do.js\": [\n\t\t\"./node_modules/moment/locale/es-do.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es-mx.js\": [\n\t\t\"./node_modules/moment/locale/es-mx.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es-us.js\": [\n\t\t\"./node_modules/moment/locale/es-us.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es.js\": [\n\t\t\"./node_modules/moment/locale/es.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./et.js\": [\n\t\t\"./node_modules/moment/locale/et.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./eu.js\": [\n\t\t\"./node_modules/moment/locale/eu.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fa.js\": [\n\t\t\"./node_modules/moment/locale/fa.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fi.js\": [\n\t\t\"./node_modules/moment/locale/fi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fil.js\": [\n\t\t\"./node_modules/moment/locale/fil.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fo.js\": [\n\t\t\"./node_modules/moment/locale/fo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fr-ca.js\": [\n\t\t\"./node_modules/moment/locale/fr-ca.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fr-ch.js\": [\n\t\t\"./node_modules/moment/locale/fr-ch.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fr.js\": [\n\t\t\"./node_modules/moment/locale/fr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fy.js\": [\n\t\t\"./node_modules/moment/locale/fy.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ga.js\": [\n\t\t\"./node_modules/moment/locale/ga.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gd.js\": [\n\t\t\"./node_modules/moment/locale/gd.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gl.js\": [\n\t\t\"./node_modules/moment/locale/gl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gom-deva.js\": [\n\t\t\"./node_modules/moment/locale/gom-deva.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gom-latn.js\": [\n\t\t\"./node_modules/moment/locale/gom-latn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gu.js\": [\n\t\t\"./node_modules/moment/locale/gu.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./he.js\": [\n\t\t\"./node_modules/moment/locale/he.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hi.js\": [\n\t\t\"./node_modules/moment/locale/hi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hr.js\": [\n\t\t\"./node_modules/moment/locale/hr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hu.js\": [\n\t\t\"./node_modules/moment/locale/hu.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hy-am.js\": [\n\t\t\"./node_modules/moment/locale/hy-am.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./id.js\": [\n\t\t\"./node_modules/moment/locale/id.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./is.js\": [\n\t\t\"./node_modules/moment/locale/is.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./it-ch.js\": [\n\t\t\"./node_modules/moment/locale/it-ch.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./it.js\": [\n\t\t\"./node_modules/moment/locale/it.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ja.js\": [\n\t\t\"./node_modules/moment/locale/ja.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./jv.js\": [\n\t\t\"./node_modules/moment/locale/jv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ka.js\": [\n\t\t\"./node_modules/moment/locale/ka.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./kk.js\": [\n\t\t\"./node_modules/moment/locale/kk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./km.js\": [\n\t\t\"./node_modules/moment/locale/km.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./kn.js\": [\n\t\t\"./node_modules/moment/locale/kn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ko.js\": [\n\t\t\"./node_modules/moment/locale/ko.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ku-kmr.js\": [\n\t\t\"./node_modules/moment/locale/ku-kmr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ku.js\": [\n\t\t\"./node_modules/moment/locale/ku.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ky.js\": [\n\t\t\"./node_modules/moment/locale/ky.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lb.js\": [\n\t\t\"./node_modules/moment/locale/lb.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lo.js\": [\n\t\t\"./node_modules/moment/locale/lo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lt.js\": [\n\t\t\"./node_modules/moment/locale/lt.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lv.js\": [\n\t\t\"./node_modules/moment/locale/lv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./me.js\": [\n\t\t\"./node_modules/moment/locale/me.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mi.js\": [\n\t\t\"./node_modules/moment/locale/mi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mk.js\": [\n\t\t\"./node_modules/moment/locale/mk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ml.js\": [\n\t\t\"./node_modules/moment/locale/ml.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mn.js\": [\n\t\t\"./node_modules/moment/locale/mn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mr.js\": [\n\t\t\"./node_modules/moment/locale/mr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ms-my.js\": [\n\t\t\"./node_modules/moment/locale/ms-my.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ms.js\": [\n\t\t\"./node_modules/moment/locale/ms.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mt.js\": [\n\t\t\"./node_modules/moment/locale/mt.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./my.js\": [\n\t\t\"./node_modules/moment/locale/my.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nb.js\": [\n\t\t\"./node_modules/moment/locale/nb.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ne.js\": [\n\t\t\"./node_modules/moment/locale/ne.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nl-be.js\": [\n\t\t\"./node_modules/moment/locale/nl-be.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nl.js\": [\n\t\t\"./node_modules/moment/locale/nl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nn.js\": [\n\t\t\"./node_modules/moment/locale/nn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./oc-lnc.js\": [\n\t\t\"./node_modules/moment/locale/oc-lnc.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pa-in.js\": [\n\t\t\"./node_modules/moment/locale/pa-in.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pl.js\": [\n\t\t\"./node_modules/moment/locale/pl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pt-br.js\": [\n\t\t\"./node_modules/moment/locale/pt-br.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pt.js\": [\n\t\t\"./node_modules/moment/locale/pt.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ro.js\": [\n\t\t\"./node_modules/moment/locale/ro.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ru.js\": [\n\t\t\"./node_modules/moment/locale/ru.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sd.js\": [\n\t\t\"./node_modules/moment/locale/sd.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./se.js\": [\n\t\t\"./node_modules/moment/locale/se.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./si.js\": [\n\t\t\"./node_modules/moment/locale/si.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sk.js\": [\n\t\t\"./node_modules/moment/locale/sk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sl.js\": [\n\t\t\"./node_modules/moment/locale/sl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sq.js\": [\n\t\t\"./node_modules/moment/locale/sq.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sr-cyrl.js\": [\n\t\t\"./node_modules/moment/locale/sr-cyrl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sr.js\": [\n\t\t\"./node_modules/moment/locale/sr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ss.js\": [\n\t\t\"./node_modules/moment/locale/ss.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sv.js\": [\n\t\t\"./node_modules/moment/locale/sv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sw.js\": [\n\t\t\"./node_modules/moment/locale/sw.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ta.js\": [\n\t\t\"./node_modules/moment/locale/ta.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./te.js\": [\n\t\t\"./node_modules/moment/locale/te.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tet.js\": [\n\t\t\"./node_modules/moment/locale/tet.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tg.js\": [\n\t\t\"./node_modules/moment/locale/tg.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./th.js\": [\n\t\t\"./node_modules/moment/locale/th.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tk.js\": [\n\t\t\"./node_modules/moment/locale/tk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tl-ph.js\": [\n\t\t\"./node_modules/moment/locale/tl-ph.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tlh.js\": [\n\t\t\"./node_modules/moment/locale/tlh.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tr.js\": [\n\t\t\"./node_modules/moment/locale/tr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tzl.js\": [\n\t\t\"./node_modules/moment/locale/tzl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tzm-latn.js\": [\n\t\t\"./node_modules/moment/locale/tzm-latn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tzm.js\": [\n\t\t\"./node_modules/moment/locale/tzm.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ug-cn.js\": [\n\t\t\"./node_modules/moment/locale/ug-cn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./uk.js\": [\n\t\t\"./node_modules/moment/locale/uk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ur.js\": [\n\t\t\"./node_modules/moment/locale/ur.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./uz-latn.js\": [\n\t\t\"./node_modules/moment/locale/uz-latn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./uz.js\": [\n\t\t\"./node_modules/moment/locale/uz.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./vi.js\": [\n\t\t\"./node_modules/moment/locale/vi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./x-pseudo.js\": [\n\t\t\"./node_modules/moment/locale/x-pseudo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./yo.js\": [\n\t\t\"./node_modules/moment/locale/yo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-cn.js\": [\n\t\t\"./node_modules/moment/locale/zh-cn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-hk.js\": [\n\t\t\"./node_modules/moment/locale/zh-hk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-mo.js\": [\n\t\t\"./node_modules/moment/locale/zh-mo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-tw.js\": [\n\t\t\"./node_modules/moment/locale/zh-tw.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t]\n};\nfunction webpackAsyncContext(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\t\te.code = 'MODULE_NOT_FOUND';\n\t\t\tthrow e;\n\t\t});\n\t}\n\n\tvar ids = map[req], id = ids[0];\n\treturn Promise.all(ids.slice(1).map(__webpack_require__.e)).then(() => {\n\t\treturn __webpack_require__.t(id, 7 | 16);\n\t});\n}\nwebpackAsyncContext.keys = () => (Object.keys(map));\nwebpackAsyncContext.id = \"./node_modules/moment/locale lazy recursive ^\\\\.\\\\/.*\\\\.js$\";\nmodule.exports = webpackAsyncContext;"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"calendar-src_fullcalendar_eventSources_eventSourceFunction_js-src_utils_moment_js-data_image_svg_xml_3-b73258.js?v=b5a1f8246e3d20bdaf6b","mappings":";;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACtKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///calendar/src\\fullcalendar\\eventSources\\eventSourceFunction.js","webpack:///calendar/src\\utils\\moment.js","webpack:///calendar/node_modules\\moment\\locale|lazy|\\^\\.*\\.js$\\|groupOptions: {}|namespace object"],"sourcesContent":["/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke \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 .\n *\n */\nimport { translate as t } from '@nextcloud/l10n';\nimport { hexToRGB, isLight, generateTextColorForHex, getHexForColorName } from '../../utils/color.js';\nimport logger from '../../utils/logger.js';\nimport { getAllObjectsInTimeRange } from '../../utils/calendarObject.js';\n\n/**\n * convert an array of calendar-objects to events\n *\n * @param {CalendarObject[]} calendarObjects Array of calendar-objects to turn into fc events\n * @param {object} calendar The calendar object\n * @param {Date} start Start of time-range\n * @param {Date} end End of time-range\n * @param {Timezone} timezone Desired time-zone\n * @return {object}[]\n */\nexport function eventSourceFunction(calendarObjects, calendar, start, end, timezone) {\n const fcEvents = [];\n const authUser = OC.currentUser;\n for (const calendarObject of calendarObjects) {\n let allObjectsInTimeRange;\n try {\n allObjectsInTimeRange = getAllObjectsInTimeRange(calendarObject, start, end);\n } catch (error) {\n logger.error(error.message);\n continue;\n }\n for (const object of allObjectsInTimeRange) {\n const classNames = [];\n if (object.status === 'CANCELLED') {\n classNames.push('fc-event-nc-cancelled');\n } else if (object.status === 'TENTATIVE') {\n classNames.push('fc-event-nc-tentative');\n }\n if (object.hasComponent('VALARM')) {\n classNames.push('fc-event-nc-alarms');\n }\n\n // For now, we only display\n if (object.name === 'VTODO' && object.endDate === null) {\n continue;\n }\n let jsStart, jsEnd;\n if (object.name === 'VEVENT') {\n jsStart = object.startDate.getInTimezone(timezone).jsDate;\n jsEnd = object.endDate.getInTimezone(timezone).jsDate;\n } else if (object.name === 'VTODO') {\n // For tasks, we only want to display when it is due,\n // not for how long it has been in progress already\n jsStart = object.endDate.getInTimezone(timezone).jsDate;\n jsEnd = object.endDate.getInTimezone(timezone).jsDate;\n } else {\n // We do not want to display anything that's neither\n // an event nor a task\n continue;\n }\n\n // Technically, an event's end is not allowed to be equal to it's start,\n // because the event's end is exclusive. Most calendar applications\n // (including all big ones) allow creating such events anyway (we do too).\n // If the event's start is equal to it's end, fullcalendar is giving\n // the event a default length of one hour. We are preventing that by\n // adding one second to the end in that case.\n if (jsStart.getTime() === jsEnd.getTime()) {\n jsEnd.setSeconds(jsEnd.getSeconds() + 1);\n }\n if (object.name === 'VTODO') {\n classNames.push('fc-event-nc-task');\n if (object.percent === 100 || object.status === 'COMPLETED') {\n classNames.push('fc-event-nc-task-completed');\n }\n }\n let title;\n if (object.name === 'VEVENT') {\n if (object.title) {\n title = object.title.replace(/\\n/g, ' ');\n } else {\n title = t('calendar', 'Untitled event');\n }\n } else {\n if (object.title) {\n title = object.title.replace(/\\n/g, ' ');\n } else {\n title = t('calendar', 'Untitled task');\n }\n if (object.percent !== null) {\n title += \" (\".concat(object.percent, \"%)\");\n }\n }\n let isPrivateEvent = false;\n let objectProperties = object._properties.get('ISPRIVATE');\n if (objectProperties && objectProperties.length > 0) {\n isPrivateEvent = objectProperties[0]._value == \"1\" ? true : false;\n }\n\n //Get owen object's user\n let owenUrl = calendarObject.dav._parent.owner;\n let owenUser = owenUrl.replace('/remote.php/dav/principals/users/', '').split('/')[0];\n if (!owenUser) {\n //Get from url shared calendar\n owenUrl = calendarObject.dav._parent.url;\n owenUser = owenUrl.replace('/remote.php/dav/calendars/' + authUser + '/personal_shared_by_', '').split('/')[0];\n }\n const isOwenOfEvent = owenUser == authUser;\n if (isPrivateEvent && !isOwenOfEvent) {\n title = t('calendar', \"Absent (\".concat(owenUser, \")\"));\n }\n const fcEvent = {\n id: [calendarObject.id, object.id].join('###'),\n title,\n allDay: object.isAllDay(),\n start: jsStart,\n end: jsEnd,\n // start: formatLocal(jsStart, object.isAllDay()),\n // end: formatLocal(jsEnd, object.isAllDay()),\n classNames,\n extendedProps: {\n objectId: calendarObject.id,\n recurrenceId: object.getReferenceRecurrenceId() ? object.getReferenceRecurrenceId().unixTime : null,\n canModifyAllDay: object.canModifyAllDay(),\n calendarOrder: calendar.order,\n calendarName: calendar.displayName,\n calendarId: calendar.id,\n darkText: isLight(hexToRGB(calendar.color)),\n objectType: object.name,\n percent: object.percent || null,\n davUrl: calendarObject.dav.url,\n location: object.location,\n description: object.description,\n isPrivate: isPrivateEvent,\n calendarObjectOwen: owenUser,\n calendarObjectIsOwen: isOwenOfEvent\n }\n };\n if (object.color) {\n const customColor = getHexForColorName(object.color);\n if (customColor) {\n fcEvent.backgroundColor = customColor;\n fcEvent.borderColor = customColor;\n fcEvent.textColor = generateTextColorForHex(customColor);\n }\n }\n fcEvents.push(fcEvent);\n }\n }\n return fcEvents;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @copyright Copyright (c) 2018 John Molakvoæ\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getFirstDay, getLanguage, getLocale } from '@nextcloud/l10n';\nimport moment from '@nextcloud/moment';\n\n/**\r\n *\r\n * @return {Promise}\r\n */\nexport default async function loadMomentLocalization() {\n const locale = getLocale().replace('_', '-').toLowerCase();\n const language = getLanguage().replace('_', '-').toLowerCase();\n if (locale === language) {\n return getLocaleFor(locale);\n }\n const [realLocale, realLanguage] = await Promise.all([getLocaleFor(locale), getLocaleFor(language)]);\n if (realLocale === realLanguage) {\n return realLocale;\n }\n const name = \"nextcloud-calendar-fake-locale-\".concat(realLocale, \"-\").concat(realLanguage);\n moment.defineLocale(name, {\n parentLocale: realLanguage,\n longDateFormat: {\n LT: moment.localeData(realLocale).longDateFormat('LT'),\n LTS: moment.localeData(realLocale).longDateFormat('LTS'),\n L: moment.localeData(realLocale).longDateFormat('L'),\n LL: moment.localeData(realLocale).longDateFormat('LL'),\n LLL: moment.localeData(realLocale).longDateFormat('LLL'),\n LLLL: moment.localeData(realLocale).longDateFormat('LLLL'),\n l: moment.localeData(realLocale).longDateFormat('l'),\n ll: moment.localeData(realLocale).longDateFormat('ll'),\n lll: moment.localeData(realLocale).longDateFormat('lll'),\n llll: moment.localeData(realLocale).longDateFormat('llll')\n },\n week: {\n dow: getFirstDay(),\n doy: moment.localeData(realLocale).firstDayOfYear()\n }\n });\n return name;\n}\n\n/**\r\n * Dynamically loads the requested locale and returns the actually loaded locale\r\n *\r\n * @param {string} locale Name of locale to load\r\n * @return {Promise}\r\n */\nasync function getLocaleFor(locale) {\n // IMPORTANT: Keep each '/moment/local/...' string as is. Otherwise, webpack might not bundle\n // locale data because the contentRegExp fails to detect any files.\n try {\n // default load e.g. en-de\n await import(\"moment/locale/\".concat(locale, \".js\"));\n return locale;\n } catch (error) {\n const splitLocale = locale.split('-');\n try {\n // failure: fallback to first part of locale, which\n // should be language\n locale = splitLocale[0];\n await import(\"moment/locale/\".concat(locale, \".js\"));\n return locale;\n } catch (e) {\n // failure, fallback to english\n console.debug('Fallback to locale', 'en');\n // English is the default locale and doesn't need to imported.\n // It is already included in moment.js.\n }\n }\n return 'en';\n}","var map = {\n\t\"./af.js\": [\n\t\t\"./node_modules/moment/locale/af.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-dz.js\": [\n\t\t\"./node_modules/moment/locale/ar-dz.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-kw.js\": [\n\t\t\"./node_modules/moment/locale/ar-kw.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-ly.js\": [\n\t\t\"./node_modules/moment/locale/ar-ly.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-ma.js\": [\n\t\t\"./node_modules/moment/locale/ar-ma.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-ps.js\": [\n\t\t\"./node_modules/moment/locale/ar-ps.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-sa.js\": [\n\t\t\"./node_modules/moment/locale/ar-sa.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar-tn.js\": [\n\t\t\"./node_modules/moment/locale/ar-tn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ar.js\": [\n\t\t\"./node_modules/moment/locale/ar.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./az.js\": [\n\t\t\"./node_modules/moment/locale/az.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./be.js\": [\n\t\t\"./node_modules/moment/locale/be.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bg.js\": [\n\t\t\"./node_modules/moment/locale/bg.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bm.js\": [\n\t\t\"./node_modules/moment/locale/bm.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bn-bd.js\": [\n\t\t\"./node_modules/moment/locale/bn-bd.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bn.js\": [\n\t\t\"./node_modules/moment/locale/bn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bo.js\": [\n\t\t\"./node_modules/moment/locale/bo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./br.js\": [\n\t\t\"./node_modules/moment/locale/br.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./bs.js\": [\n\t\t\"./node_modules/moment/locale/bs.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ca.js\": [\n\t\t\"./node_modules/moment/locale/ca.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./cs.js\": [\n\t\t\"./node_modules/moment/locale/cs.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./cv.js\": [\n\t\t\"./node_modules/moment/locale/cv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./cy.js\": [\n\t\t\"./node_modules/moment/locale/cy.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./da.js\": [\n\t\t\"./node_modules/moment/locale/da.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./de-at.js\": [\n\t\t\"./node_modules/moment/locale/de-at.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./de-ch.js\": [\n\t\t\"./node_modules/moment/locale/de-ch.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./de.js\": [\n\t\t\"./node_modules/moment/locale/de.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./dv.js\": [\n\t\t\"./node_modules/moment/locale/dv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./el.js\": [\n\t\t\"./node_modules/moment/locale/el.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-au.js\": [\n\t\t\"./node_modules/moment/locale/en-au.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-ca.js\": [\n\t\t\"./node_modules/moment/locale/en-ca.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-gb.js\": [\n\t\t\"./node_modules/moment/locale/en-gb.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-ie.js\": [\n\t\t\"./node_modules/moment/locale/en-ie.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-il.js\": [\n\t\t\"./node_modules/moment/locale/en-il.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-in.js\": [\n\t\t\"./node_modules/moment/locale/en-in.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-nz.js\": [\n\t\t\"./node_modules/moment/locale/en-nz.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./en-sg.js\": [\n\t\t\"./node_modules/moment/locale/en-sg.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./eo.js\": [\n\t\t\"./node_modules/moment/locale/eo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es-do.js\": [\n\t\t\"./node_modules/moment/locale/es-do.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es-mx.js\": [\n\t\t\"./node_modules/moment/locale/es-mx.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es-us.js\": [\n\t\t\"./node_modules/moment/locale/es-us.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./es.js\": [\n\t\t\"./node_modules/moment/locale/es.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./et.js\": [\n\t\t\"./node_modules/moment/locale/et.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./eu.js\": [\n\t\t\"./node_modules/moment/locale/eu.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fa.js\": [\n\t\t\"./node_modules/moment/locale/fa.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fi.js\": [\n\t\t\"./node_modules/moment/locale/fi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fil.js\": [\n\t\t\"./node_modules/moment/locale/fil.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fo.js\": [\n\t\t\"./node_modules/moment/locale/fo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fr-ca.js\": [\n\t\t\"./node_modules/moment/locale/fr-ca.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fr-ch.js\": [\n\t\t\"./node_modules/moment/locale/fr-ch.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fr.js\": [\n\t\t\"./node_modules/moment/locale/fr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./fy.js\": [\n\t\t\"./node_modules/moment/locale/fy.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ga.js\": [\n\t\t\"./node_modules/moment/locale/ga.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gd.js\": [\n\t\t\"./node_modules/moment/locale/gd.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gl.js\": [\n\t\t\"./node_modules/moment/locale/gl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gom-deva.js\": [\n\t\t\"./node_modules/moment/locale/gom-deva.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gom-latn.js\": [\n\t\t\"./node_modules/moment/locale/gom-latn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./gu.js\": [\n\t\t\"./node_modules/moment/locale/gu.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./he.js\": [\n\t\t\"./node_modules/moment/locale/he.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hi.js\": [\n\t\t\"./node_modules/moment/locale/hi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hr.js\": [\n\t\t\"./node_modules/moment/locale/hr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hu.js\": [\n\t\t\"./node_modules/moment/locale/hu.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./hy-am.js\": [\n\t\t\"./node_modules/moment/locale/hy-am.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./id.js\": [\n\t\t\"./node_modules/moment/locale/id.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./is.js\": [\n\t\t\"./node_modules/moment/locale/is.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./it-ch.js\": [\n\t\t\"./node_modules/moment/locale/it-ch.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./it.js\": [\n\t\t\"./node_modules/moment/locale/it.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ja.js\": [\n\t\t\"./node_modules/moment/locale/ja.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./jv.js\": [\n\t\t\"./node_modules/moment/locale/jv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ka.js\": [\n\t\t\"./node_modules/moment/locale/ka.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./kk.js\": [\n\t\t\"./node_modules/moment/locale/kk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./km.js\": [\n\t\t\"./node_modules/moment/locale/km.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./kn.js\": [\n\t\t\"./node_modules/moment/locale/kn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ko.js\": [\n\t\t\"./node_modules/moment/locale/ko.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ku-kmr.js\": [\n\t\t\"./node_modules/moment/locale/ku-kmr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ku.js\": [\n\t\t\"./node_modules/moment/locale/ku.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ky.js\": [\n\t\t\"./node_modules/moment/locale/ky.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lb.js\": [\n\t\t\"./node_modules/moment/locale/lb.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lo.js\": [\n\t\t\"./node_modules/moment/locale/lo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lt.js\": [\n\t\t\"./node_modules/moment/locale/lt.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./lv.js\": [\n\t\t\"./node_modules/moment/locale/lv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./me.js\": [\n\t\t\"./node_modules/moment/locale/me.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mi.js\": [\n\t\t\"./node_modules/moment/locale/mi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mk.js\": [\n\t\t\"./node_modules/moment/locale/mk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ml.js\": [\n\t\t\"./node_modules/moment/locale/ml.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mn.js\": [\n\t\t\"./node_modules/moment/locale/mn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mr.js\": [\n\t\t\"./node_modules/moment/locale/mr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ms-my.js\": [\n\t\t\"./node_modules/moment/locale/ms-my.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ms.js\": [\n\t\t\"./node_modules/moment/locale/ms.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./mt.js\": [\n\t\t\"./node_modules/moment/locale/mt.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./my.js\": [\n\t\t\"./node_modules/moment/locale/my.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nb.js\": [\n\t\t\"./node_modules/moment/locale/nb.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ne.js\": [\n\t\t\"./node_modules/moment/locale/ne.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nl-be.js\": [\n\t\t\"./node_modules/moment/locale/nl-be.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nl.js\": [\n\t\t\"./node_modules/moment/locale/nl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./nn.js\": [\n\t\t\"./node_modules/moment/locale/nn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./oc-lnc.js\": [\n\t\t\"./node_modules/moment/locale/oc-lnc.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pa-in.js\": [\n\t\t\"./node_modules/moment/locale/pa-in.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pl.js\": [\n\t\t\"./node_modules/moment/locale/pl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pt-br.js\": [\n\t\t\"./node_modules/moment/locale/pt-br.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./pt.js\": [\n\t\t\"./node_modules/moment/locale/pt.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ro.js\": [\n\t\t\"./node_modules/moment/locale/ro.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ru.js\": [\n\t\t\"./node_modules/moment/locale/ru.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sd.js\": [\n\t\t\"./node_modules/moment/locale/sd.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./se.js\": [\n\t\t\"./node_modules/moment/locale/se.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./si.js\": [\n\t\t\"./node_modules/moment/locale/si.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sk.js\": [\n\t\t\"./node_modules/moment/locale/sk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sl.js\": [\n\t\t\"./node_modules/moment/locale/sl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sq.js\": [\n\t\t\"./node_modules/moment/locale/sq.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sr-cyrl.js\": [\n\t\t\"./node_modules/moment/locale/sr-cyrl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sr.js\": [\n\t\t\"./node_modules/moment/locale/sr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ss.js\": [\n\t\t\"./node_modules/moment/locale/ss.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sv.js\": [\n\t\t\"./node_modules/moment/locale/sv.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./sw.js\": [\n\t\t\"./node_modules/moment/locale/sw.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ta.js\": [\n\t\t\"./node_modules/moment/locale/ta.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./te.js\": [\n\t\t\"./node_modules/moment/locale/te.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tet.js\": [\n\t\t\"./node_modules/moment/locale/tet.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tg.js\": [\n\t\t\"./node_modules/moment/locale/tg.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./th.js\": [\n\t\t\"./node_modules/moment/locale/th.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tk.js\": [\n\t\t\"./node_modules/moment/locale/tk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tl-ph.js\": [\n\t\t\"./node_modules/moment/locale/tl-ph.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tlh.js\": [\n\t\t\"./node_modules/moment/locale/tlh.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tr.js\": [\n\t\t\"./node_modules/moment/locale/tr.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tzl.js\": [\n\t\t\"./node_modules/moment/locale/tzl.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tzm-latn.js\": [\n\t\t\"./node_modules/moment/locale/tzm-latn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./tzm.js\": [\n\t\t\"./node_modules/moment/locale/tzm.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ug-cn.js\": [\n\t\t\"./node_modules/moment/locale/ug-cn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./uk.js\": [\n\t\t\"./node_modules/moment/locale/uk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./ur.js\": [\n\t\t\"./node_modules/moment/locale/ur.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./uz-latn.js\": [\n\t\t\"./node_modules/moment/locale/uz-latn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./uz.js\": [\n\t\t\"./node_modules/moment/locale/uz.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./vi.js\": [\n\t\t\"./node_modules/moment/locale/vi.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./x-pseudo.js\": [\n\t\t\"./node_modules/moment/locale/x-pseudo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./yo.js\": [\n\t\t\"./node_modules/moment/locale/yo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-cn.js\": [\n\t\t\"./node_modules/moment/locale/zh-cn.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-hk.js\": [\n\t\t\"./node_modules/moment/locale/zh-hk.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-mo.js\": [\n\t\t\"./node_modules/moment/locale/zh-mo.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t],\n\t\"./zh-tw.js\": [\n\t\t\"./node_modules/moment/locale/zh-tw.js\",\n\t\t\"vendors-node_modules_moment_locale_af_js-node_modules_moment_locale_ar-dz_js-node_modules_mom-582c96\",\n\t\t\"node_modules_moment_locale_sync_recursive_\"\n\t]\n};\nfunction webpackAsyncContext(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\t\te.code = 'MODULE_NOT_FOUND';\n\t\t\tthrow e;\n\t\t});\n\t}\n\n\tvar ids = map[req], id = ids[0];\n\treturn Promise.all(ids.slice(1).map(__webpack_require__.e)).then(() => {\n\t\treturn __webpack_require__.t(id, 7 | 16);\n\t});\n}\nwebpackAsyncContext.keys = () => (Object.keys(map));\nwebpackAsyncContext.id = \"./node_modules/moment/locale lazy recursive ^\\\\.\\\\/.*\\\\.js$\";\nmodule.exports = webpackAsyncContext;"],"names":[],"sourceRoot":""} diff --git a/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js b/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js index 5f6a67d..a5569c7 100644 --- a/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js +++ b/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js @@ -316,6 +316,15 @@ const getRFCProperties = () => { placeholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Choisir les soins'), tagPlaceholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Choisir les soins'), options: [] + }, + comment: { + readableName: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Comment'), + icon: 'TextBoxOutline', + info: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Commentaires.'), + placeholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Commentaires'), + tagPlaceholder: (0,_nextcloud_l10n__WEBPACK_IMPORTED_MODULE_0__.translate)('calendar', 'Commentaires'), + options: [], + defaultNumberOfRows: 4 } }; }; @@ -1817,4 +1826,4 @@ function GenColors(steps) { /***/ }) }]); -//# sourceMappingURL=calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map?v=94fac30d128df46a89a6 \ No newline at end of file +//# sourceMappingURL=calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map?v=d2880e4c429713e99f7b \ No newline at end of file diff --git a/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map b/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map index 870cdfa..5589fa9 100644 --- a/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map +++ b/calendar/js/calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js.map @@ -1 +1 @@ -{"version":3,"file":"calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js?v=94fac30d128df46a89a6","mappings":";;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;AClQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC1HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///calendar/src\\defaults\\defaultCategories.js","webpack:///calendar/src\\models\\consts.js","webpack:///calendar/src\\models\\rfcProps.js","webpack:///calendar/src\\services\\caldavService.js","webpack:///calendar/src\\services\\talkService.js","webpack:///calendar/src\\services\\timezoneDataProviderService.js","webpack:///calendar/src\\services\\timezoneDetectionService.js","webpack:///calendar/src\\utils\\attendee.js","webpack:///calendar/src\\utils\\calendarObject.js","webpack:///calendar/src\\utils\\closestColor.js","webpack:///calendar/src\\utils\\color.js","webpack:///calendar/src\\utils\\date.js","webpack:///calendar/src\\utils\\logger.js","webpack:///calendar/src\\utils\\uidToColor.js"],"sourcesContent":["/**\r\n * Calendar App\r\n *\r\n * @copyright 2019 Georg Ehrke \r\n *\r\n * @author Georg Ehrke\r\n *\r\n * @author Richard Steinmetz \r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE\r\n * License as published by the Free Software Foundation; either\r\n * version 3 of the License, or any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU AFFERO GENERAL PUBLIC LICENSE for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public\r\n * License along with this library. If not, see .\r\n *\r\n */\nimport { translate as t } from '@nextcloud/l10n';\n\n/**\r\n *\r\n */\nexport function getDefaultCategories() {\n // This list was taken from https://tools.ietf.org/html/rfc5545#section-5\n const values = [t('calendar', 'Anniversary'), t('calendar', 'Appointment'), t('calendar', 'Business'), t('calendar', 'Education'), t('calendar', 'Holiday'), t('calendar', 'Meeting'), t('calendar', 'Miscellaneous'), t('calendar', 'Non-working hours'), t('calendar', 'Not in office'), t('calendar', 'Personal'), t('calendar', 'Phone call'), t('calendar', 'Sick day'), t('calendar', 'Special occasion'), t('calendar', 'Travel'), t('calendar', 'Vacation')];\n return values.map(value => ({\n value,\n label: value\n }));\n}\nexport default getDefaultCategories;","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nconst COMPONENT_NAME_EVENT = 'VEVENT';\nconst COMPONENT_NAME_JOURNAL = 'VJOURNAL';\nconst COMPONENT_NAME_VTODO = 'VTODO';\nconst ITIP_MESSAGE_ADD = 'ADD';\nconst ITIP_MESSAGE_CANCEL = 'CANCEL';\nconst ITIP_MESSAGE_COUNTER = 'COUNTER';\nconst ITIP_MESSAGE_DECLINECOUNTER = 'DECLINECOUNTER';\nconst ITIP_MESSAGE_PUBLISH = 'PUBLISH';\nconst ITIP_MESSAGE_REFRESH = 'REFRESH';\nconst ITIP_MESSAGE_REPLY = 'REPLY';\nconst ITIP_MESSAGE_REQUEST = 'REQUEST';\nconst PRINCIPAL_PREFIX_USER = 'principal:principals/users/';\nconst PRINCIPAL_PREFIX_GROUP = 'principal:principals/groups/';\nconst PRINCIPAL_PREFIX_CIRCLE = 'principal:principals/circles/';\nconst PRINCIPAL_PREFIX_CALENDAR_RESOURCE = 'principal:principals/calendar-resources/';\nconst PRINCIPAL_PREFIX_CALENDAR_ROOM = 'principal:principals/calendar-rooms/';\nconst CALDAV_BIRTHDAY_CALENDAR = 'contact_birthdays';\nconst IMPORT_STAGE_DEFAULT = 'default';\nconst IMPORT_STAGE_IMPORTING = 'importing';\nconst IMPORT_STAGE_AWAITING_USER_SELECT = 'awaitingUserSelect';\nconst IMPORT_STAGE_PROCESSING = 'processing';\nexport { COMPONENT_NAME_EVENT, COMPONENT_NAME_JOURNAL, COMPONENT_NAME_VTODO, ITIP_MESSAGE_ADD, ITIP_MESSAGE_CANCEL, ITIP_MESSAGE_COUNTER, ITIP_MESSAGE_DECLINECOUNTER, ITIP_MESSAGE_PUBLISH, ITIP_MESSAGE_REFRESH, ITIP_MESSAGE_REPLY, ITIP_MESSAGE_REQUEST, PRINCIPAL_PREFIX_USER, PRINCIPAL_PREFIX_GROUP, PRINCIPAL_PREFIX_CIRCLE, PRINCIPAL_PREFIX_CALENDAR_RESOURCE, PRINCIPAL_PREFIX_CALENDAR_ROOM, CALDAV_BIRTHDAY_CALENDAR, IMPORT_STAGE_DEFAULT, IMPORT_STAGE_IMPORTING, IMPORT_STAGE_AWAITING_USER_SELECT, IMPORT_STAGE_PROCESSING };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { translate as t } from '@nextcloud/l10n';\nimport { getDefaultCategories } from '../defaults/defaultCategories.js';\n\n/**\r\n * Gets all supported RFC properties\r\n *\r\n * @return {{color: {readableName: *, icon: string, multiple: boolean, info: *}, timeTransparency: {readableName: *, defaultValue: string, icon: string, multiple: boolean, options: *[], info: *}, description: {readableName: *, icon: string, placeholder: *, defaultNumberOfRows: number}, location: {readableName: *, icon: string, placeholder: *}, categories: {readableName: *, icon: string, multiple: boolean, options: *, tagPlaceholder: *, placeholder: *, info: *}, accessClass: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, status: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, locations: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, articles: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}}}\r\n */\nconst getRFCProperties = () => {\n return {\n /**\r\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.3\r\n */\n accessClass: {\n readableName: t('calendar', 'When shared show'),\n icon: 'Eye',\n options: [{\n value: 'PUBLIC',\n label: t('calendar', 'When shared show full event')\n }, {\n value: 'CONFIDENTIAL',\n label: t('calendar', 'When shared show only busy')\n }, {\n value: 'PRIVATE',\n label: t('calendar', 'When shared hide this event')\n }],\n multiple: false,\n info: t('calendar', 'The visibility of this event in shared calendars.'),\n defaultValue: 'PUBLIC'\n },\n /**\r\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.7\r\n */\n location: {\n readableName: t('calendar', 'Location'),\n placeholder: t('calendar', 'Choisir le lieu'),\n icon: 'MapMarker'\n },\n /**\r\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.5\r\n */\n description: {\n readableName: t('calendar', 'Description'),\n placeholder: t('calendar', 'Choisir les soins'),\n icon: 'TextBoxOutline',\n defaultNumberOfRows: 2\n },\n /**\r\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.11\r\n */\n status: {\n readableName: t('calendar', 'Status'),\n icon: 'Check',\n options: [{\n value: 'CONFIRMED',\n label: t('calendar', 'Confirmed')\n }, {\n value: 'TENTATIVE',\n label: t('calendar', 'Tentative')\n }, {\n value: 'CANCELLED',\n label: t('calendar', 'Canceled')\n }],\n multiple: false,\n info: t('calendar', 'Confirmation about the overall status of the event.'),\n defaultValue: 'CONFIRMED'\n },\n /**\r\n * https://tools.ietf.org/html/rfc5545#section-3.8.2.7\r\n */\n timeTransparency: {\n readableName: t('calendar', 'Show as'),\n icon: 'Briefcase',\n multiple: false,\n info: t('calendar', 'Take this event into account when calculating free-busy information.'),\n options: [{\n value: 'TRANSPARENT',\n label: t('calendar', 'Free')\n }, {\n value: 'OPAQUE',\n label: t('calendar', 'Busy')\n }],\n defaultValue: 'TRANSPARENT'\n },\n /**\r\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.2\r\n */\n categories: {\n readableName: t('calendar', 'Categories'),\n icon: 'Tag',\n multiple: true,\n info: t('calendar', 'Categories help you to structure and organize your events.'),\n placeholder: t('calendar', 'Search or add categories'),\n tagPlaceholder: t('calendar', 'Add this as a new category'),\n options: getDefaultCategories()\n },\n /**\r\n * https://tools.ietf.org/html/rfc7986#section-5.9\r\n */\n color: {\n readableName: t('calendar', 'Custom color'),\n icon: 'EyedropperVariant',\n multiple: false,\n info: t('calendar', 'Special color of this event. Overrides the calendar-color.')\n },\n locations: {\n readableName: t('calendar', 'Locations'),\n icon: 'Tag',\n searchable: true,\n multiple: false,\n info: t('calendar', 'Choisir le lieu du soin.'),\n placeholder: t('calendar', 'Choisir un lieu'),\n tagPlaceholder: t('calendar', 'Choisir un lieu'),\n options: []\n },\n clients: {\n readableName: t('calendar', 'Clients'),\n icon: 'Human',\n searchable: true,\n multiple: false,\n info: t('calendar', 'Choisir le donneur d\\'ordre.'),\n placeholder: t('calendar', 'Choisir un client'),\n tagPlaceholder: t('calendar', 'Choisir un client'),\n options: []\n },\n client: {\n readableName: t('calendar', 'Choisir un client'),\n placeholder: t('calendar', 'Choisir un client'),\n icon: 'Human'\n },\n embalmers: {\n readableName: t('calendar', 'Embalmers'),\n icon: 'Human',\n searchable: true,\n multiple: false,\n info: t('calendar', 'Thanatopracteur from Gestion'),\n placeholder: t('calendar', 'Choose thanatopracteur'),\n tagPlaceholder: t('calendar', 'Choose thanatopracteur'),\n options: []\n },\n embalmer: {\n readableName: t('calendar', 'Embalmer'),\n placeholder: t('calendar', 'Add a thanatopracteur'),\n icon: 'Human'\n },\n articles: {\n readableName: t('calendar', 'Articles'),\n icon: 'TextBoxOutline',\n searchable: true,\n multiple: true,\n info: t('calendar', 'Choisir les soins à appliquer.'),\n placeholder: t('calendar', 'Choisir les soins'),\n tagPlaceholder: t('calendar', 'Choisir les soins'),\n options: []\n }\n };\n};\nexport { getRFCProperties };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport DavClient from '@nextcloud/cdav-library';\nimport { generateRemoteUrl } from '@nextcloud/router';\nimport { getRequestToken } from '@nextcloud/auth';\nimport { CALDAV_BIRTHDAY_CALENDAR } from '../models/consts.js';\nconst clients = {};\nconst getClientKey = headers => JSON.stringify(headers);\nconst getClient = function () {\n let headers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const clientKey = getClientKey(headers);\n if (clients[clientKey]) {\n return clients[clientKey];\n }\n clients[clientKey] = new DavClient({\n rootUrl: generateRemoteUrl('dav')\n }, () => {\n const mergedHeaders = {\n 'X-Requested-With': 'XMLHttpRequest',\n requesttoken: getRequestToken(),\n 'X-NC-CalDAV-Webcal-Caching': 'On',\n ...headers\n };\n const xhr = new XMLHttpRequest();\n const oldOpen = xhr.open;\n\n // override open() method to add headers\n xhr.open = function () {\n const result = oldOpen.apply(this, arguments);\n for (const name in mergedHeaders) {\n xhr.setRequestHeader(name, mergedHeaders[name]);\n }\n return result;\n };\n OC.registerXHRForErrorProcessing(xhr); // eslint-disable-line no-undef\n return xhr;\n });\n return clients[clientKey];\n};\n\n/**\r\n * Initializes the client for use in the user-view\r\n */\nconst initializeClientForUserView = async () => {\n await getClient().connect({\n enableCalDAV: true\n });\n};\n\n/**\r\n * Initializes the client for use in the public/embed-view\r\n */\nconst initializeClientForPublicView = async () => {\n await getClient()._createPublicCalendarHome();\n};\n\n/**\r\n * Fetch all calendars from the server\r\n *\r\n * @param {object} headers\r\n * @return {Promise}\r\n */\nconst getCalendarHome = headers => getClient(headers).calendarHomes[0];\n\n/**\r\n * Fetch all collections in the calendar home from the server\r\n *\r\n * @return {Promise}\r\n */\nconst findAll = () => {\n return getCalendarHome().findAllCalDAVCollectionsGrouped();\n};\n\n/**\r\n * Fetch all subscriptions in the calendar home from the server\r\n */\nexport const findAllSubscriptions = async () => {\n const headers = {\n 'X-NC-CalDAV-Webcal-Caching': 'Off'\n };\n\n // Ensure the client is initialized once\n await getClient(headers).connect({\n enableCalDAV: true\n });\n return getCalendarHome(headers).findAllSubscriptions();\n};\n\n/**\r\n * Fetch all deleted calendars from the server\r\n *\r\n * @return {Promise}\r\n */\nconst findAllDeletedCalendars = () => {\n return getCalendarHome().findAllDeletedCalendars();\n};\n\n/**\r\n * Fetch public calendars by their token\r\n *\r\n * @param {string[]} tokens List of tokens\r\n * @return {Promise}\r\n */\nconst findPublicCalendarsByTokens = async tokens => {\n const findPromises = [];\n for (const token of tokens) {\n const promise = getClient().publicCalendarHome.find(token).catch(() => null); // Catch outdated tokens\n\n findPromises.push(promise);\n }\n const calendars = await Promise.all(findPromises);\n return calendars.filter(calendar => calendar !== null);\n};\n\n/**\r\n * Fetches all scheduling inboxes\r\n *\r\n * Nitpick detail: Technically, we shouldn't be querying all scheduling inboxes\r\n * in the calendar-home and just take the first one, but rather query the\r\n * \"CALDAV:schedule-inbox-URL\" property on the principal URL and take that one.\r\n * However, it doesn't make any difference for the Nextcloud CalDAV server\r\n * and saves us extraneous requests here.\r\n *\r\n * https://tools.ietf.org/html/rfc6638#section-2.2.1\r\n *\r\n * @return {Promise}\r\n */\nconst findSchedulingInbox = async () => {\n const inboxes = await getCalendarHome().findAllScheduleInboxes();\n return inboxes[0];\n};\n\n/**\r\n * Fetches all scheduling outboxes\r\n *\r\n * Nitpick detail: Technically, we shouldn't be querying all scheduling outboxes\r\n * in the calendar-home and just take the first one, but rather query the\r\n * \"CALDAV:schedule-outbox-URL\" property on the principal URL and take that one.\r\n * However, it doesn't make any difference for the Nextcloud CalDAV server\r\n * and saves us extraneous requests here.\r\n *\r\n * https://tools.ietf.org/html/rfc6638#section-2.1.1\r\n *\r\n * @return {Promise}\r\n */\nconst findSchedulingOutbox = async () => {\n const outboxes = await getCalendarHome().findAllScheduleOutboxes();\n return outboxes[0];\n};\n\n/**\r\n * Creates a calendar\r\n *\r\n * @param {string} displayName Visible name\r\n * @param {string} color Color\r\n * @param {string[]} components Supported component set\r\n * @param {number} order Order of calendar in list\r\n * @param {string} timezoneIcs ICS representation of timezone\r\n * @return {Promise}\r\n */\nconst createCalendar = async (displayName, color, components, order, timezoneIcs) => {\n return getCalendarHome().createCalendarCollection(displayName, color, components, order, timezoneIcs);\n};\n\n/**\r\n * Creates a subscription\r\n *\r\n * This function does not return a subscription, but a cached calendar\r\n *\r\n * @param {string} displayName Visible name\r\n * @param {string} color Color\r\n * @param {string} source Link to WebCAL Source\r\n * @param {number} order Order of calendar in list\r\n * @return {Promise}\r\n */\nconst createSubscription = async (displayName, color, source, order) => {\n return getCalendarHome().createSubscribedCollection(displayName, color, source, order);\n};\n\n/**\r\n * Enables the birthday calendar\r\n *\r\n * @return {Promise}\r\n */\nconst enableBirthdayCalendar = async () => {\n await getCalendarHome().enableBirthdayCalendar();\n return getBirthdayCalendar();\n};\n\n/**\r\n * Gets the birthday calendar\r\n *\r\n * @return {Promise}\r\n */\nconst getBirthdayCalendar = async () => {\n return getCalendarHome().find(CALDAV_BIRTHDAY_CALENDAR);\n};\n\n/**\r\n * Returns the Current User Principal\r\n *\r\n * @return {Principal}\r\n */\nconst getCurrentUserPrincipal = () => {\n return getClient().currentUserPrincipal;\n};\n\n/**\r\n * Finds calendar principals by displayname\r\n *\r\n * @param {string} term The search-term\r\n * @return {Promise}\r\n */\nconst principalPropertySearchByDisplaynameOrEmail = async term => {\n return getClient().principalPropertySearchByDisplaynameOrEmail(term);\n};\n\n/**\r\n * Performs a principal property search based on multiple advanced filters\r\n *\r\n * @param {object} query The destructuring query object\r\n * @param {string=} query.displayName The display name to search for\r\n * @param {number=} query.capacity The minimum required seating capacity\r\n * @param {string[]=} query.features The features to filter by\r\n * @param {string=} query.roomType The room type to filter by\r\n * @return {Promise}\r\n */\nconst advancedPrincipalPropertySearch = async query => {\n return getClient().advancedPrincipalPropertySearch(query);\n};\n\n/**\r\n * Finds one principal by it's URL\r\n *\r\n * @param {string} url The principal-url\r\n * @return {Promise}\r\n */\nconst findPrincipalByUrl = async url => {\n return getClient().findPrincipal(url);\n};\nexport { initializeClientForUserView, initializeClientForPublicView, findAll, findAllDeletedCalendars, findPublicCalendarsByTokens, findSchedulingInbox, findSchedulingOutbox, createCalendar, createSubscription, enableBirthdayCalendar, getBirthdayCalendar, getCurrentUserPrincipal, principalPropertySearchByDisplaynameOrEmail, advancedPrincipalPropertySearch, findPrincipalByUrl };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Team Popcorn \r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport HTTPClient from '@nextcloud/axios';\nimport { translate as t } from '@nextcloud/l10n';\nimport { generateUrl, generateOcsUrl } from '@nextcloud/router';\nimport { loadState } from '@nextcloud/initial-state';\nimport { getCurrentUser } from '@nextcloud/auth';\nimport logger from '../utils/logger.js';\nimport { removeMailtoPrefix } from '../utils/attendee.js';\n\n/**\r\n * Creates a new public talk room\r\n *\r\n * @param {?string} eventTitle Title of the event\r\n * @param {?string} eventDescription Description of the event\r\n * @param {?string[]} attendees Attendees of the event\r\n *\r\n * @return {Promise}\r\n */\nexport async function createTalkRoom() {\n let eventTitle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let eventDescription = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n let attendees = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n const apiVersion = loadState('calendar', 'talk_api_version');\n try {\n const response = await HTTPClient.post(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room', {\n roomType: 3,\n roomName: eventTitle || t('calendar', 'Chat room for event')\n });\n const conversation = response.data.ocs.data;\n const token = conversation.token;\n if (eventDescription) {\n await HTTPClient.put(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/description', {\n description: eventDescription\n });\n }\n return generateURLForToken(token);\n } catch (error) {\n console.debug(error);\n throw error;\n }\n}\n\n/**\r\n *\r\n * @param eventComponent\r\n */\nexport async function updateTalkParticipants(eventComponent) {\n var _eventComponent$getCo, _eventComponent$getCo2;\n const apiVersion = loadState('calendar', 'talk_api_version');\n const url = (_eventComponent$getCo = (_eventComponent$getCo2 = eventComponent.getConferenceList()[0]) === null || _eventComponent$getCo2 === void 0 ? void 0 : _eventComponent$getCo2.uri) !== null && _eventComponent$getCo !== void 0 ? _eventComponent$getCo : eventComponent.location;\n if (!url || !url.startsWith(window.location.protocol + '//' + window.location.host)) {\n logger.debug('Event\\'s conference/location is from another host', url);\n return;\n }\n const token = extractCallTokenFromUrl(url);\n if (!token) {\n logger.debug('URL ' + url + ' contains no call token');\n return;\n }\n try {\n const {\n data: {\n ocs: {\n data: room\n }\n }\n } = await HTTPClient.get(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token);\n const participantsResponse = await HTTPClient.get(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/participants');\n // Ignore if the actor isn't owner of the conversation\n if (!participantsResponse.data.ocs.data.some(participant => participant.actorId === getCurrentUser().uid && participant.participantType <= 2)) {\n logger.debug('Current user is not a moderator or owner', {\n currentUser: getCurrentUser().uid,\n conversation: participantsResponse.data.ocs.data\n });\n return;\n }\n console.info('room', room);\n for (const attendee of eventComponent.getAttendeeIterator()) {\n logger.debug('Processing attendee', {\n attendee\n });\n if (['GROUP', 'RESOURCE', 'ROOM'].includes(attendee.userType)) {\n continue;\n }\n const participantId = removeMailtoPrefix(attendee.email);\n try {\n var _searchResult$data$oc;\n // Map attendee email to Nextcloud user uid\n const searchResult = await HTTPClient.get(generateOcsUrl('core/autocomplete/', 2) + 'get?search=' + encodeURIComponent(participantId) + '&itemType=&itemId=%20&shareTypes[]=0&limit=2');\n // Only map if there is exactly one result\n if (searchResult.data.ocs.data.length === 1 && searchResult.data.ocs.data[0].id !== getCurrentUser().uid) {\n await HTTPClient.post(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/participants', {\n newParticipant: searchResult.data.ocs.data[0].id,\n source: 'users'\n });\n } else if (((_searchResult$data$oc = searchResult.data.ocs.data[0]) === null || _searchResult$data$oc === void 0 ? void 0 : _searchResult$data$oc.id) === getCurrentUser().uid) {\n logger.debug('Skipping organizer ' + searchResult.data.ocs.data[0].id);\n } else if (room.type === 3) {\n await HTTPClient.post(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/participants', {\n newParticipant: participantId,\n source: 'emails'\n });\n } else {\n logger.debug('Attendee ' + participantId + ' ignored as Talk participant');\n }\n } catch (error) {\n logger.info('Could not add attendee ' + participantId + ' as Talk participant', {\n error\n });\n }\n }\n } catch (error) {\n logger.warn('Could not update Talk room attendees', {\n error\n });\n }\n}\n\n/**\r\n * Checks whether the value contains a talk link\r\n *\r\n * @param {?string} text Haystack\r\n * @return {boolean}\r\n */\nexport function doesContainTalkLink(text) {\n if (!text) {\n return false;\n }\n\n // TODO: there is most definitely a more reliable way,\n // but this works for now\n const fakeUrl = generateURLForToken();\n return text.includes(fakeUrl);\n}\n\n/**\r\n * Generates an absolute URL to the talk room based on the token\r\n *\r\n * @param {string} token The token to the call room\r\n * @return {string}\r\n */\nfunction generateURLForToken() {\n let token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + token);\n}\n\n/**\r\n * Extract a spreed call token from the given URL\r\n *\r\n * @param {string} callUrl URL of the spreed call\r\n * @return {string|undefined} Matched token or undefined if URL is invalid\r\n */\nexport function extractCallTokenFromUrl(callUrl) {\n var _callUrl$match$, _callUrl$match;\n return (_callUrl$match$ = (_callUrl$match = callUrl.match(/\\/call\\/([a-z0-9]*)(\\/|#.*)?$/)) === null || _callUrl$match === void 0 ? void 0 : _callUrl$match[1]) !== null && _callUrl$match$ !== void 0 ? _callUrl$match$ : undefined;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getTimezoneManager } from '@nextcloud/calendar-js';\nconst timezoneManager = getTimezoneManager();\nlet initialized = false;\n\n/**\r\n * Gets the timezone-manager\r\n * initializes it if necessary\r\n *\r\n * @return {TimezoneManager}\r\n */\nexport default function () {\n if (!initialized) {\n timezoneManager.registerDefaultTimezones();\n initialized = true;\n }\n return timezoneManager;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport jstz from 'jstz';\n\n/**\r\n * Returns the current timezone of the user\r\n *\r\n * @return {string} Current timezone of user\r\n */\nconst detectTimezone = () => {\n const determinedTimezone = jstz.determine();\n if (!determinedTimezone) {\n return 'UTC';\n }\n const timezoneName = determinedTimezone.name();\n if (!timezoneName) {\n return 'UTC';\n }\n return timezoneName;\n};\nexport default detectTimezone;\nexport { detectTimezone };","/**\r\n * @copyright Copyright (c) 2021 Richard Steinmetz \r\n *\r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Remove the mailto prefix from a URI and return it\r\n *\r\n * @param {string} uri URI to remove the prefix from\r\n * @return {string} URI without a mailto prefix\r\n */\nexport function removeMailtoPrefix(uri) {\n if (typeof uri !== 'string') {\n return '';\n }\n if (uri.startsWith('mailto:')) {\n return uri.slice(7);\n }\n return uri;\n}\n\n/**\r\n * Add the mailto prefix to a URI if it doesn't have one yet and return it\r\n *\r\n * @param {string} uri URI to add the prefix to\r\n * @return {string} URI with a mailto prefix\r\n */\nexport function addMailtoPrefix(uri) {\n if (typeof uri !== 'string') {\n return 'mailto:';\n }\n if (uri.startsWith('mailto:')) {\n return uri;\n }\n return \"mailto:\".concat(uri);\n}\n\n/**\r\n * Get the display name of an organizer\r\n *\r\n * @param {?object} organizer Organizer object to extract a display name from\r\n * @return {string} Display name of given organizer\r\n */\nexport function organizerDisplayName(organizer) {\n if (!organizer) {\n return '';\n }\n if (organizer.commonName) {\n return organizer.commonName;\n }\n return removeMailtoPrefix(organizer.uri);\n}","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { DateTimeValue } from '@nextcloud/calendar-js';\n\n/**\r\n * Get all recurrence-items in given range\r\n *\r\n * @param {object} calendarObject Calendar-object model\r\n * @param {Date} start Begin of time-range\r\n * @param {Date} end End of time-range\r\n * @return {Array}\r\n */\nconst getAllObjectsInTimeRange = (calendarObject, start, end) => {\n const iterator = calendarObject.calendarComponent.getVObjectIterator();\n const firstVObject = iterator.next().value;\n if (!firstVObject) {\n return [];\n }\n const s = DateTimeValue.fromJSDate(start, true);\n const e = DateTimeValue.fromJSDate(end, true);\n return firstVObject.recurrenceManager.getAllOccurrencesBetween(s, e);\n};\n\n/**\r\n * Get recurrence-item at exactly a given recurrence-Id\r\n *\r\n * @param {object} calendarObject Calendar-object model\r\n * @param {Date} recurrenceId RecurrenceId to retrieve\r\n * @return {AbstractRecurringComponent|null}\r\n */\nconst getObjectAtRecurrenceId = (calendarObject, recurrenceId) => {\n const iterator = calendarObject.calendarComponent.getVObjectIterator();\n const firstVObject = iterator.next().value;\n if (!firstVObject) {\n return null;\n }\n const d = DateTimeValue.fromJSDate(recurrenceId, true);\n return firstVObject.recurrenceManager.getOccurrenceAtExactly(d);\n};\nexport { getAllObjectsInTimeRange, getObjectAtRecurrenceId };","/**\r\n * @copyright Copyright (c) 2023 Richard Steinmetz \r\n *\r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n// Code was taken from:\n// - https://github.com/juliuste/closest-css-color\n// - https://github.com/gausie/colour-proximity\n// - https://github.com/gausie/colour-proximity/pull/3\n\nimport cssColors from 'css-color-names';\nimport sortBy from 'lodash/sortBy.js';\nimport pick from 'lodash/pick.js';\nimport uniqBy from 'lodash/uniqBy.js';\nimport { get } from 'color-string';\nconst uniqColorKeys = uniqBy(Object.keys(cssColors), c => cssColors[c]);\nconst filteredColors = pick(cssColors, uniqColorKeys);\nconst colors = sortBy(Object.keys(filteredColors).map(name => ({\n name,\n hex: filteredColors[name]\n})), c => c.hex);\nconst defaults = {\n detailed: false\n};\n\n/**\r\n * Find the closest CSS color to a given hex color.\r\n *\r\n * Adapted from https://github.com/juliuste/closest-css-color\r\n *\r\n * Copyright (c) 2021, Julius Tens\r\n *\r\n * Permission to use, copy, modify, and/or distribute this software for any purpose with or without\r\n * fee is hereby granted, provided that the above copyright notice and this permission notice\r\n * appear in all copies.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS\r\n * SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE\r\n * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,\r\n * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\r\n * OF THIS SOFTWARE.\r\n *\r\n * @param {string} hex Hex color string\r\n * @param {object} opt Options\r\n * @param {boolean=} opt.detailed Return color object instead of just the name\r\n * @return {string|{name: string, hex: string}} Closest color name or object\r\n */\nexport default function closestColor(hex) {\n let opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n const options = {\n ...defaults,\n ...opt\n };\n const sortedColors = sortBy(colors, c => proximity(hex, c.hex));\n if (options.detailed) {\n return sortedColors[0];\n }\n return sortedColors[0].name;\n}\n\n/**\r\n * Calculate the proximity between two colors.\r\n *\r\n * Adapted from https://github.com/gausie/colour-proximity\r\n *\r\n * Copyright (c) 2013, Samuel Gaus\r\n *\r\n * @param {string} s1 Hex color string 1\r\n * @param {string} s2 Hex color string 2\r\n * @return {number}\r\n */\nfunction proximity(s1, s2) {\n const c1 = rgb2lab(get.rgb(s1));\n const c2 = rgb2lab(get.rgb(s2));\n return Math.sqrt(Math.pow(c1[0] - c2[0], 2) + Math.pow(c1[1] - c2[1], 2) + Math.pow(c1[2] - c2[2], 2));\n}\n\n/**\r\n * Adapted from https://github.com/gausie/colour-proximity\r\n *\r\n * Copyright (c) 2013, Samuel Gaus\r\n *\r\n * @param {number[]} input RGB array\r\n */\nfunction rgb2lab(input) {\n // This code is adapted from various functions at http://www.easyrgb.com/index.php?X=MATH\n\n const rgb = [0, 0, 0];\n const xyz = [0, 0, 0];\n const Lab = [0, 0, 0];\n for (let i = 0; i < input.length; i++) {\n let value = input[i] / 255;\n if (value > 0.04045) {\n value = Math.pow((value + 0.055) / 1.055, 2.4);\n } else {\n value = value / 12.92;\n }\n rgb[i] = value * 100;\n }\n xyz[0] = (rgb[0] * 0.4124 + rgb[1] * 0.3576 + rgb[2] * 0.1805) / 95.047; // ref_X = 95.047 Observer= 2°, Illuminant= D65\n xyz[1] = (rgb[0] * 0.2126 + rgb[1] * 0.7152 + rgb[2] * 0.0722) / 100.0; // ref_Y = 100.000\n xyz[2] = (rgb[0] * 0.0193 + rgb[1] * 0.1192 + rgb[2] * 0.9505) / 108.883; // ref_Z = 108.883\n\n for (let i = 0; i < 3; i++) {\n let value = xyz[i];\n if (value > 0.008856) {\n value = Math.pow(value, 1 / 3);\n } else {\n value = 7.787 * value + 16 / 116;\n }\n xyz[i] = value;\n }\n Lab[0] = parseFloat((116 * xyz[1] - 16).toFixed(3));\n Lab[1] = parseFloat((500 * (xyz[0] - xyz[1])).toFixed(3));\n Lab[2] = parseFloat((200 * (xyz[1] - xyz[2])).toFixed(3));\n return Lab;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport convert from 'color-convert';\nimport { uidToColor } from './uidToColor.js';\nimport css3Colors from 'css-color-names';\nimport closestColor from './closestColor.js';\n\n/**\r\n * Detect if a color is light or dark\r\n *\r\n * @param {object} data The destructuring object\r\n * @param {number} data.red Red part of the RGB\r\n * @param {number} data.green Green part of the RGB\r\n * @param {number} data.blue Blue part of the RGB\r\n * @return {boolean} true if color is light, false if color is dark\r\n */\nexport function isLight(_ref) {\n let {\n red,\n green,\n blue\n } = _ref;\n const brightness = (red * 299 + green * 587 + blue * 114) / 1000;\n return brightness > 130;\n}\n\n/**\r\n * Get a text-color that's readable on a given background color\r\n *\r\n * @param {string} hexColor The hex color to get a text color for\r\n * @return {string} the matching text color\r\n */\nexport function generateTextColorForHex(hexColor) {\n return generateTextColorForRGB(hexToRGB(hexColor));\n}\n\n/**\r\n * Get a text-color that's readable on a given background color\r\n *\r\n * @param {object} data The destructuring object\r\n * @param {number} data.red Red part of the RGB\r\n * @param {number} data.green Green part of the RGB\r\n * @param {number} data.blue Blue part of the RGB\r\n * @return {string}\r\n */\nexport function generateTextColorForRGB(_ref2) {\n let {\n red,\n green,\n blue\n } = _ref2;\n return isLight({\n red,\n green,\n blue\n }) ? '#000000' : '#FAFAFA';\n}\n\n/**\r\n * Convert hex string to RGB\r\n *\r\n * @param {string} hexColor The hex color to convert\r\n * @return {string} the RGB result\r\n */\nexport function hexToRGB(hexColor) {\n if (hexColor == null) {\n return {\n red: 0,\n green: 0,\n blue: 0\n };\n }\n const [red, green, blue] = convert.hex.rgb(hexColor.slice(1));\n return {\n red,\n green,\n blue\n };\n}\n\n/**\r\n * Generates a hex color based on RGB string\r\n *\r\n * @param {string} uid The string to generate a color from\r\n * @return {string} The hex color\r\n */\nexport function uidToHexColor(uid) {\n const color = uidToColor(uid);\n return '#' + convert.rgb.hex(color.r, color.g, color.b);\n}\n\n/**\r\n * Detects a color from a given string\r\n *\r\n * @param {string} color The color to get the real RGB hex string from\r\n * @return {string|boolean|*} String if color detected, boolean if not\r\n */\nexport function detectColor(color) {\n if (/^(#)((?:[A-Fa-f0-9]{3}){1,2})$/.test(color)) {\n // #ff00ff and #f0f\n return color;\n } else if (/^((?:[A-Fa-f0-9]{3}){1,2})$/.test(color)) {\n // ff00ff and f0f\n return '#' + color;\n } else if (/^(#)((?:[A-Fa-f0-9]{8}))$/.test(color)) {\n // #ff00ffff and #f0ff\n return color.slice(0, 7);\n } else if (/^((?:[A-Fa-f0-9]{8}))$/.test(color)) {\n // ff00ffff and f0ff\n return '#' + color.slice(0, 6);\n }\n return false;\n}\n\n/**\r\n * Gets the HEX code for a css3 color name\r\n *\r\n * @param {string} colorName The name of the css3 color\r\n * @return {string | null} string of HEX if valid color, null if not\r\n */\nexport function getHexForColorName(colorName) {\n return css3Colors[colorName] || null;\n}\n\n/**\r\n * Gets the closest css3 color name for a given HEX code\r\n *\r\n * @param {string} hex The HEX code to get a css3 color name for\r\n * @return {string}\r\n */\nexport function getClosestCSS3ColorNameForHex(hex) {\n return closestColor(hex);\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport logger from './logger.js';\n\n/**\r\n * returns a new Date object\r\n *\r\n * @return {Date}\r\n */\nexport function dateFactory() {\n return new Date();\n}\n\n/**\r\n * formats a Date object as YYYYMMDD\r\n *\r\n * @param {Date} date Date to format\r\n * @return {string}\r\n */\nexport function getYYYYMMDDFromDate(date) {\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().split('T')[0];\n}\n\n/**\r\n * get unix time from date object\r\n *\r\n * @param {Date} date Date to format\r\n * @return {number}\r\n */\nexport function getUnixTimestampFromDate(date) {\n return Math.floor(date.getTime() / 1000);\n}\n\n/**\r\n * Gets a Date-object based on the firstday param used in routes\r\n *\r\n * @param {string} firstDayParam The firstday param from the router\r\n * @return {Date}\r\n */\nexport function getDateFromFirstdayParam(firstDayParam) {\n if (firstDayParam === 'now') {\n return dateFactory();\n }\n const [year, month, date] = firstDayParam.split('-').map(str => parseInt(str, 10));\n if (Number.isNaN(year) || Number.isNaN(month) || Number.isNaN(date)) {\n logger.error('First day parameter contains non-numerical components, falling back to today');\n return dateFactory();\n }\n const dateObject = dateFactory();\n dateObject.setFullYear(year, month - 1, date);\n dateObject.setHours(0, 0, 0, 0);\n return dateObject;\n}\n\n/**\r\n * formats firstday param as YYYYMMDD\r\n *\r\n * @param {string} firstDayParam The firstday param from the router\r\n * @return {string}\r\n */\nexport function getYYYYMMDDFromFirstdayParam(firstDayParam) {\n if (firstDayParam === 'now') {\n return getYYYYMMDDFromDate(dateFactory());\n }\n return firstDayParam;\n}\n\n/**\r\n * Gets a date object based on the given DateTimeValue\r\n * Ignores given timezone-information\r\n *\r\n * @param {DateTimeValue} dateTimeValue Value to get date from\r\n * @return {Date}\r\n */\nexport function getDateFromDateTimeValue(dateTimeValue) {\n return new Date(dateTimeValue.year, dateTimeValue.month - 1, dateTimeValue.day, dateTimeValue.hour, dateTimeValue.minute, 0, 0);\n}\n\n/**\r\n * modifies a date\r\n *\r\n * @param {Date} date Date object to modify\r\n * @param {object} data The destructuring object\r\n * @param {number} data.day Number of days to add\r\n * @param {number} data.week Number of weeks to add\r\n * @param {number} data.month Number of months to add\r\n * @param data.year\r\n * @return {Date}\r\n */\nexport function modifyDate(date, _ref) {\n let {\n day = 0,\n week = 0,\n month = 0,\n year = 0\n } = _ref;\n date = new Date(date.getTime());\n date.setDate(date.getDate() + day);\n date.setDate(date.getDate() + week * 7);\n date.setMonth(date.getMonth() + month);\n date.setFullYear(date.getFullYear() + year);\n return date;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getLoggerBuilder } from '@nextcloud/logger';\nconst logger = getLoggerBuilder().setApp('calendar').detectUser().build();\n\n/**\r\n * Logs a debug message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logDebug = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.debug(message, context);\n};\n\n/**\r\n * Logs an error message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logError = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.error(message, context);\n};\n\n/**\r\n * Logs a fatal message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logFatal = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.fatal(message, context);\n};\n\n/**\r\n * Logs an info message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logInfo = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.info(message, context);\n};\n\n/**\r\n * Logs a warn message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logWarn = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.warn(message, context);\n};\nexport default logger;\nexport { logDebug, logError, logFatal, logInfo, logWarn };","/**\r\n * @copyright Copyright (c) 2018 John Molakvoæ \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport md5 from 'md5';\n\n/**\r\n * This is copied from nextcloud-vue for now, until it is exposed upstream.\r\n */\n\nexport const uidToColor = uid => {\n // Normalize hash\n let hash = uid.toLowerCase();\n\n // Already a md5 hash?\n if (hash.match(/^([0-9a-f]{4}-?){8}$/) === null) {\n hash = md5(hash);\n }\n hash = hash.replace(/[^0-9a-f]/g, '');\n const steps = 6;\n const finalPalette = GenColors(steps);\n\n /**\r\n * Convert a string to an integer evenly\r\n *\r\n * @param {string} hash The string to convert\r\n * @param {number} maximum The maximum value\r\n * @return {number} The integer calculated\r\n */\n function hashToInt(hash, maximum) {\n let finalInt = 0;\n const result = [];\n\n // Splitting evenly the string\n for (let i = 0; i < hash.length; i++) {\n // chars in md5 goes up to f, hex:16\n result.push(parseInt(hash.charAt(i), 16) % 16);\n }\n\n // Adds up all results\n for (const j in result) {\n finalInt += result[j];\n }\n\n // chars in md5 goes up to f, hex:16\n // make sure we're always using int in our operation\n return parseInt(parseInt(finalInt, 10) % maximum, 10);\n }\n return finalPalette[hashToInt(hash, steps * 3)];\n};\n\n/**\r\n * Color object\r\n *\r\n * @param {number} r The red value\r\n * @param {number} g The green value\r\n * @param {number} b The blue value\r\n */\nfunction Color(r, g, b) {\n this.r = r;\n this.g = g;\n this.b = b;\n}\n\n/**\r\n * Calculate the number of steps\r\n *\r\n * @param {number} steps The number of steps\r\n * @param {Array} ends The ends\r\n * @return {Array} Array containing the number of steps per color\r\n */\nfunction stepCalc(steps, ends) {\n const step = new Array(3);\n step[0] = (ends[1].r - ends[0].r) / steps;\n step[1] = (ends[1].g - ends[0].g) / steps;\n step[2] = (ends[1].b - ends[0].b) / steps;\n return step;\n}\n\n/**\r\n * Create a color palette from two colors\r\n *\r\n * @param {number} steps The number of steps the palette has\r\n * @param {string} color1 The first color\r\n * @param {string} color2 The second color\r\n * @return {Array} The created palette array\r\n */\nfunction mixPalette(steps, color1, color2) {\n const palette = [];\n palette.push(color1);\n const step = stepCalc(steps, [color1, color2]);\n for (let i = 1; i < steps; i++) {\n const r = parseInt(color1.r + step[0] * i, 10);\n const g = parseInt(color1.g + step[1] * i, 10);\n const b = parseInt(color1.b + step[2] * i, 10);\n palette.push(new Color(r, g, b));\n }\n return palette;\n}\n\n/**\r\n * Generate colors from the official nextcloud color\r\n * You can provide how many colors you want (multiplied by 3)\r\n * if step = 6\r\n * 3 colors * 6 will result in 18 generated colors\r\n *\r\n * @param {number} [steps] Number of steps to go from a color to another\r\n * @return {object[]}\r\n */\nfunction GenColors(steps) {\n if (!steps) {\n steps = 6;\n }\n const red = new Color(182, 70, 157);\n const yellow = new Color(221, 203, 85);\n const blue = new Color(0, 130, 201); // Nextcloud blue\n\n const palette1 = mixPalette(steps, red, yellow);\n const palette2 = mixPalette(steps, yellow, blue);\n const palette3 = mixPalette(steps, blue, red);\n return palette1.concat(palette2).concat(palette3);\n}\nexport default uidToColor;"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"calendar-src_models_rfcProps_js-src_services_caldavService_js-src_services_talkService_js-src_services-8a2790.js?v=d2880e4c429713e99f7b","mappings":";;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;AClQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACjLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACrCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC1HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///calendar/src\\defaults\\defaultCategories.js","webpack:///calendar/src\\models\\consts.js","webpack:///calendar/src\\models\\rfcProps.js","webpack:///calendar/src\\services\\caldavService.js","webpack:///calendar/src\\services\\talkService.js","webpack:///calendar/src\\services\\timezoneDataProviderService.js","webpack:///calendar/src\\services\\timezoneDetectionService.js","webpack:///calendar/src\\utils\\attendee.js","webpack:///calendar/src\\utils\\calendarObject.js","webpack:///calendar/src\\utils\\closestColor.js","webpack:///calendar/src\\utils\\color.js","webpack:///calendar/src\\utils\\date.js","webpack:///calendar/src\\utils\\logger.js","webpack:///calendar/src\\utils\\uidToColor.js"],"sourcesContent":["/**\r\n * Calendar App\r\n *\r\n * @copyright 2019 Georg Ehrke \r\n *\r\n * @author Georg Ehrke\r\n *\r\n * @author Richard Steinmetz \r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE\r\n * License as published by the Free Software Foundation; either\r\n * version 3 of the License, or any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU AFFERO GENERAL PUBLIC LICENSE for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public\r\n * License along with this library. If not, see .\r\n *\r\n */\nimport { translate as t } from '@nextcloud/l10n';\n\n/**\r\n *\r\n */\nexport function getDefaultCategories() {\n // This list was taken from https://tools.ietf.org/html/rfc5545#section-5\n const values = [t('calendar', 'Anniversary'), t('calendar', 'Appointment'), t('calendar', 'Business'), t('calendar', 'Education'), t('calendar', 'Holiday'), t('calendar', 'Meeting'), t('calendar', 'Miscellaneous'), t('calendar', 'Non-working hours'), t('calendar', 'Not in office'), t('calendar', 'Personal'), t('calendar', 'Phone call'), t('calendar', 'Sick day'), t('calendar', 'Special occasion'), t('calendar', 'Travel'), t('calendar', 'Vacation')];\n return values.map(value => ({\n value,\n label: value\n }));\n}\nexport default getDefaultCategories;","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nconst COMPONENT_NAME_EVENT = 'VEVENT';\nconst COMPONENT_NAME_JOURNAL = 'VJOURNAL';\nconst COMPONENT_NAME_VTODO = 'VTODO';\nconst ITIP_MESSAGE_ADD = 'ADD';\nconst ITIP_MESSAGE_CANCEL = 'CANCEL';\nconst ITIP_MESSAGE_COUNTER = 'COUNTER';\nconst ITIP_MESSAGE_DECLINECOUNTER = 'DECLINECOUNTER';\nconst ITIP_MESSAGE_PUBLISH = 'PUBLISH';\nconst ITIP_MESSAGE_REFRESH = 'REFRESH';\nconst ITIP_MESSAGE_REPLY = 'REPLY';\nconst ITIP_MESSAGE_REQUEST = 'REQUEST';\nconst PRINCIPAL_PREFIX_USER = 'principal:principals/users/';\nconst PRINCIPAL_PREFIX_GROUP = 'principal:principals/groups/';\nconst PRINCIPAL_PREFIX_CIRCLE = 'principal:principals/circles/';\nconst PRINCIPAL_PREFIX_CALENDAR_RESOURCE = 'principal:principals/calendar-resources/';\nconst PRINCIPAL_PREFIX_CALENDAR_ROOM = 'principal:principals/calendar-rooms/';\nconst CALDAV_BIRTHDAY_CALENDAR = 'contact_birthdays';\nconst IMPORT_STAGE_DEFAULT = 'default';\nconst IMPORT_STAGE_IMPORTING = 'importing';\nconst IMPORT_STAGE_AWAITING_USER_SELECT = 'awaitingUserSelect';\nconst IMPORT_STAGE_PROCESSING = 'processing';\nexport { COMPONENT_NAME_EVENT, COMPONENT_NAME_JOURNAL, COMPONENT_NAME_VTODO, ITIP_MESSAGE_ADD, ITIP_MESSAGE_CANCEL, ITIP_MESSAGE_COUNTER, ITIP_MESSAGE_DECLINECOUNTER, ITIP_MESSAGE_PUBLISH, ITIP_MESSAGE_REFRESH, ITIP_MESSAGE_REPLY, ITIP_MESSAGE_REQUEST, PRINCIPAL_PREFIX_USER, PRINCIPAL_PREFIX_GROUP, PRINCIPAL_PREFIX_CIRCLE, PRINCIPAL_PREFIX_CALENDAR_RESOURCE, PRINCIPAL_PREFIX_CALENDAR_ROOM, CALDAV_BIRTHDAY_CALENDAR, IMPORT_STAGE_DEFAULT, IMPORT_STAGE_IMPORTING, IMPORT_STAGE_AWAITING_USER_SELECT, IMPORT_STAGE_PROCESSING };","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke \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 .\n *\n */\nimport { translate as t } from '@nextcloud/l10n';\nimport { getDefaultCategories } from '../defaults/defaultCategories.js';\n\n/**\n * Gets all supported RFC properties\n *\n * @return {{color: {readableName: *, icon: string, multiple: boolean, info: *}, timeTransparency: {readableName: *, defaultValue: string, icon: string, multiple: boolean, options: *[], info: *}, description: {readableName: *, icon: string, placeholder: *, defaultNumberOfRows: number}, location: {readableName: *, icon: string, placeholder: *}, categories: {readableName: *, icon: string, multiple: boolean, options: *, tagPlaceholder: *, placeholder: *, info: *}, accessClass: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, status: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, locations: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}, articles: {readableName: *, defaultValue: string, icon: string, options: *[], multiple: boolean, info: *}}}\n */\nconst getRFCProperties = () => {\n return {\n /**\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.3\n */\n accessClass: {\n readableName: t('calendar', 'When shared show'),\n icon: 'Eye',\n options: [{\n value: 'PUBLIC',\n label: t('calendar', 'When shared show full event')\n }, {\n value: 'CONFIDENTIAL',\n label: t('calendar', 'When shared show only busy')\n }, {\n value: 'PRIVATE',\n label: t('calendar', 'When shared hide this event')\n }],\n multiple: false,\n info: t('calendar', 'The visibility of this event in shared calendars.'),\n defaultValue: 'PUBLIC'\n },\n /**\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.7\n */\n location: {\n readableName: t('calendar', 'Location'),\n placeholder: t('calendar', 'Choisir le lieu'),\n icon: 'MapMarker'\n },\n /**\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.5\n */\n description: {\n readableName: t('calendar', 'Description'),\n placeholder: t('calendar', 'Choisir les soins'),\n icon: 'TextBoxOutline',\n defaultNumberOfRows: 2\n },\n /**\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.11\n */\n status: {\n readableName: t('calendar', 'Status'),\n icon: 'Check',\n options: [{\n value: 'CONFIRMED',\n label: t('calendar', 'Confirmed')\n }, {\n value: 'TENTATIVE',\n label: t('calendar', 'Tentative')\n }, {\n value: 'CANCELLED',\n label: t('calendar', 'Canceled')\n }],\n multiple: false,\n info: t('calendar', 'Confirmation about the overall status of the event.'),\n defaultValue: 'CONFIRMED'\n },\n /**\n * https://tools.ietf.org/html/rfc5545#section-3.8.2.7\n */\n timeTransparency: {\n readableName: t('calendar', 'Show as'),\n icon: 'Briefcase',\n multiple: false,\n info: t('calendar', 'Take this event into account when calculating free-busy information.'),\n options: [{\n value: 'TRANSPARENT',\n label: t('calendar', 'Free')\n }, {\n value: 'OPAQUE',\n label: t('calendar', 'Busy')\n }],\n defaultValue: 'TRANSPARENT'\n },\n /**\n * https://tools.ietf.org/html/rfc5545#section-3.8.1.2\n */\n categories: {\n readableName: t('calendar', 'Categories'),\n icon: 'Tag',\n multiple: true,\n info: t('calendar', 'Categories help you to structure and organize your events.'),\n placeholder: t('calendar', 'Search or add categories'),\n tagPlaceholder: t('calendar', 'Add this as a new category'),\n options: getDefaultCategories()\n },\n /**\n * https://tools.ietf.org/html/rfc7986#section-5.9\n */\n color: {\n readableName: t('calendar', 'Custom color'),\n icon: 'EyedropperVariant',\n multiple: false,\n info: t('calendar', 'Special color of this event. Overrides the calendar-color.')\n },\n locations: {\n readableName: t('calendar', 'Locations'),\n icon: 'Tag',\n searchable: true,\n multiple: false,\n info: t('calendar', 'Choisir le lieu du soin.'),\n placeholder: t('calendar', 'Choisir un lieu'),\n tagPlaceholder: t('calendar', 'Choisir un lieu'),\n options: []\n },\n clients: {\n readableName: t('calendar', 'Clients'),\n icon: 'Human',\n searchable: true,\n multiple: false,\n info: t('calendar', 'Choisir le donneur d\\'ordre.'),\n placeholder: t('calendar', 'Choisir un client'),\n tagPlaceholder: t('calendar', 'Choisir un client'),\n options: []\n },\n client: {\n readableName: t('calendar', 'Choisir un client'),\n placeholder: t('calendar', 'Choisir un client'),\n icon: 'Human'\n },\n embalmers: {\n readableName: t('calendar', 'Embalmers'),\n icon: 'Human',\n searchable: true,\n multiple: false,\n info: t('calendar', 'Thanatopracteur from Gestion'),\n placeholder: t('calendar', 'Choose thanatopracteur'),\n tagPlaceholder: t('calendar', 'Choose thanatopracteur'),\n options: []\n },\n embalmer: {\n readableName: t('calendar', 'Embalmer'),\n placeholder: t('calendar', 'Add a thanatopracteur'),\n icon: 'Human'\n },\n articles: {\n readableName: t('calendar', 'Articles'),\n icon: 'TextBoxOutline',\n searchable: true,\n multiple: true,\n info: t('calendar', 'Choisir les soins à appliquer.'),\n placeholder: t('calendar', 'Choisir les soins'),\n tagPlaceholder: t('calendar', 'Choisir les soins'),\n options: []\n },\n comment: {\n readableName: t('calendar', 'Comment'),\n icon: 'TextBoxOutline',\n info: t('calendar', 'Commentaires.'),\n placeholder: t('calendar', 'Commentaires'),\n tagPlaceholder: t('calendar', 'Commentaires'),\n options: [],\n defaultNumberOfRows: 4\n }\n };\n};\nexport { getRFCProperties };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport DavClient from '@nextcloud/cdav-library';\nimport { generateRemoteUrl } from '@nextcloud/router';\nimport { getRequestToken } from '@nextcloud/auth';\nimport { CALDAV_BIRTHDAY_CALENDAR } from '../models/consts.js';\nconst clients = {};\nconst getClientKey = headers => JSON.stringify(headers);\nconst getClient = function () {\n let headers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n const clientKey = getClientKey(headers);\n if (clients[clientKey]) {\n return clients[clientKey];\n }\n clients[clientKey] = new DavClient({\n rootUrl: generateRemoteUrl('dav')\n }, () => {\n const mergedHeaders = {\n 'X-Requested-With': 'XMLHttpRequest',\n requesttoken: getRequestToken(),\n 'X-NC-CalDAV-Webcal-Caching': 'On',\n ...headers\n };\n const xhr = new XMLHttpRequest();\n const oldOpen = xhr.open;\n\n // override open() method to add headers\n xhr.open = function () {\n const result = oldOpen.apply(this, arguments);\n for (const name in mergedHeaders) {\n xhr.setRequestHeader(name, mergedHeaders[name]);\n }\n return result;\n };\n OC.registerXHRForErrorProcessing(xhr); // eslint-disable-line no-undef\n return xhr;\n });\n return clients[clientKey];\n};\n\n/**\r\n * Initializes the client for use in the user-view\r\n */\nconst initializeClientForUserView = async () => {\n await getClient().connect({\n enableCalDAV: true\n });\n};\n\n/**\r\n * Initializes the client for use in the public/embed-view\r\n */\nconst initializeClientForPublicView = async () => {\n await getClient()._createPublicCalendarHome();\n};\n\n/**\r\n * Fetch all calendars from the server\r\n *\r\n * @param {object} headers\r\n * @return {Promise}\r\n */\nconst getCalendarHome = headers => getClient(headers).calendarHomes[0];\n\n/**\r\n * Fetch all collections in the calendar home from the server\r\n *\r\n * @return {Promise}\r\n */\nconst findAll = () => {\n return getCalendarHome().findAllCalDAVCollectionsGrouped();\n};\n\n/**\r\n * Fetch all subscriptions in the calendar home from the server\r\n */\nexport const findAllSubscriptions = async () => {\n const headers = {\n 'X-NC-CalDAV-Webcal-Caching': 'Off'\n };\n\n // Ensure the client is initialized once\n await getClient(headers).connect({\n enableCalDAV: true\n });\n return getCalendarHome(headers).findAllSubscriptions();\n};\n\n/**\r\n * Fetch all deleted calendars from the server\r\n *\r\n * @return {Promise}\r\n */\nconst findAllDeletedCalendars = () => {\n return getCalendarHome().findAllDeletedCalendars();\n};\n\n/**\r\n * Fetch public calendars by their token\r\n *\r\n * @param {string[]} tokens List of tokens\r\n * @return {Promise}\r\n */\nconst findPublicCalendarsByTokens = async tokens => {\n const findPromises = [];\n for (const token of tokens) {\n const promise = getClient().publicCalendarHome.find(token).catch(() => null); // Catch outdated tokens\n\n findPromises.push(promise);\n }\n const calendars = await Promise.all(findPromises);\n return calendars.filter(calendar => calendar !== null);\n};\n\n/**\r\n * Fetches all scheduling inboxes\r\n *\r\n * Nitpick detail: Technically, we shouldn't be querying all scheduling inboxes\r\n * in the calendar-home and just take the first one, but rather query the\r\n * \"CALDAV:schedule-inbox-URL\" property on the principal URL and take that one.\r\n * However, it doesn't make any difference for the Nextcloud CalDAV server\r\n * and saves us extraneous requests here.\r\n *\r\n * https://tools.ietf.org/html/rfc6638#section-2.2.1\r\n *\r\n * @return {Promise}\r\n */\nconst findSchedulingInbox = async () => {\n const inboxes = await getCalendarHome().findAllScheduleInboxes();\n return inboxes[0];\n};\n\n/**\r\n * Fetches all scheduling outboxes\r\n *\r\n * Nitpick detail: Technically, we shouldn't be querying all scheduling outboxes\r\n * in the calendar-home and just take the first one, but rather query the\r\n * \"CALDAV:schedule-outbox-URL\" property on the principal URL and take that one.\r\n * However, it doesn't make any difference for the Nextcloud CalDAV server\r\n * and saves us extraneous requests here.\r\n *\r\n * https://tools.ietf.org/html/rfc6638#section-2.1.1\r\n *\r\n * @return {Promise}\r\n */\nconst findSchedulingOutbox = async () => {\n const outboxes = await getCalendarHome().findAllScheduleOutboxes();\n return outboxes[0];\n};\n\n/**\r\n * Creates a calendar\r\n *\r\n * @param {string} displayName Visible name\r\n * @param {string} color Color\r\n * @param {string[]} components Supported component set\r\n * @param {number} order Order of calendar in list\r\n * @param {string} timezoneIcs ICS representation of timezone\r\n * @return {Promise}\r\n */\nconst createCalendar = async (displayName, color, components, order, timezoneIcs) => {\n return getCalendarHome().createCalendarCollection(displayName, color, components, order, timezoneIcs);\n};\n\n/**\r\n * Creates a subscription\r\n *\r\n * This function does not return a subscription, but a cached calendar\r\n *\r\n * @param {string} displayName Visible name\r\n * @param {string} color Color\r\n * @param {string} source Link to WebCAL Source\r\n * @param {number} order Order of calendar in list\r\n * @return {Promise}\r\n */\nconst createSubscription = async (displayName, color, source, order) => {\n return getCalendarHome().createSubscribedCollection(displayName, color, source, order);\n};\n\n/**\r\n * Enables the birthday calendar\r\n *\r\n * @return {Promise}\r\n */\nconst enableBirthdayCalendar = async () => {\n await getCalendarHome().enableBirthdayCalendar();\n return getBirthdayCalendar();\n};\n\n/**\r\n * Gets the birthday calendar\r\n *\r\n * @return {Promise}\r\n */\nconst getBirthdayCalendar = async () => {\n return getCalendarHome().find(CALDAV_BIRTHDAY_CALENDAR);\n};\n\n/**\r\n * Returns the Current User Principal\r\n *\r\n * @return {Principal}\r\n */\nconst getCurrentUserPrincipal = () => {\n return getClient().currentUserPrincipal;\n};\n\n/**\r\n * Finds calendar principals by displayname\r\n *\r\n * @param {string} term The search-term\r\n * @return {Promise}\r\n */\nconst principalPropertySearchByDisplaynameOrEmail = async term => {\n return getClient().principalPropertySearchByDisplaynameOrEmail(term);\n};\n\n/**\r\n * Performs a principal property search based on multiple advanced filters\r\n *\r\n * @param {object} query The destructuring query object\r\n * @param {string=} query.displayName The display name to search for\r\n * @param {number=} query.capacity The minimum required seating capacity\r\n * @param {string[]=} query.features The features to filter by\r\n * @param {string=} query.roomType The room type to filter by\r\n * @return {Promise}\r\n */\nconst advancedPrincipalPropertySearch = async query => {\n return getClient().advancedPrincipalPropertySearch(query);\n};\n\n/**\r\n * Finds one principal by it's URL\r\n *\r\n * @param {string} url The principal-url\r\n * @return {Promise}\r\n */\nconst findPrincipalByUrl = async url => {\n return getClient().findPrincipal(url);\n};\nexport { initializeClientForUserView, initializeClientForPublicView, findAll, findAllDeletedCalendars, findPublicCalendarsByTokens, findSchedulingInbox, findSchedulingOutbox, createCalendar, createSubscription, enableBirthdayCalendar, getBirthdayCalendar, getCurrentUserPrincipal, principalPropertySearchByDisplaynameOrEmail, advancedPrincipalPropertySearch, findPrincipalByUrl };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Team Popcorn \r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport HTTPClient from '@nextcloud/axios';\nimport { translate as t } from '@nextcloud/l10n';\nimport { generateUrl, generateOcsUrl } from '@nextcloud/router';\nimport { loadState } from '@nextcloud/initial-state';\nimport { getCurrentUser } from '@nextcloud/auth';\nimport logger from '../utils/logger.js';\nimport { removeMailtoPrefix } from '../utils/attendee.js';\n\n/**\r\n * Creates a new public talk room\r\n *\r\n * @param {?string} eventTitle Title of the event\r\n * @param {?string} eventDescription Description of the event\r\n * @param {?string[]} attendees Attendees of the event\r\n *\r\n * @return {Promise}\r\n */\nexport async function createTalkRoom() {\n let eventTitle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n let eventDescription = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n let attendees = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n const apiVersion = loadState('calendar', 'talk_api_version');\n try {\n const response = await HTTPClient.post(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room', {\n roomType: 3,\n roomName: eventTitle || t('calendar', 'Chat room for event')\n });\n const conversation = response.data.ocs.data;\n const token = conversation.token;\n if (eventDescription) {\n await HTTPClient.put(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/description', {\n description: eventDescription\n });\n }\n return generateURLForToken(token);\n } catch (error) {\n console.debug(error);\n throw error;\n }\n}\n\n/**\r\n *\r\n * @param eventComponent\r\n */\nexport async function updateTalkParticipants(eventComponent) {\n var _eventComponent$getCo, _eventComponent$getCo2;\n const apiVersion = loadState('calendar', 'talk_api_version');\n const url = (_eventComponent$getCo = (_eventComponent$getCo2 = eventComponent.getConferenceList()[0]) === null || _eventComponent$getCo2 === void 0 ? void 0 : _eventComponent$getCo2.uri) !== null && _eventComponent$getCo !== void 0 ? _eventComponent$getCo : eventComponent.location;\n if (!url || !url.startsWith(window.location.protocol + '//' + window.location.host)) {\n logger.debug('Event\\'s conference/location is from another host', url);\n return;\n }\n const token = extractCallTokenFromUrl(url);\n if (!token) {\n logger.debug('URL ' + url + ' contains no call token');\n return;\n }\n try {\n const {\n data: {\n ocs: {\n data: room\n }\n }\n } = await HTTPClient.get(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token);\n const participantsResponse = await HTTPClient.get(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/participants');\n // Ignore if the actor isn't owner of the conversation\n if (!participantsResponse.data.ocs.data.some(participant => participant.actorId === getCurrentUser().uid && participant.participantType <= 2)) {\n logger.debug('Current user is not a moderator or owner', {\n currentUser: getCurrentUser().uid,\n conversation: participantsResponse.data.ocs.data\n });\n return;\n }\n console.info('room', room);\n for (const attendee of eventComponent.getAttendeeIterator()) {\n logger.debug('Processing attendee', {\n attendee\n });\n if (['GROUP', 'RESOURCE', 'ROOM'].includes(attendee.userType)) {\n continue;\n }\n const participantId = removeMailtoPrefix(attendee.email);\n try {\n var _searchResult$data$oc;\n // Map attendee email to Nextcloud user uid\n const searchResult = await HTTPClient.get(generateOcsUrl('core/autocomplete/', 2) + 'get?search=' + encodeURIComponent(participantId) + '&itemType=&itemId=%20&shareTypes[]=0&limit=2');\n // Only map if there is exactly one result\n if (searchResult.data.ocs.data.length === 1 && searchResult.data.ocs.data[0].id !== getCurrentUser().uid) {\n await HTTPClient.post(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/participants', {\n newParticipant: searchResult.data.ocs.data[0].id,\n source: 'users'\n });\n } else if (((_searchResult$data$oc = searchResult.data.ocs.data[0]) === null || _searchResult$data$oc === void 0 ? void 0 : _searchResult$data$oc.id) === getCurrentUser().uid) {\n logger.debug('Skipping organizer ' + searchResult.data.ocs.data[0].id);\n } else if (room.type === 3) {\n await HTTPClient.post(generateOcsUrl('apps/spreed/api/' + apiVersion + '/', 2) + 'room/' + token + '/participants', {\n newParticipant: participantId,\n source: 'emails'\n });\n } else {\n logger.debug('Attendee ' + participantId + ' ignored as Talk participant');\n }\n } catch (error) {\n logger.info('Could not add attendee ' + participantId + ' as Talk participant', {\n error\n });\n }\n }\n } catch (error) {\n logger.warn('Could not update Talk room attendees', {\n error\n });\n }\n}\n\n/**\r\n * Checks whether the value contains a talk link\r\n *\r\n * @param {?string} text Haystack\r\n * @return {boolean}\r\n */\nexport function doesContainTalkLink(text) {\n if (!text) {\n return false;\n }\n\n // TODO: there is most definitely a more reliable way,\n // but this works for now\n const fakeUrl = generateURLForToken();\n return text.includes(fakeUrl);\n}\n\n/**\r\n * Generates an absolute URL to the talk room based on the token\r\n *\r\n * @param {string} token The token to the call room\r\n * @return {string}\r\n */\nfunction generateURLForToken() {\n let token = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';\n return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + token);\n}\n\n/**\r\n * Extract a spreed call token from the given URL\r\n *\r\n * @param {string} callUrl URL of the spreed call\r\n * @return {string|undefined} Matched token or undefined if URL is invalid\r\n */\nexport function extractCallTokenFromUrl(callUrl) {\n var _callUrl$match$, _callUrl$match;\n return (_callUrl$match$ = (_callUrl$match = callUrl.match(/\\/call\\/([a-z0-9]*)(\\/|#.*)?$/)) === null || _callUrl$match === void 0 ? void 0 : _callUrl$match[1]) !== null && _callUrl$match$ !== void 0 ? _callUrl$match$ : undefined;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getTimezoneManager } from '@nextcloud/calendar-js';\nconst timezoneManager = getTimezoneManager();\nlet initialized = false;\n\n/**\r\n * Gets the timezone-manager\r\n * initializes it if necessary\r\n *\r\n * @return {TimezoneManager}\r\n */\nexport default function () {\n if (!initialized) {\n timezoneManager.registerDefaultTimezones();\n initialized = true;\n }\n return timezoneManager;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport jstz from 'jstz';\n\n/**\r\n * Returns the current timezone of the user\r\n *\r\n * @return {string} Current timezone of user\r\n */\nconst detectTimezone = () => {\n const determinedTimezone = jstz.determine();\n if (!determinedTimezone) {\n return 'UTC';\n }\n const timezoneName = determinedTimezone.name();\n if (!timezoneName) {\n return 'UTC';\n }\n return timezoneName;\n};\nexport default detectTimezone;\nexport { detectTimezone };","/**\r\n * @copyright Copyright (c) 2021 Richard Steinmetz \r\n *\r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Remove the mailto prefix from a URI and return it\r\n *\r\n * @param {string} uri URI to remove the prefix from\r\n * @return {string} URI without a mailto prefix\r\n */\nexport function removeMailtoPrefix(uri) {\n if (typeof uri !== 'string') {\n return '';\n }\n if (uri.startsWith('mailto:')) {\n return uri.slice(7);\n }\n return uri;\n}\n\n/**\r\n * Add the mailto prefix to a URI if it doesn't have one yet and return it\r\n *\r\n * @param {string} uri URI to add the prefix to\r\n * @return {string} URI with a mailto prefix\r\n */\nexport function addMailtoPrefix(uri) {\n if (typeof uri !== 'string') {\n return 'mailto:';\n }\n if (uri.startsWith('mailto:')) {\n return uri;\n }\n return \"mailto:\".concat(uri);\n}\n\n/**\r\n * Get the display name of an organizer\r\n *\r\n * @param {?object} organizer Organizer object to extract a display name from\r\n * @return {string} Display name of given organizer\r\n */\nexport function organizerDisplayName(organizer) {\n if (!organizer) {\n return '';\n }\n if (organizer.commonName) {\n return organizer.commonName;\n }\n return removeMailtoPrefix(organizer.uri);\n}","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { DateTimeValue } from '@nextcloud/calendar-js';\n\n/**\r\n * Get all recurrence-items in given range\r\n *\r\n * @param {object} calendarObject Calendar-object model\r\n * @param {Date} start Begin of time-range\r\n * @param {Date} end End of time-range\r\n * @return {Array}\r\n */\nconst getAllObjectsInTimeRange = (calendarObject, start, end) => {\n const iterator = calendarObject.calendarComponent.getVObjectIterator();\n const firstVObject = iterator.next().value;\n if (!firstVObject) {\n return [];\n }\n const s = DateTimeValue.fromJSDate(start, true);\n const e = DateTimeValue.fromJSDate(end, true);\n return firstVObject.recurrenceManager.getAllOccurrencesBetween(s, e);\n};\n\n/**\r\n * Get recurrence-item at exactly a given recurrence-Id\r\n *\r\n * @param {object} calendarObject Calendar-object model\r\n * @param {Date} recurrenceId RecurrenceId to retrieve\r\n * @return {AbstractRecurringComponent|null}\r\n */\nconst getObjectAtRecurrenceId = (calendarObject, recurrenceId) => {\n const iterator = calendarObject.calendarComponent.getVObjectIterator();\n const firstVObject = iterator.next().value;\n if (!firstVObject) {\n return null;\n }\n const d = DateTimeValue.fromJSDate(recurrenceId, true);\n return firstVObject.recurrenceManager.getOccurrenceAtExactly(d);\n};\nexport { getAllObjectsInTimeRange, getObjectAtRecurrenceId };","/**\r\n * @copyright Copyright (c) 2023 Richard Steinmetz \r\n *\r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n// Code was taken from:\n// - https://github.com/juliuste/closest-css-color\n// - https://github.com/gausie/colour-proximity\n// - https://github.com/gausie/colour-proximity/pull/3\n\nimport cssColors from 'css-color-names';\nimport sortBy from 'lodash/sortBy.js';\nimport pick from 'lodash/pick.js';\nimport uniqBy from 'lodash/uniqBy.js';\nimport { get } from 'color-string';\nconst uniqColorKeys = uniqBy(Object.keys(cssColors), c => cssColors[c]);\nconst filteredColors = pick(cssColors, uniqColorKeys);\nconst colors = sortBy(Object.keys(filteredColors).map(name => ({\n name,\n hex: filteredColors[name]\n})), c => c.hex);\nconst defaults = {\n detailed: false\n};\n\n/**\r\n * Find the closest CSS color to a given hex color.\r\n *\r\n * Adapted from https://github.com/juliuste/closest-css-color\r\n *\r\n * Copyright (c) 2021, Julius Tens\r\n *\r\n * Permission to use, copy, modify, and/or distribute this software for any purpose with or without\r\n * fee is hereby granted, provided that the above copyright notice and this permission notice\r\n * appear in all copies.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS\r\n * SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE\r\n * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,\r\n * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\r\n * OF THIS SOFTWARE.\r\n *\r\n * @param {string} hex Hex color string\r\n * @param {object} opt Options\r\n * @param {boolean=} opt.detailed Return color object instead of just the name\r\n * @return {string|{name: string, hex: string}} Closest color name or object\r\n */\nexport default function closestColor(hex) {\n let opt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n const options = {\n ...defaults,\n ...opt\n };\n const sortedColors = sortBy(colors, c => proximity(hex, c.hex));\n if (options.detailed) {\n return sortedColors[0];\n }\n return sortedColors[0].name;\n}\n\n/**\r\n * Calculate the proximity between two colors.\r\n *\r\n * Adapted from https://github.com/gausie/colour-proximity\r\n *\r\n * Copyright (c) 2013, Samuel Gaus\r\n *\r\n * @param {string} s1 Hex color string 1\r\n * @param {string} s2 Hex color string 2\r\n * @return {number}\r\n */\nfunction proximity(s1, s2) {\n const c1 = rgb2lab(get.rgb(s1));\n const c2 = rgb2lab(get.rgb(s2));\n return Math.sqrt(Math.pow(c1[0] - c2[0], 2) + Math.pow(c1[1] - c2[1], 2) + Math.pow(c1[2] - c2[2], 2));\n}\n\n/**\r\n * Adapted from https://github.com/gausie/colour-proximity\r\n *\r\n * Copyright (c) 2013, Samuel Gaus\r\n *\r\n * @param {number[]} input RGB array\r\n */\nfunction rgb2lab(input) {\n // This code is adapted from various functions at http://www.easyrgb.com/index.php?X=MATH\n\n const rgb = [0, 0, 0];\n const xyz = [0, 0, 0];\n const Lab = [0, 0, 0];\n for (let i = 0; i < input.length; i++) {\n let value = input[i] / 255;\n if (value > 0.04045) {\n value = Math.pow((value + 0.055) / 1.055, 2.4);\n } else {\n value = value / 12.92;\n }\n rgb[i] = value * 100;\n }\n xyz[0] = (rgb[0] * 0.4124 + rgb[1] * 0.3576 + rgb[2] * 0.1805) / 95.047; // ref_X = 95.047 Observer= 2°, Illuminant= D65\n xyz[1] = (rgb[0] * 0.2126 + rgb[1] * 0.7152 + rgb[2] * 0.0722) / 100.0; // ref_Y = 100.000\n xyz[2] = (rgb[0] * 0.0193 + rgb[1] * 0.1192 + rgb[2] * 0.9505) / 108.883; // ref_Z = 108.883\n\n for (let i = 0; i < 3; i++) {\n let value = xyz[i];\n if (value > 0.008856) {\n value = Math.pow(value, 1 / 3);\n } else {\n value = 7.787 * value + 16 / 116;\n }\n xyz[i] = value;\n }\n Lab[0] = parseFloat((116 * xyz[1] - 16).toFixed(3));\n Lab[1] = parseFloat((500 * (xyz[0] - xyz[1])).toFixed(3));\n Lab[2] = parseFloat((200 * (xyz[1] - xyz[2])).toFixed(3));\n return Lab;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport convert from 'color-convert';\nimport { uidToColor } from './uidToColor.js';\nimport css3Colors from 'css-color-names';\nimport closestColor from './closestColor.js';\n\n/**\r\n * Detect if a color is light or dark\r\n *\r\n * @param {object} data The destructuring object\r\n * @param {number} data.red Red part of the RGB\r\n * @param {number} data.green Green part of the RGB\r\n * @param {number} data.blue Blue part of the RGB\r\n * @return {boolean} true if color is light, false if color is dark\r\n */\nexport function isLight(_ref) {\n let {\n red,\n green,\n blue\n } = _ref;\n const brightness = (red * 299 + green * 587 + blue * 114) / 1000;\n return brightness > 130;\n}\n\n/**\r\n * Get a text-color that's readable on a given background color\r\n *\r\n * @param {string} hexColor The hex color to get a text color for\r\n * @return {string} the matching text color\r\n */\nexport function generateTextColorForHex(hexColor) {\n return generateTextColorForRGB(hexToRGB(hexColor));\n}\n\n/**\r\n * Get a text-color that's readable on a given background color\r\n *\r\n * @param {object} data The destructuring object\r\n * @param {number} data.red Red part of the RGB\r\n * @param {number} data.green Green part of the RGB\r\n * @param {number} data.blue Blue part of the RGB\r\n * @return {string}\r\n */\nexport function generateTextColorForRGB(_ref2) {\n let {\n red,\n green,\n blue\n } = _ref2;\n return isLight({\n red,\n green,\n blue\n }) ? '#000000' : '#FAFAFA';\n}\n\n/**\r\n * Convert hex string to RGB\r\n *\r\n * @param {string} hexColor The hex color to convert\r\n * @return {string} the RGB result\r\n */\nexport function hexToRGB(hexColor) {\n if (hexColor == null) {\n return {\n red: 0,\n green: 0,\n blue: 0\n };\n }\n const [red, green, blue] = convert.hex.rgb(hexColor.slice(1));\n return {\n red,\n green,\n blue\n };\n}\n\n/**\r\n * Generates a hex color based on RGB string\r\n *\r\n * @param {string} uid The string to generate a color from\r\n * @return {string} The hex color\r\n */\nexport function uidToHexColor(uid) {\n const color = uidToColor(uid);\n return '#' + convert.rgb.hex(color.r, color.g, color.b);\n}\n\n/**\r\n * Detects a color from a given string\r\n *\r\n * @param {string} color The color to get the real RGB hex string from\r\n * @return {string|boolean|*} String if color detected, boolean if not\r\n */\nexport function detectColor(color) {\n if (/^(#)((?:[A-Fa-f0-9]{3}){1,2})$/.test(color)) {\n // #ff00ff and #f0f\n return color;\n } else if (/^((?:[A-Fa-f0-9]{3}){1,2})$/.test(color)) {\n // ff00ff and f0f\n return '#' + color;\n } else if (/^(#)((?:[A-Fa-f0-9]{8}))$/.test(color)) {\n // #ff00ffff and #f0ff\n return color.slice(0, 7);\n } else if (/^((?:[A-Fa-f0-9]{8}))$/.test(color)) {\n // ff00ffff and f0ff\n return '#' + color.slice(0, 6);\n }\n return false;\n}\n\n/**\r\n * Gets the HEX code for a css3 color name\r\n *\r\n * @param {string} colorName The name of the css3 color\r\n * @return {string | null} string of HEX if valid color, null if not\r\n */\nexport function getHexForColorName(colorName) {\n return css3Colors[colorName] || null;\n}\n\n/**\r\n * Gets the closest css3 color name for a given HEX code\r\n *\r\n * @param {string} hex The HEX code to get a css3 color name for\r\n * @return {string}\r\n */\nexport function getClosestCSS3ColorNameForHex(hex) {\n return closestColor(hex);\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport logger from './logger.js';\n\n/**\r\n * returns a new Date object\r\n *\r\n * @return {Date}\r\n */\nexport function dateFactory() {\n return new Date();\n}\n\n/**\r\n * formats a Date object as YYYYMMDD\r\n *\r\n * @param {Date} date Date to format\r\n * @return {string}\r\n */\nexport function getYYYYMMDDFromDate(date) {\n return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().split('T')[0];\n}\n\n/**\r\n * get unix time from date object\r\n *\r\n * @param {Date} date Date to format\r\n * @return {number}\r\n */\nexport function getUnixTimestampFromDate(date) {\n return Math.floor(date.getTime() / 1000);\n}\n\n/**\r\n * Gets a Date-object based on the firstday param used in routes\r\n *\r\n * @param {string} firstDayParam The firstday param from the router\r\n * @return {Date}\r\n */\nexport function getDateFromFirstdayParam(firstDayParam) {\n if (firstDayParam === 'now') {\n return dateFactory();\n }\n const [year, month, date] = firstDayParam.split('-').map(str => parseInt(str, 10));\n if (Number.isNaN(year) || Number.isNaN(month) || Number.isNaN(date)) {\n logger.error('First day parameter contains non-numerical components, falling back to today');\n return dateFactory();\n }\n const dateObject = dateFactory();\n dateObject.setFullYear(year, month - 1, date);\n dateObject.setHours(0, 0, 0, 0);\n return dateObject;\n}\n\n/**\r\n * formats firstday param as YYYYMMDD\r\n *\r\n * @param {string} firstDayParam The firstday param from the router\r\n * @return {string}\r\n */\nexport function getYYYYMMDDFromFirstdayParam(firstDayParam) {\n if (firstDayParam === 'now') {\n return getYYYYMMDDFromDate(dateFactory());\n }\n return firstDayParam;\n}\n\n/**\r\n * Gets a date object based on the given DateTimeValue\r\n * Ignores given timezone-information\r\n *\r\n * @param {DateTimeValue} dateTimeValue Value to get date from\r\n * @return {Date}\r\n */\nexport function getDateFromDateTimeValue(dateTimeValue) {\n return new Date(dateTimeValue.year, dateTimeValue.month - 1, dateTimeValue.day, dateTimeValue.hour, dateTimeValue.minute, 0, 0);\n}\n\n/**\r\n * modifies a date\r\n *\r\n * @param {Date} date Date object to modify\r\n * @param {object} data The destructuring object\r\n * @param {number} data.day Number of days to add\r\n * @param {number} data.week Number of weeks to add\r\n * @param {number} data.month Number of months to add\r\n * @param data.year\r\n * @return {Date}\r\n */\nexport function modifyDate(date, _ref) {\n let {\n day = 0,\n week = 0,\n month = 0,\n year = 0\n } = _ref;\n date = new Date(date.getTime());\n date.setDate(date.getDate() + day);\n date.setDate(date.getDate() + week * 7);\n date.setMonth(date.getMonth() + month);\n date.setFullYear(date.getFullYear() + year);\n return date;\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getLoggerBuilder } from '@nextcloud/logger';\nconst logger = getLoggerBuilder().setApp('calendar').detectUser().build();\n\n/**\r\n * Logs a debug message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logDebug = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.debug(message, context);\n};\n\n/**\r\n * Logs an error message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logError = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.error(message, context);\n};\n\n/**\r\n * Logs a fatal message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logFatal = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.fatal(message, context);\n};\n\n/**\r\n * Logs an info message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logInfo = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.info(message, context);\n};\n\n/**\r\n * Logs a warn message\r\n *\r\n * @param {string} message The message to log\r\n * @param {object=} context Additional context if needed\r\n */\nconst logWarn = function (message) {\n let context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n logger.warn(message, context);\n};\nexport default logger;\nexport { logDebug, logError, logFatal, logInfo, logWarn };","/**\r\n * @copyright Copyright (c) 2018 John Molakvoæ \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport md5 from 'md5';\n\n/**\r\n * This is copied from nextcloud-vue for now, until it is exposed upstream.\r\n */\n\nexport const uidToColor = uid => {\n // Normalize hash\n let hash = uid.toLowerCase();\n\n // Already a md5 hash?\n if (hash.match(/^([0-9a-f]{4}-?){8}$/) === null) {\n hash = md5(hash);\n }\n hash = hash.replace(/[^0-9a-f]/g, '');\n const steps = 6;\n const finalPalette = GenColors(steps);\n\n /**\r\n * Convert a string to an integer evenly\r\n *\r\n * @param {string} hash The string to convert\r\n * @param {number} maximum The maximum value\r\n * @return {number} The integer calculated\r\n */\n function hashToInt(hash, maximum) {\n let finalInt = 0;\n const result = [];\n\n // Splitting evenly the string\n for (let i = 0; i < hash.length; i++) {\n // chars in md5 goes up to f, hex:16\n result.push(parseInt(hash.charAt(i), 16) % 16);\n }\n\n // Adds up all results\n for (const j in result) {\n finalInt += result[j];\n }\n\n // chars in md5 goes up to f, hex:16\n // make sure we're always using int in our operation\n return parseInt(parseInt(finalInt, 10) % maximum, 10);\n }\n return finalPalette[hashToInt(hash, steps * 3)];\n};\n\n/**\r\n * Color object\r\n *\r\n * @param {number} r The red value\r\n * @param {number} g The green value\r\n * @param {number} b The blue value\r\n */\nfunction Color(r, g, b) {\n this.r = r;\n this.g = g;\n this.b = b;\n}\n\n/**\r\n * Calculate the number of steps\r\n *\r\n * @param {number} steps The number of steps\r\n * @param {Array} ends The ends\r\n * @return {Array} Array containing the number of steps per color\r\n */\nfunction stepCalc(steps, ends) {\n const step = new Array(3);\n step[0] = (ends[1].r - ends[0].r) / steps;\n step[1] = (ends[1].g - ends[0].g) / steps;\n step[2] = (ends[1].b - ends[0].b) / steps;\n return step;\n}\n\n/**\r\n * Create a color palette from two colors\r\n *\r\n * @param {number} steps The number of steps the palette has\r\n * @param {string} color1 The first color\r\n * @param {string} color2 The second color\r\n * @return {Array} The created palette array\r\n */\nfunction mixPalette(steps, color1, color2) {\n const palette = [];\n palette.push(color1);\n const step = stepCalc(steps, [color1, color2]);\n for (let i = 1; i < steps; i++) {\n const r = parseInt(color1.r + step[0] * i, 10);\n const g = parseInt(color1.g + step[1] * i, 10);\n const b = parseInt(color1.b + step[2] * i, 10);\n palette.push(new Color(r, g, b));\n }\n return palette;\n}\n\n/**\r\n * Generate colors from the official nextcloud color\r\n * You can provide how many colors you want (multiplied by 3)\r\n * if step = 6\r\n * 3 colors * 6 will result in 18 generated colors\r\n *\r\n * @param {number} [steps] Number of steps to go from a color to another\r\n * @return {object[]}\r\n */\nfunction GenColors(steps) {\n if (!steps) {\n steps = 6;\n }\n const red = new Color(182, 70, 157);\n const yellow = new Color(221, 203, 85);\n const blue = new Color(0, 130, 201); // Nextcloud blue\n\n const palette1 = mixPalette(steps, red, yellow);\n const palette2 = mixPalette(steps, yellow, blue);\n const palette3 = mixPalette(steps, blue, red);\n return palette1.concat(palette2).concat(palette3);\n}\nexport default uidToColor;"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/calendar/js/calendar-src_store_index_js.js b/calendar/js/calendar-src_store_index_js.js index 9587ea6..72408c3 100644 --- a/calendar/js/calendar-src_store_index_js.js +++ b/calendar/js/calendar-src_store_index_js.js @@ -874,6 +874,7 @@ const mapEventComponentToEventObject = eventComponent => { location: eventComponent.location, client: "CLIENT", embalmer: "TEST", + comment: "", description: eventComponent.description, accessClass: eventComponent.accessClass, status: eventComponent.status, @@ -965,6 +966,9 @@ const mapEventComponentToEventObject = eventComponent => { if (eventComponent.hasProperty('EMBALMER')) { eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER'); } + if (eventComponent.hasProperty('COMMENT')) { + eventObject.comment = eventComponent.getFirstPropertyFirstValue('COMMENT'); + } return eventObject; }; @@ -2229,6 +2233,22 @@ const mutations = { calendarObjectInstance.eventComponent.location = location; calendarObjectInstance.location = location; }, + /** + * Change the comment of an event + * + * @param {object} state The Vuex state + * @param {object} data The destructuring object + * @param {object} data.calendarObjectInstance The calendarObjectInstance object + * @param {string} data.comment New comment to set + */ + changeComment(state, _ref11) { + let { + calendarObjectInstance, + comment + } = _ref11; + calendarObjectInstance.eventComponent.comment = comment; + calendarObjectInstance.comment = comment; + }, /** * Change the client of an event * @@ -4640,7 +4660,31 @@ const actions = { if (eventComponent != null) { if (eventComponent.client != null) { let newClientKeyValue = "CLIENT:" + eventComponent.client; - icsValue = icsValue.replace(/CLIENT:\d+/, newClientKeyValue); + let regexEmptyClient = /CLIENT:(?!\d)(?=\s*[\r\n])/g; + if (regexEmptyClient.test(icsValue)) { + icsValue = icsValue.replace(regexEmptyClient, newClientKeyValue); + } + let regex = /CLIENT:\d+/; + if (regex.test(icsValue)) { + icsValue = icsValue.replace(regex, newClientKeyValue); + } else { + const customKeyValue = { + "CLIENT": eventComponent.client + }; + icsValue = (0,_models_calendarObject_js__WEBPACK_IMPORTED_MODULE_0__.setCustomKeyValuesArrayToIcsAndReturnIcs)(icsValue, customKeyValue); + } + } + if (eventComponent.comment != null) { + let newCommentKeyValue = "COMMENT:" + eventComponent.comment; + let regex = /^COMMENT:.*$/m; + if (regex.test(icsValue)) { + icsValue = icsValue.replace(regex, newCommentKeyValue); + } else { + const customKeyValue = { + "COMMENT": eventComponent.comment + }; + icsValue = (0,_models_calendarObject_js__WEBPACK_IMPORTED_MODULE_0__.setCustomKeyValuesArrayToIcsAndReturnIcs)(icsValue, customKeyValue); + } } if (eventComponent.isPrivate != null) { let isPrivateValue = eventComponent.isPrivate ? "1" : "0"; @@ -8259,4 +8303,4 @@ function getLinkToConfig(key) { /***/ }) }]); -//# sourceMappingURL=calendar-src_store_index_js.js.map?v=fcfc2d6839479e13e5cc \ No newline at end of file +//# sourceMappingURL=calendar-src_store_index_js.js.map?v=fcfc2d6839479e13e5cc diff --git a/calendar/js/calendar-src_store_index_js.js.map b/calendar/js/calendar-src_store_index_js.js.map index aa71d87..547657d 100644 --- a/calendar/js/calendar-src_store_index_js.js.map +++ b/calendar/js/calendar-src_store_index_js.js.map @@ -1 +1 @@ -{"version":3,"file":"calendar-src_store_index_js.js?v=fcfc2d6839479e13e5cc","mappings":";;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;AC3KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AClHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACxYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACnNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACj8EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AC9cA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACx3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC9QA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACpjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC3OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///calendar/src\\models\\alarm.js","webpack:///calendar/src\\models\\attachment.js","webpack:///calendar/src\\models\\attendee.js","webpack:///calendar/src\\models\\calendar.js","webpack:///calendar/src\\models\\calendarObject.js","webpack:///calendar/src\\models\\calendarShare.js","webpack:///calendar/src\\models\\event.js","webpack:///calendar/src\\models\\principal.js","webpack:///calendar/src\\models\\recurrenceRule.js","webpack:///calendar/src\\services\\attachmentService.js","webpack:///calendar/src\\services\\roleService.js","webpack:///calendar/src\\services\\settings.js","webpack:///calendar/src\\store\\calendarObjectInstance.js","webpack:///calendar/src\\store\\calendarObjects.js","webpack:///calendar/src\\store\\calendars.js","webpack:///calendar/src\\store\\contacts.js","webpack:///calendar/src\\store\\davRestrictions.js","webpack:///calendar/src\\store\\fetchedTimeRanges.js","webpack:///calendar/src\\store\\importFiles.js","webpack:///calendar/src\\store\\importState.js","webpack:///calendar/src\\store\\index.js","webpack:///calendar/src\\store\\principals.js","webpack:///calendar/src\\store\\settings.js","webpack:///calendar/src\\store\\userRole.js","webpack:///calendar/src\\utils\\alarms.js","webpack:///calendar/src\\utils\\recurrence.js","webpack:///calendar/src\\utils\\settings.js"],"sourcesContent":["/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getAmountAndUnitForTimedEvents, getAmountHoursMinutesAndUnitForAllDayEvents } from '../utils/alarms.js';\nimport { getDateFromDateTimeValue } from '../utils/date.js';\n\n/**\r\n * Creates a complete alarm object based on given props\r\n *\r\n * @param {object} props The alarm properties already provided\r\n * @return {object}\r\n */\nconst getDefaultAlarmObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js alarm component\n alarmComponent: null,\n // Type of alarm: DISPLAY, EMAIL, AUDIO\n type: null,\n // Whether or not the alarm is relative\n isRelative: false,\n // Date object of an absolute alarm (if it's absolute, it must be DATE-TIME)\n absoluteDate: null,\n // The time zone id of for absolute alarms\n absoluteTimezoneId: null,\n // Whether or not the relative alarm is before the event,\n relativeIsBefore: null,\n // Whether or not the alarm is relative to the event's start\n relativeIsRelatedToStart: null,\n // TIMED EVENTS:\n // Unit (seconds, minutes, hours, ...) if this alarm is inside a timed event\n relativeUnitTimed: null,\n // The amount of unit if this alarm is inside a timed event\n relativeAmountTimed: null,\n // ALL-DAY EVENTS:\n // Unit (seconds, minutes, hours, ...) if this alarm is inside an all-day event\n relativeUnitAllDay: null,\n // The amount of unit if this alarm is inside a all-day event\n relativeAmountAllDay: null,\n // The hours to display alarm for in an all-day event (e.g. 1 day before at 9:00 am)\n relativeHoursAllDay: null,\n // The minutes to display alarm for in an all-day event (e.g. 1 day before at 9:30 am)\n relativeMinutesAllDay: null,\n // The total amount of seconds for a relative alarm\n relativeTrigger: null\n }, props);\n};\n\n/**\r\n * Map an alarm component to our alarm object\r\n *\r\n * @param {AlarmComponent} alarmComponent The calendar-js alarm-component to turn into an alarm object\r\n * @return {object}\r\n */\nconst mapAlarmComponentToAlarmObject = alarmComponent => {\n if (alarmComponent.trigger.isRelative()) {\n const relativeIsBefore = alarmComponent.trigger.value.isNegative;\n const relativeIsRelatedToStart = alarmComponent.trigger.related === 'START';\n const {\n amount: relativeAmountTimed,\n unit: relativeUnitTimed\n } = getAmountAndUnitForTimedEvents(alarmComponent.trigger.value.totalSeconds);\n const {\n unit: relativeUnitAllDay,\n amount: relativeAmountAllDay,\n hours: relativeHoursAllDay,\n minutes: relativeMinutesAllDay\n } = getAmountHoursMinutesAndUnitForAllDayEvents(alarmComponent.trigger.value.totalSeconds);\n const relativeTrigger = alarmComponent.trigger.value.totalSeconds;\n return getDefaultAlarmObject({\n alarmComponent,\n type: alarmComponent.action,\n isRelative: alarmComponent.trigger.isRelative(),\n relativeIsBefore,\n relativeIsRelatedToStart,\n relativeUnitTimed,\n relativeAmountTimed,\n relativeUnitAllDay,\n relativeAmountAllDay,\n relativeHoursAllDay,\n relativeMinutesAllDay,\n relativeTrigger\n });\n } else {\n const absoluteDate = getDateFromDateTimeValue(alarmComponent.trigger.value);\n return getDefaultAlarmObject({\n alarmComponent,\n type: alarmComponent.action,\n isRelative: alarmComponent.trigger.isRelative(),\n absoluteDate,\n absoluteTimezoneId: alarmComponent.trigger.value.timezoneId\n });\n }\n};\nexport { getDefaultAlarmObject, mapAlarmComponentToAlarmObject };","/**\r\n * @copyright Copyright (c) 2022 Mikhail Sazanov\r\n *\r\n * @author Mikhail Sazanov \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Creates a complete attachment object based on given props\r\n *\r\n * @param {object} props The attachment properties already provided\r\n * @return {object}\r\n */\nconst getDefaultAttachmentObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js attachment property\n attachmentProperty: null,\n // The file name of the attachment\n fileName: null,\n // The attachment mime type\n formatType: null,\n // The uri of the attachment\n uri: null,\n // The value from calendar object\n value: null,\n // Preview of file\n xNcHasPreview: null,\n // File id in NC\n xNcFileId: null\n }, props);\n};\n\n/**\r\n * Maps a calendar-js attachment property to our attachment object\r\n *\r\n * @param {attachmentProperty} attachmentProperty The calendar-js attachmentProperty to turn into a attachment object\r\n * @return {object}\r\n */\nconst mapAttachmentPropertyToAttchmentObject = attachmentProperty => {\n return getDefaultAttachmentObject({\n attachmentProperty,\n fileName: attachmentProperty.getParameterFirstValue('FILENAME'),\n formatType: attachmentProperty.formatType,\n uri: attachmentProperty.uri,\n value: attachmentProperty.value,\n xNcHasPreview: attachmentProperty.getParameterFirstValue('X-NC-HAS-PREVIEW') === 'true',\n xNcFileId: attachmentProperty.getParameterFirstValue('X-NC-FILE-ID')\n });\n};\nexport { getDefaultAttachmentObject, mapAttachmentPropertyToAttchmentObject };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n * @copyright Copyright (c) 2023 Jonas Heinrich\r\n *\r\n * @author Georg Ehrke \r\n * @author Jonas Heinrich \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Creates a complete attendee object based on given props\r\n *\r\n * TODO:\r\n * - we should eventually support delegatedFrom and delegatedTo\r\n *\r\n * @param {object} props The attendee properties already provided\r\n * @return {object}\r\n */\nconst getDefaultAttendeeObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js attendee property\n attendeeProperty: null,\n // The display-name of the attendee\n commonName: null,\n // The calendar-user-type of the attendee\n calendarUserType: 'INDIVIDUAL',\n // The participation status of the attendee\n participationStatus: 'NEEDS-ACTION',\n // The role of the attendee\n role: 'REQ-PARTICIPANT',\n // The RSVP for the attendee\n rsvp: false,\n // The uri of the attendee\n uri: null,\n // Member address of the attendee\n member: null\n }, props);\n};\n\n/**\r\n * Maps a calendar-js attendee property to our attendee object\r\n *\r\n * @param {AttendeeProperty} attendeeProperty The calendar-js attendeeProperty to turn into a attendee object\r\n * @return {object}\r\n */\nconst mapAttendeePropertyToAttendeeObject = attendeeProperty => {\n return getDefaultAttendeeObject({\n attendeeProperty,\n commonName: attendeeProperty.commonName,\n calendarUserType: attendeeProperty.userType,\n participationStatus: attendeeProperty.participationStatus,\n role: attendeeProperty.role,\n rsvp: attendeeProperty.rsvp,\n uri: attendeeProperty.email,\n member: attendeeProperty.member\n });\n};\nexport { getDefaultAttendeeObject, mapAttendeePropertyToAttendeeObject };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { detectColor, uidToHexColor } from '../utils/color.js';\nimport { mapDavShareeToCalendarShareObject } from './calendarShare.js';\n\n/**\r\n * Creates a complete calendar-object based on given props\r\n *\r\n * @param {object} props Calendar-props already provided\r\n * @return {object}\r\n */\nconst getDefaultCalendarObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // Id of the calendar\n id: '',\n // Visible display name\n displayName: '',\n // Color of the calendar\n color: uidToHexColor(''),\n // Whether or not the calendar is visible in the grid\n enabled: true,\n // Whether or not the calendar is loading events at the moment\n loading: false,\n // Whether this calendar supports VEvents\n supportsEvents: true,\n // Whether this calendar supports VJournals\n supportsJournals: false,\n // Whether this calendar supports VTodos\n supportsTasks: false,\n // The principal uri of the owner\n owner: '',\n // Timezone set for this calendar\n timezone: null,\n // List of shares\n shares: [],\n // Published url\n publishURL: null,\n // Internal CalDAV url of this calendar\n url: '',\n // Whether this calendar is read-only\n readOnly: false,\n // The order of this calendar in the calendar-list\n order: 0,\n // Whether or not the calendar is shared with me\n isSharedWithMe: false,\n // Whether or not the calendar can be shared by me\n canBeShared: false,\n // Whether or not the calendar can be published by me\n canBePublished: false,\n // Reference to cdav-lib object\n dav: false,\n // All calendar-objects from this calendar that have already been fetched\n calendarObjects: [],\n // Time-ranges that have already been fetched for this calendar\n fetchedTimeRanges: []\n }, props);\n};\n\n/**\r\n * Map a dav collection to our calendar object model\r\n *\r\n * @param {object} calendar The calendar object from the cdav library\r\n * @param {object=} currentUserPrincipal The principal model of the current user principal\r\n * @return {object}\r\n */\nconst mapDavCollectionToCalendar = (calendar, currentUserPrincipal) => {\n const id = btoa(calendar.url);\n const displayName = calendar.displayname || getCalendarUriFromUrl(calendar.url);\n\n // calendar.color can be set to anything on the server,\n // so make sure it's something that remotely looks like a color\n let color = detectColor(calendar.color);\n if (!color) {\n // As fallback if we don't know what color that is supposed to be\n color = uidToHexColor(displayName);\n }\n const supportsEvents = calendar.components.includes('VEVENT');\n const supportsJournals = calendar.components.includes('VJOURNAL');\n const supportsTasks = calendar.components.includes('VTODO');\n const owner = calendar.owner;\n const readOnly = !calendar.isWriteable();\n const canBeShared = calendar.isShareable();\n const canBePublished = calendar.isPublishable();\n const order = calendar.order || 0;\n const url = calendar.url;\n const publishURL = calendar.publishURL || null;\n const timezone = calendar.timezone || null;\n let isSharedWithMe = false;\n if (!currentUserPrincipal) {\n // If the user is not authenticated, the calendar\n // will always be marked as shared with them\n isSharedWithMe = true;\n } else {\n isSharedWithMe = owner !== currentUserPrincipal.url;\n }\n let enabled;\n if (!currentUserPrincipal) {\n // If the user is not authenticated,\n // always enable the calendar\n enabled = true;\n } else if (typeof calendar.enabled === 'boolean') {\n // If calendar-enabled is set, we will just take that\n enabled = calendar.enabled;\n } else {\n // If there is no calendar-enabled,\n // we will display the calendar by default and set enabled\n enabled = true;\n calendar.enabled = true;\n }\n const shares = [];\n if (!!currentUserPrincipal && Array.isArray(calendar.shares)) {\n for (const share of calendar.shares) {\n if (share.href === currentUserPrincipal.principalScheme) {\n continue;\n }\n shares.push(mapDavShareeToCalendarShareObject(share));\n }\n }\n return getDefaultCalendarObject({\n id,\n displayName,\n color,\n order,\n url,\n enabled,\n supportsEvents,\n supportsJournals,\n supportsTasks,\n isSharedWithMe,\n owner,\n readOnly,\n publishURL,\n canBeShared,\n canBePublished,\n shares,\n timezone,\n dav: calendar\n });\n};\n\n/**\r\n * Gets the calendar uri from the url\r\n *\r\n * @param {string} url The url to get calendar uri from\r\n * @return {string}\r\n */\nfunction getCalendarUriFromUrl(url) {\n if (url.endsWith('/')) {\n url = url.substring(0, url.length - 1);\n }\n return url.substring(url.lastIndexOf('/') + 1);\n}\nexport { getDefaultCalendarObject, mapDavCollectionToCalendar };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getParserManager } from '@nextcloud/calendar-js';\nimport { COMPONENT_NAME_EVENT, COMPONENT_NAME_JOURNAL, COMPONENT_NAME_VTODO } from './consts.js';\n\n/**\r\n * Creates a complete calendar-object-object based on given props\r\n *\r\n * @param {object} props Calendar-object-props already provided\r\n * @return {object}\r\n */\nconst getDefaultCalendarObjectObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // Id of this calendar-object\n id: null,\n // Id of the associated calendar\n calendarId: null,\n // The cdav-library object storing the calendar-object\n dav: null,\n // The parsed calendar-js object\n calendarComponent: null,\n // The uid of the calendar-object\n uid: null,\n // The uri of the calendar-object\n uri: null,\n // The type of calendar-object\n objectType: null,\n // Whether or not the calendar-object is an event\n isEvent: false,\n // Whether or not the calendar-object is a journal\n isJournal: false,\n // Whether or not the calendar-object is a task\n isTodo: false,\n // Whether or not the calendar-object exists on the server\n existsOnServer: false\n }, props);\n};\n\n/**\r\n * Maps a calendar-object from c-dav to our calendar-object object\r\n *\r\n * @param {VObject} dav The c-dav VObject\r\n * @param {string} calendarId The calendar-id this object is associated with\r\n * @return {object}\r\n */\nconst mapCDavObjectToCalendarObject = (dav, calendarId) => {\n const parserManager = getParserManager();\n const parser = parserManager.getParserForFileType('text/calendar');\n\n // This should not be the case, but let's just be on the safe side\n if (typeof dav.data !== 'string' || dav.data.trim() === '') {\n throw new Error('Empty calendar object');\n }\n parser.parse(dav.data);\n const calendarComponentIterator = parser.getItemIterator();\n const calendarComponent = calendarComponentIterator.next().value;\n if (!calendarComponent) {\n throw new Error('Empty calendar object');\n }\n const vObjectIterator = calendarComponent.getVObjectIterator();\n const firstVObject = vObjectIterator.next().value;\n return getDefaultCalendarObjectObject({\n id: btoa(dav.url),\n calendarId,\n dav,\n calendarComponent,\n uid: firstVObject.uid,\n uri: dav.url,\n objectType: firstVObject.name,\n isEvent: firstVObject.name === COMPONENT_NAME_EVENT,\n isJournal: firstVObject.name === COMPONENT_NAME_JOURNAL,\n isTodo: firstVObject.name === COMPONENT_NAME_VTODO,\n existsOnServer: true\n });\n};\n\n/**\r\n * Maps a calendar-component from calendar-js to our calendar-object object\r\n *\r\n * @param {CalendarComponent} calendarComponent The calendarComponent to create the calendarObject from\r\n * @param {string=} calendarId The associated calendar if applicable\r\n * @return {object}\r\n */\nconst mapCalendarJsToCalendarObject = function (calendarComponent) {\n let calendarId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n const vObjectIterator = calendarComponent.getVObjectIterator();\n const firstVObject = vObjectIterator.next().value;\n if (!firstVObject) {\n throw new Error('Calendar object without vobjects');\n }\n return getDefaultCalendarObjectObject({\n calendarId,\n calendarComponent,\n uid: firstVObject.uid,\n objectType: firstVObject.name,\n isEvent: firstVObject.name === COMPONENT_NAME_EVENT,\n isJournal: firstVObject.name === COMPONENT_NAME_JOURNAL,\n isTodo: firstVObject.name === COMPONENT_NAME_VTODO\n });\n};\nconst getKeyValueIcsProperty = (key, value) => {\n return \"\".concat(key, \":\").concat(value, \"\\r\\n\");\n};\nconst setCustomKeyValueToIcsAndReturnIcs = (ics, key, value) => {\n const property = getKeyValueIcsProperty(key, value);\n ics = ics.replace('END:VEVENT', \"\".concat(property, \"END:VEVENT\"));\n return ics;\n};\nconst setCustomKeyValuesArrayToIcsAndReturnIcs = (ics, keyValueArray) => {\n for (var key in keyValueArray) {\n const value = keyValueArray[key] ? keyValueArray[key] : '';\n ics = setCustomKeyValueToIcsAndReturnIcs(ics, key, value);\n }\n return ics;\n};\nexport { getDefaultCalendarObjectObject, mapCDavObjectToCalendarObject, mapCalendarJsToCalendarObject, setCustomKeyValuesArrayToIcsAndReturnIcs, getKeyValueIcsProperty, setCustomKeyValueToIcsAndReturnIcs };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { PRINCIPAL_PREFIX_CIRCLE, PRINCIPAL_PREFIX_GROUP, PRINCIPAL_PREFIX_USER } from './consts.js';\n\n/**\r\n * Creates a complete calendar-share-object based on given props\r\n *\r\n * @param {object} props Calendar-share-props already provided\r\n * @return {object}\r\n */\nconst getDefaultCalendarShareObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // Unique identifier\n id: null,\n // Displayname of the sharee\n displayName: null,\n // Whether or not share is writable\n writeable: false,\n // Whether or not sharee is an individual user\n isUser: false,\n // Whether or not sharee is an admin-defined group\n isGroup: false,\n // Whether or not sharee is a user-defined group\n isCircle: false,\n // Uri necessary for deleting / updating share\n uri: null\n }, props);\n};\n\n/**\r\n * Map a dav collection to our calendar object model\r\n *\r\n * @param {object} sharee The sharee object from the cdav library shares\r\n * @return {object}\r\n */\nconst mapDavShareeToCalendarShareObject = sharee => {\n // sharee.href might contain non-latin characters, so let's uri encode it first\n const id = btoa(encodeURI(sharee.href));\n let displayName;\n if (sharee['common-name'] && sharee['common-name'].trim() !== '') {\n displayName = sharee['common-name'];\n } else if (sharee.href.startsWith(PRINCIPAL_PREFIX_GROUP)) {\n displayName = decodeURIComponent(sharee.href.slice(28));\n } else if (sharee.href.startsWith(PRINCIPAL_PREFIX_USER)) {\n displayName = decodeURIComponent(sharee.href.slice(27));\n } else {\n displayName = sharee.href;\n }\n const writeable = sharee.access[0].endsWith('read-write');\n const isUser = sharee.href.startsWith(PRINCIPAL_PREFIX_USER);\n const isGroup = sharee.href.startsWith(PRINCIPAL_PREFIX_GROUP);\n const isCircle = sharee.href.startsWith(PRINCIPAL_PREFIX_CIRCLE);\n const uri = sharee.href;\n return getDefaultCalendarShareObject({\n id,\n displayName,\n writeable,\n isUser,\n isGroup,\n isCircle,\n uri\n });\n};\nexport { getDefaultCalendarShareObject, mapDavShareeToCalendarShareObject };","/**\n * @copyright Copyright (c) 2020 Georg Ehrke\n *\n * @author Georg Ehrke \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 .\n *\n */\n\nimport { getDateFromDateTimeValue } from '../utils/date.js';\nimport { DurationValue, DateTimeValue } from '@nextcloud/calendar-js';\nimport { getHexForColorName, getClosestCSS3ColorNameForHex } from '../utils/color.js';\nimport { mapAlarmComponentToAlarmObject } from './alarm.js';\nimport { mapAttendeePropertyToAttendeeObject } from './attendee.js';\nimport { mapAttachmentPropertyToAttchmentObject } from './attachment.js';\nimport { getDefaultRecurrenceRuleObject, mapRecurrenceRuleValueToRecurrenceRuleObject } from './recurrenceRule.js';\n\n/**\n * Creates a complete calendar-object-instance-object based on given props\n *\n * @param {object} props The props already provided\n * @return {object}\n */\nconst getDefaultEventObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The real event-component coming from calendar-js\n eventComponent: null,\n // Title of the event\n title: null,\n // Start date of the event\n startDate: null,\n // Timezone of the start date\n startTimezoneId: null,\n // End date of the event\n endDate: null,\n // Timezone of the end date\n endTimezoneId: null,\n // Indicator whether or not event is all-day\n isAllDay: false,\n // Whether or not the user is allowed to toggle the all-day checkbox\n canModifyAllDay: true,\n // Location that the event takes places in\n location: null,\n //client of the event\n client: null,\n //embalmer(Thanato) of the event\n embalmer: null,\n //Private\n isPrivate: false,\n // description of the event\n description: null,\n // Access class of the event (PUBLIC, PRIVATE, CONFIDENTIAL)\n accessClass: null,\n // Status of the event (CONFIRMED, TENTATIVE, CANCELLED)\n status: null,\n // Whether or not to block this event in Free-Busy reports (TRANSPARENT, OPAQUE)\n timeTransparency: null,\n // The recurrence rule of this event. We only support one recurrence-rule\n recurrenceRule: getDefaultRecurrenceRuleObject(),\n // Whether or not this event has multiple recurrence-rules\n hasMultipleRRules: false,\n // Whether or not this is the master item\n isMasterItem: false,\n // Whether or not this is a recurrence-exception\n isRecurrenceException: false,\n // Whether or not the applied modifications require to update this and all future\n forceThisAndAllFuture: false,\n // Whether or not it's possible to create a recurrence-exception for this event\n canCreateRecurrenceException: false,\n // Attendees of this event\n attendees: [],\n // Organizer of the event\n organizer: null,\n // Alarm of the event\n alarms: [],\n // Custom color of the event\n customColor: null,\n // Categories\n categories: [],\n // Attachments of this event\n attachments: []\n }, props);\n};\n\n/**\n *\n * @param {EventComponent} eventComponent The calendar-js eventComponent\n * @return {object}\n */\nconst mapEventComponentToEventObject = eventComponent => {\n const eventObject = getDefaultEventObject({\n eventComponent,\n title: eventComponent.title,\n isAllDay: eventComponent.isAllDay(),\n isPrivate: false,\n canModifyAllDay: eventComponent.canModifyAllDay(),\n location: eventComponent.location,\n client: \"CLIENT\",\n embalmer: \"TEST\",\n description: eventComponent.description,\n accessClass: eventComponent.accessClass,\n status: eventComponent.status,\n timeTransparency: eventComponent.timeTransparency,\n categories: Array.from(eventComponent.getCategoryIterator()),\n isMasterItem: eventComponent.isMasterItem(),\n isRecurrenceException: eventComponent.isRecurrenceException(),\n canCreateRecurrenceException: eventComponent.canCreateRecurrenceExceptions()\n });\n\n /**\n * According to RFC5545, DTEND is exclusive. This is rather intuitive for timed-events\n * but rather unintuitive for all-day events\n *\n * That's why, when an event is all-day from 2019-10-03 to 2019-10-04,\n * it will be displayed as 2019-10-03 to 2019-10-03 in the editor.\n */\n eventObject.startDate = getDateFromDateTimeValue(eventComponent.startDate);\n eventObject.startTimezoneId = eventComponent.startDate.timezoneId;\n if (eventComponent.isAllDay()) {\n const endDate = eventComponent.endDate.clone();\n endDate.addDuration(DurationValue.fromSeconds(-1 * 60 * 60 * 24));\n eventObject.endDate = getDateFromDateTimeValue(endDate);\n } else {\n eventObject.endDate = getDateFromDateTimeValue(eventComponent.endDate);\n }\n eventObject.endTimezoneId = eventComponent.endDate.timezoneId;\n\n /**\n * Extract organizer if there is any\n */\n if (eventComponent.organizer) {\n const organizerProperty = eventComponent.getFirstProperty('ORGANIZER');\n eventObject.organizer = {\n commonName: organizerProperty.commonName,\n uri: organizerProperty.email,\n attendeeProperty: organizerProperty\n };\n }\n\n /**\n * Extract alarms\n */\n for (const alarm of eventComponent.getAlarmIterator()) {\n eventObject.alarms.push(mapAlarmComponentToAlarmObject(alarm));\n }\n\n /**\n * Extract attendees\n */\n for (const attendee of eventComponent.getAttendeeIterator()) {\n eventObject.attendees.push(mapAttendeePropertyToAttendeeObject(attendee));\n }\n\n /**\n * Extract attachments\n */\n\n for (const attachment of eventComponent.getPropertyIterator('ATTACH')) {\n eventObject.attachments.push(mapAttachmentPropertyToAttchmentObject(attachment));\n }\n\n /**\n * Extract recurrence-rule\n */\n const recurrenceRuleIterator = eventComponent.getPropertyIterator('RRULE');\n const recurrenceRuleFirstIteration = recurrenceRuleIterator.next();\n const firstRecurrenceRule = recurrenceRuleFirstIteration.value;\n if (firstRecurrenceRule) {\n eventObject.recurrenceRule = mapRecurrenceRuleValueToRecurrenceRuleObject(firstRecurrenceRule.getFirstValue(), eventComponent.startDate);\n eventObject.hasMultipleRRules = !recurrenceRuleIterator.next().done;\n }\n\n /**\n * Convert the CSS 3 color name to a hex color\n */\n if (eventComponent.hasProperty('COLOR')) {\n const hexColor = getHexForColorName(eventComponent.getFirstPropertyFirstValue('COLOR'));\n if (hexColor !== null) {\n eventObject.customColor = hexColor;\n }\n }\n if (eventComponent.hasProperty('CLIENT')) {\n eventObject.client = eventComponent.getFirstPropertyFirstValue('CLIENT');\n }\n if (eventComponent.hasProperty('ISPRIVATE')) {\n eventObject.isPrivate = eventComponent.getFirstPropertyFirstValue('ISPRIVATE') === '1' ? true : false;\n }\n if (eventComponent.hasProperty('EMBALMER')) {\n eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER');\n }\n return eventObject;\n};\n\n/**\n * Copy data from a calendar-object-instance into a calendar-js event-component\n *\n * @param {object} eventObject The calendar-object-instance object\n * @param {EventComponent} eventComponent The calendar-js EventComponent object\n */\nconst copyCalendarObjectInstanceIntoEventComponent = (eventObject, eventComponent) => {\n eventComponent.title = eventObject.title;\n eventComponent.location = eventObject.location;\n eventComponent.client = eventObject.client;\n eventComponent.embalmer = eventObject.embalmer;\n eventComponent.isPrivate = eventObject.isPrivate;\n eventComponent.description = eventObject.description;\n eventComponent.accessClass = eventObject.accessClass;\n eventComponent.status = eventObject.status;\n eventComponent.timeTransparency = eventObject.timeTransparency;\n for (const category of eventObject.categories) {\n eventComponent.addCategory(category);\n }\n if (eventObject.organizer) {\n eventComponent.setOrganizerFromNameAndEMail(eventObject.organizer.commonName, eventObject.organizer.uri);\n }\n for (const alarm of eventObject.alarms) {\n if (alarm.isRelative) {\n const duration = DurationValue.fromSeconds(alarm.relativeTrigger);\n eventComponent.addRelativeAlarm(alarm.type, duration, alarm.relativeIsRelatedToStart);\n } else {\n const date = DateTimeValue.fromJSDate(alarm.absoluteDate);\n eventComponent.addAbsoluteAlarm(alarm.type, date);\n }\n }\n for (const attendee of eventObject.attendees) {\n eventComponent.addProperty(attendee.attendeeProperty);\n }\n for (const rule of eventObject.eventComponent.getPropertyIterator('RRULE')) {\n eventComponent.addProperty(rule);\n }\n if (eventObject.customColor) {\n eventComponent.color = getClosestCSS3ColorNameForHex(eventObject.customColor);\n }\n};\nexport { getDefaultEventObject, mapEventComponentToEventObject, copyCalendarObjectInstanceIntoEventComponent };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport { PRINCIPAL_PREFIX_CALENDAR_RESOURCE, PRINCIPAL_PREFIX_CALENDAR_ROOM, PRINCIPAL_PREFIX_CIRCLE, PRINCIPAL_PREFIX_GROUP, PRINCIPAL_PREFIX_USER } from './consts.js';\n\n/**\r\n * Creates a complete principal-object based on given props\r\n *\r\n * @param {object} props Principal-props already provided\r\n * @return {any}\r\n */\nconst getDefaultPrincipalObject = props => Object.assign({}, {\n // Id of the principal\n id: null,\n // Calendar-user-type. This can be INDIVIDUAL, GROUP, RESOURCE or ROOM\n calendarUserType: 'INDIVIDUAL',\n // E-Mail address of principal used for scheduling\n emailAddress: null,\n // The principals display-name\n // TODO: this should be renamed to displayName\n displayname: null,\n // principalScheme\n principalScheme: null,\n // The internal user-id in case it is of type INDIVIDUAL and a user\n // TODO: userId is deprecrated, use principalId instead\n userId: null,\n // url to the DAV-principal-resource\n url: null,\n // The cdav-library object\n dav: null,\n // Whether or not this principal represents a circle\n isCircle: false,\n // Whether or not this principal represents a user\n isUser: false,\n // Whether or not this principal represents a group\n isGroup: false,\n // Whether or not this principal represents a calendar-resource\n isCalendarResource: false,\n // Whether or not this principal represents a calendar-room\n isCalendarRoom: false,\n // The id of the principal without prefix. e.g. userId / groupId / etc.\n principalId: null,\n // The url of the default calendar for invitations\n scheduleDefaultCalendarUrl: null\n}, props);\n\n/**\r\n * converts a dav principal into a vuex object\r\n *\r\n * @param {object} dav cdav-library Principal object\r\n * @return {object}\r\n */\nconst mapDavToPrincipal = dav => {\n const id = btoa(encodeURI(dav.url));\n const calendarUserType = dav.calendarUserType;\n const principalScheme = dav.principalScheme;\n const emailAddress = dav.email;\n const displayname = dav.displayname;\n const scheduleDefaultCalendarUrl = dav.scheduleDefaultCalendarUrl;\n const isUser = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_USER);\n const isGroup = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_GROUP);\n const isCircle = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_CIRCLE);\n const isCalendarResource = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_CALENDAR_RESOURCE);\n const isCalendarRoom = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_CALENDAR_ROOM);\n let principalId = null;\n if (isUser) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_USER.length);\n } else if (isGroup) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_GROUP.length);\n } else if (isCircle) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_CIRCLE.length);\n } else if (isCalendarResource) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_CALENDAR_RESOURCE.length);\n } else if (isCalendarRoom) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_CALENDAR_ROOM.length);\n }\n const url = dav.principalUrl;\n const userId = dav.userId;\n return getDefaultPrincipalObject({\n id,\n calendarUserType,\n principalScheme,\n emailAddress,\n displayname,\n url,\n dav,\n isUser,\n isGroup,\n isCircle,\n isCalendarResource,\n isCalendarRoom,\n principalId,\n userId,\n scheduleDefaultCalendarUrl\n });\n};\nexport { getDefaultPrincipalObject, mapDavToPrincipal };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getWeekDayFromDate } from '../utils/recurrence.js';\nimport { getDateFromDateTimeValue } from '../utils/date.js';\n\n/**\r\n * Creates a complete recurrence-rule-object based on given props\r\n *\r\n * @param {object} props Recurrence-rule-object-props already provided\r\n * @return {object}\r\n */\nconst getDefaultRecurrenceRuleObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js recurrence-rule value\n recurrenceRuleValue: null,\n // The frequency of the recurrence-rule (DAILY, WEEKLY, ...)\n frequency: 'NONE',\n // The interval of the recurrence-rule, must be a positive integer\n interval: 1,\n // Positive integer if recurrence-rule limited by count, null otherwise\n count: null,\n // Date if recurrence-rule limited by date, null otherwise\n // We do not store a timezone here, since we only care about the date part\n until: null,\n // List of byDay components to limit/expand the recurrence-rule\n byDay: [],\n // List of byMonth components to limit/expand the recurrence-rule\n byMonth: [],\n // List of byMonthDay components to limit/expand the recurrence-rule\n byMonthDay: [],\n // A position to limit the recurrence-rule (e.g. -1 for last Friday)\n bySetPosition: null,\n // Whether or not the rule is not supported for editing\n isUnsupported: false\n }, props);\n};\n\n/**\r\n * Maps a calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapRecurrenceRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n switch (recurrenceRuleValue.frequency) {\n case 'DAILY':\n return mapDailyRuleValueToRecurrenceRuleObject(recurrenceRuleValue);\n case 'WEEKLY':\n return mapWeeklyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate);\n case 'MONTHLY':\n return mapMonthlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate);\n case 'YEARLY':\n return mapYearlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate);\n default:\n // SECONDLY, MINUTELY, HOURLY\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n isUnsupported: true\n });\n }\n};\nconst FORBIDDEN_BY_PARTS_DAILY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH', 'BYSETPOS'];\nconst FORBIDDEN_BY_PARTS_WEEKLY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH', 'BYSETPOS'];\nconst FORBIDDEN_BY_PARTS_MONTHLY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH'];\nconst FORBIDDEN_BY_PARTS_YEARLY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO'];\nconst SUPPORTED_BY_DAY_WEEKLY = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];\n\n/**\r\n * Get all numbers between start and end as strings\r\n *\r\n * @param {number} start Lower end of range\r\n * @param {number} end Upper end of range\r\n * @return {string[]}\r\n */\nconst getRangeAsStrings = (start, end) => {\n return Array.apply(null, Array(end - start + 1)).map((_, n) => n + start).map(s => s.toString());\n};\nconst SUPPORTED_BY_MONTHDAY_MONTHLY = getRangeAsStrings(1, 31);\nconst SUPPORTED_BY_MONTH_YEARLY = getRangeAsStrings(1, 12);\n\n/**\r\n * Maps a daily calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @return {object}\r\n */\nconst mapDailyRuleValueToRecurrenceRuleObject = recurrenceRuleValue => {\n /**\r\n * We only support DAILY rules without any by-parts in the editor.\r\n * If the recurrence-rule contains any by-parts, mark it as unsupported.\r\n */\n const isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_DAILY);\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n isUnsupported\n });\n};\n\n/**\r\n * Maps a weekly calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapWeeklyRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n /**\r\n * For WEEKLY recurrences, our editor only allows BYDAY\r\n *\r\n * As defined in RFC5545 3.3.10. Recurrence Rule:\r\n * > Each BYDAY value can also be preceded by a positive (+n) or\r\n * > negative (-n) integer. If present, this indicates the nth\r\n * > occurrence of a specific day within the MONTHLY or YEARLY \"RRULE\".\r\n *\r\n * RFC 5545 specifies other components, which can be used along WEEKLY.\r\n * Among them are BYMONTH and BYSETPOS. We don't support those.\r\n */\n const containsUnsupportedByParts = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_WEEKLY);\n const containsInvalidByDayPart = recurrenceRuleValue.getComponent('BYDAY').some(weekday => !SUPPORTED_BY_DAY_WEEKLY.includes(weekday));\n const isUnsupported = containsUnsupportedByParts || containsInvalidByDayPart;\n const byDay = recurrenceRuleValue.getComponent('BYDAY').filter(weekday => SUPPORTED_BY_DAY_WEEKLY.includes(weekday));\n\n // If the BYDAY is empty, add the day that the event occurs in\n // E.g. if the event is on a Wednesday, automatically set BYDAY:WE\n if (byDay.length === 0) {\n byDay.push(getWeekDayFromDate(baseDate.jsDate));\n }\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n byDay,\n isUnsupported\n });\n};\n\n/**\r\n * Maps a monthly calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapMonthlyRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n /**\r\n * We only supports BYMONTHDAY, BYDAY, BYSETPOS in order to expand the monthly rule.\r\n * It supports either BYMONTHDAY or the combination of BYDAY and BYSETPOS. They have to be used exclusively\r\n * and cannot be combined.\r\n *\r\n * We do not support other BY-parts like BYMONTH\r\n *\r\n * For monthly recurrence-rules, BYDAY components are allowed to be preceded by positive or negative integers.\r\n * The Nextcloud-editor supports at most one BYDAY component with an integer.\r\n * If it's presented with such a BYDAY component, it will internally be converted to BYDAY without integer and BYSETPOS.\r\n * e.g.\r\n * BYDAY=3WE => BYDAY=WE,BYSETPOS=3\r\n *\r\n * BYSETPOS is limited to -2, -1, 1, 2, 3, 4, 5\r\n * Other values are not supported\r\n *\r\n * BYDAY is limited to \"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\", \"SU\",\r\n * \"MO,TU,WE,TH,FR,SA,SU\", \"MO,TU,WE,TH,FR\", \"SA,SU\"\r\n *\r\n * BYMONTHDAY is limited to \"1\", \"2\", ..., \"31\"\r\n */\n let isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_MONTHLY);\n let byDay = [];\n let bySetPosition = null;\n let byMonthDay = [];\n\n // This handles the first case, where we have a BYMONTHDAY rule\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTHDAY'])) {\n // verify there is no BYDAY or BYSETPOS at the same time\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY', 'BYSETPOS'])) {\n isUnsupported = true;\n }\n const containsInvalidByMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY').some(monthDay => !SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay.toString()));\n isUnsupported = isUnsupported || containsInvalidByMonthDay;\n byMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY').filter(monthDay => SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay.toString())).map(monthDay => monthDay.toString());\n\n // This handles cases where we have both BYDAY and BYSETPOS\n } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY']) && containsRecurrenceComponent(recurrenceRuleValue, ['BYSETPOS'])) {\n if (isAllowedByDay(recurrenceRuleValue.getComponent('BYDAY'))) {\n byDay = recurrenceRuleValue.getComponent('BYDAY');\n } else {\n byDay = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];\n isUnsupported = true;\n }\n const setPositionArray = recurrenceRuleValue.getComponent('BYSETPOS');\n if (setPositionArray.length === 1 && isAllowedBySetPos(setPositionArray[0])) {\n bySetPosition = setPositionArray[0];\n } else {\n bySetPosition = 1;\n isUnsupported = true;\n }\n\n // This handles cases where we only have a BYDAY\n } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY'])) {\n const byDayArray = recurrenceRuleValue.getComponent('BYDAY');\n if (byDayArray.length > 1) {\n byMonthDay.push(baseDate.day.toString());\n isUnsupported = true;\n } else {\n const firstElement = byDayArray[0];\n const match = /^(-?\\d)([A-Z]{2})$/.exec(firstElement);\n if (match) {\n const matchedBySetPosition = match[1];\n const matchedByDay = match[2];\n if (isAllowedBySetPos(matchedBySetPosition)) {\n byDay = [matchedByDay];\n bySetPosition = parseInt(matchedBySetPosition, 10);\n } else {\n byDay = [matchedByDay];\n bySetPosition = 1;\n isUnsupported = true;\n }\n } else {\n byMonthDay.push(baseDate.day.toString());\n isUnsupported = true;\n }\n }\n\n // This is a fallback where we just default BYMONTHDAY to the start date of the event\n } else {\n byMonthDay.push(baseDate.day.toString());\n }\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n byDay,\n bySetPosition,\n byMonthDay,\n isUnsupported\n });\n};\n\n/**\r\n * Maps a yearly calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapYearlyRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n /**\r\n * We only supports BYMONTH, BYDAY, BYSETPOS in order to expand the yearly rule.\r\n * It supports a combination of them.\r\n *\r\n * We do not support other BY-parts.\r\n *\r\n * For yearly recurrence-rules, BYDAY components are allowed to be preceded by positive or negative integers.\r\n * The Nextcloud-editor supports at most one BYDAY component with an integer.\r\n * If it's presented with such a BYDAY component, it will internally be converted to BYDAY without integer and BYSETPOS.\r\n * e.g.\r\n * BYDAY=3WE => BYDAY=WE,BYSETPOS=3\r\n *\r\n * BYSETPOS is limited to -2, -1, 1, 2, 3, 4, 5\r\n * Other values are not supported\r\n *\r\n * BYDAY is limited to \"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\", \"SU\",\r\n * \"MO,TU,WE,TH,FR,SA,SU\", \"MO,TU,WE,TH,FR\", \"SA,SU\"\r\n */\n let isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_YEARLY);\n let byDay = [];\n let bySetPosition = null;\n let byMonth = [];\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTH'])) {\n const containsInvalidByMonthDay = recurrenceRuleValue.getComponent('BYMONTH').some(month => !SUPPORTED_BY_MONTH_YEARLY.includes(month.toString()));\n isUnsupported = isUnsupported || containsInvalidByMonthDay;\n byMonth = recurrenceRuleValue.getComponent('BYMONTH').filter(monthDay => SUPPORTED_BY_MONTH_YEARLY.includes(monthDay.toString())).map(month => month.toString());\n } else {\n byMonth.push(baseDate.month.toString());\n }\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY']) && containsRecurrenceComponent(recurrenceRuleValue, ['BYSETPOS'])) {\n if (isAllowedByDay(recurrenceRuleValue.getComponent('BYDAY'))) {\n byDay = recurrenceRuleValue.getComponent('BYDAY');\n } else {\n byDay = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];\n isUnsupported = true;\n }\n const setPositionArray = recurrenceRuleValue.getComponent('BYSETPOS');\n if (setPositionArray.length === 1 && isAllowedBySetPos(setPositionArray[0])) {\n bySetPosition = setPositionArray[0];\n } else {\n bySetPosition = 1;\n isUnsupported = true;\n }\n } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY'])) {\n const byDayArray = recurrenceRuleValue.getComponent('BYDAY');\n if (byDayArray.length > 1) {\n isUnsupported = true;\n } else {\n const firstElement = byDayArray[0];\n const match = /^(-?\\d)([A-Z]{2})$/.exec(firstElement);\n if (match) {\n const matchedBySetPosition = match[1];\n const matchedByDay = match[2];\n if (isAllowedBySetPos(matchedBySetPosition)) {\n byDay = [matchedByDay];\n bySetPosition = parseInt(matchedBySetPosition, 10);\n } else {\n byDay = [matchedByDay];\n bySetPosition = 1;\n isUnsupported = true;\n }\n } else {\n isUnsupported = true;\n }\n }\n }\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n byDay,\n bySetPosition,\n byMonth,\n isUnsupported\n });\n};\n\n/**\r\n * Checks if the given parameter is a supported BYDAY value\r\n *\r\n * @param {string[]} byDay The byDay component to check\r\n * @return {boolean}\r\n */\nconst isAllowedByDay = byDay => {\n return ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU', 'FR,MO,SA,SU,TH,TU,WE', 'FR,MO,TH,TU,WE', 'SA,SU'].includes(byDay.slice().sort().join(','));\n};\n\n/**\r\n * Checks if the given parameter is a supported BYSETPOS value\r\n *\r\n * @param {string} bySetPos The bySetPos component to check\r\n * @return {boolean}\r\n */\nconst isAllowedBySetPos = bySetPos => {\n return ['-2', '-1', '1', '2', '3', '4', '5'].includes(bySetPos.toString());\n};\n\n/**\r\n * Checks if the recurrence-rule contains any of the given components\r\n *\r\n * @param {RecurValue} recurrenceRule The recurrence-rule value to check for the given components\r\n * @param {string[]} components List of components to check for\r\n * @return {boolean}\r\n */\nconst containsRecurrenceComponent = (recurrenceRule, components) => {\n for (const component of components) {\n const componentValue = recurrenceRule.getComponent(component);\n if (componentValue.length > 0) {\n return true;\n }\n }\n return false;\n};\n\n/**\r\n * Returns a full recurrence-rule-object with default values derived from recurrenceRuleValue\r\n * and additional props\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The recurrence-rule value to get default values from\r\n * @param {object} props The properties to provide on top of default one\r\n * @return {object}\r\n */\nconst getDefaultRecurrenceRuleObjectForRecurrenceValue = (recurrenceRuleValue, props) => {\n const isUnsupported = recurrenceRuleValue.count !== null && recurrenceRuleValue.until !== null;\n let isUnsupportedProps = {};\n if (isUnsupported) {\n isUnsupportedProps = {\n isUnsupported\n };\n }\n return getDefaultRecurrenceRuleObject(Object.assign({}, {\n recurrenceRuleValue,\n frequency: recurrenceRuleValue.frequency,\n interval: parseInt(recurrenceRuleValue.interval, 10) || 1,\n count: recurrenceRuleValue.count,\n until: recurrenceRuleValue.until ? getDateFromDateTimeValue(recurrenceRuleValue.until) : null\n }, props, isUnsupportedProps));\n};\nexport { getDefaultRecurrenceRuleObject, mapRecurrenceRuleValueToRecurrenceRuleObject };","/**\r\n * @copyright 2022 Mikhail Sazanov \r\n *\r\n * @author 2022 Mikhail Sazanov \r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport axios from '@nextcloud/axios';\nimport { generateOcsUrl, generateRemoteUrl } from '@nextcloud/router';\nimport { showError, showSuccess } from '@nextcloud/dialogs';\nimport { translate as t } from '@nextcloud/l10n';\nimport { parseXML } from 'webdav';\n\n/**\r\n * Makes a share link for a given file or directory.\r\n *\r\n * @param {string} path The file path from the user's root directory. e.g. `/myfile.txt`\r\n * @return {string} url share link\r\n */\nconst shareFile = async function (path) {\n try {\n const res = await axios.post(generateOcsUrl('apps/files_sharing/api/v1/', 2) + 'shares', {\n shareType: OC.Share.SHARE_TYPE_LINK,\n path\n });\n return res.data.ocs.data;\n } catch (error) {\n var _error$response;\n if (error !== null && error !== void 0 && (_error$response = error.response) !== null && _error$response !== void 0 && (_error$response = _error$response.data) !== null && _error$response !== void 0 && (_error$response = _error$response.ocs) !== null && _error$response !== void 0 && (_error$response = _error$response.meta) !== null && _error$response !== void 0 && _error$response.message) {\n console.error(\"Error while sharing file: \".concat(error.response.data.ocs.meta.message));\n showError(error.response.data.ocs.meta.message);\n throw error;\n } else {\n console.error('Error while sharing file: Unknown error');\n showError(t('calendar', 'Error while sharing file'));\n throw error;\n }\n }\n};\n\n/**\r\n * Share file with a user with permissions\r\n *\r\n * @param path\r\n * @param sharedWith\r\n * @param permissions\r\n * @return {Promise<[{path: string, permissions, scope: string, name: string, backend: string, type: string},{path: string, permissions: *, scope: string, name: string, backend: string, type: string}]>}\r\n */\nconst shareFileWith = async function (path, sharedWith) {\n let permissions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 17;\n try {\n const url = generateOcsUrl('apps/files_sharing/api/v1/', 2);\n const res = await axios.post(\"\".concat(url, \"shares\"), {\n password: null,\n shareType: OC.Share.SHARE_TYPE_USER,\n // WITH USERS,\n permissions,\n // 14 - edit, 17 - view\n path,\n shareWith: sharedWith\n });\n return res.data.ocs.data;\n } catch (error) {\n var _error$response2;\n if (error !== null && error !== void 0 && (_error$response2 = error.response) !== null && _error$response2 !== void 0 && (_error$response2 = _error$response2.data) !== null && _error$response2 !== void 0 && (_error$response2 = _error$response2.ocs) !== null && _error$response2 !== void 0 && (_error$response2 = _error$response2.meta) !== null && _error$response2 !== void 0 && _error$response2.message) {\n console.error(\"Error while sharing file with user: \".concat(error.response.data.ocs.meta.message));\n showError(error.response.data.ocs.meta.message);\n throw error;\n } else {\n console.error('Error while sharing file with user: Unknown error');\n showError(t('calendar', 'Error while sharing file with user'));\n throw error;\n }\n }\n};\nconst createFolder = async function (folderName, userId) {\n const url = generateRemoteUrl(\"dav/files/\".concat(userId, \"/\").concat(folderName));\n try {\n await axios({\n method: 'MKCOL',\n url\n });\n } catch (e) {\n var _e$response;\n if ((e === null || e === void 0 || (_e$response = e.response) === null || _e$response === void 0 ? void 0 : _e$response.status) !== 405) {\n showError(t('calendar', 'Error creating a folder {folder}', {\n folder: folderName\n }));\n // Maybe the actual upload succeeds -> keep going\n return folderName;\n }\n\n // Folder already exists\n if (folderName !== '/') {\n folderName = await findFirstOwnedFolder(folderName, userId);\n }\n }\n return folderName;\n};\nconst findFirstOwnedFolder = async function (path, userId) {\n var _info$multistatus;\n const infoXml = await getFileInfo(path, userId);\n const info = await parseXML(infoXml);\n const mountType = info === null || info === void 0 || (_info$multistatus = info.multistatus) === null || _info$multistatus === void 0 || (_info$multistatus = _info$multistatus.response[0]) === null || _info$multistatus === void 0 || (_info$multistatus = _info$multistatus.propstat) === null || _info$multistatus === void 0 || (_info$multistatus = _info$multistatus.prop) === null || _info$multistatus === void 0 ? void 0 : _info$multistatus['mount-type'];\n if (mountType !== 'shared') {\n return path;\n }\n const hierarchy = path.split('/');\n hierarchy.pop();\n if (hierarchy.length === 1) {\n return '/';\n }\n return findFirstOwnedFolder(hierarchy.join('/'), userId);\n};\nconst uploadLocalAttachment = async function (folder, files, dav, componentAttachments) {\n const attachments = [];\n const promises = [];\n files.forEach(file => {\n // temp fix, until we decide where to save the attachments\n if (componentAttachments.map(attachment => attachment.fileName.split('/').pop()).indexOf(file.name) !== -1) {\n // TODO may be show user confirmation dialog to create a file named Existing_File_(2) ?\n showError(t('calendar', 'Attachment {fileName} already exists!', {\n fileName: file.name\n }));\n } else {\n const url = generateRemoteUrl(\"dav/files/\".concat(dav.userId, \"/\").concat(folder, \"/\").concat(file.name));\n const res = axios.put(url, file).then(resp => {\n const data = {\n fileName: file.name,\n formatType: file.type,\n uri: url,\n value: url,\n path: \"/\".concat(file.name)\n };\n if (resp.status === 204 || resp.status === 201) {\n showSuccess(t('calendar', 'Attachment {fileName} added!', {\n fileName: file.name\n }));\n attachments.push(data);\n }\n }).catch(() => {\n showError(t('calendar', 'An error occurred during uploading file {fileName}', {\n fileName: file.name\n }));\n });\n promises.push(res);\n }\n });\n await Promise.all(promises);\n return attachments;\n};\nconst uploadRemoteFile = async function (folder, fileUrl, fileName, dav) {\n try {\n // Télécharger le fichier distant\n const response = await axios.get(fileUrl, {\n responseType: 'blob'\n });\n\n // Envoyer le fichier récupéré en PUT vers WebDAV\n const url = generateRemoteUrl(\"dav/files/\".concat(dav.userId, \"/\").concat(folder, \"/\").concat(fileName));\n const uploadResponse = await axios.put(url, response.data, {\n headers: {\n 'Content-Type': response.data.type // Utilise le type MIME du fichier\n }\n });\n if (uploadResponse.status === 204 || uploadResponse.status === 201) {\n showSuccess(t('calendar', 'Attachment {fileName} added!', {\n fileName: fileName\n }));\n return {\n fileName: fileName,\n formatType: response.data.type,\n uri: url,\n value: url,\n path: \"/\".concat(fileName)\n };\n }\n } catch (error) {\n showError(t('calendar', 'An error occurred during uploading file {fileName}', {\n fileName: fileName\n }));\n return null;\n }\n};\n// TODO is shared or not @share-types@\nconst getFileInfo = async function (path, userId) {\n const url = generateRemoteUrl(\"dav/files/\".concat(userId, \"/\").concat(path));\n const res = await axios({\n method: 'PROPFIND',\n url,\n data: \"\\n\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\"\n }).catch(() => {\n showError(t('calendar', 'An error occurred during getting file information'));\n });\n return res.data;\n};\nexport { getFileInfo, shareFile, shareFileWith, uploadLocalAttachment, createFolder, uploadRemoteFile };","import axios from \"@nextcloud/axios\";\nimport { generateUrl } from \"@nextcloud/router\";\nexport default {\n async fetchAndCommitRoles(commit) {\n try {\n var url = '/apps/gestion/getUserConnectedGroups';\n const ajaxUrl = generateUrl(url);\n axios.get(ajaxUrl).then(response => {\n let roles = JSON.parse(response.data);\n commit(\"setUserRole\", roles);\n }).catch(error => {});\n } catch (error) {}\n }\n};","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport HttpClient from '@nextcloud/axios';\nimport { getLinkToConfig } from '../utils/settings.js';\n\n/**\r\n *\r\n * @param {string} key Config-key to set\r\n * @param {string | number | boolean} value Config-value to set\r\n * @return {Promise}\r\n */\nconst setConfig = async (key, value) => {\n await HttpClient.post(getLinkToConfig(key), {\n value\n });\n};\nexport { setConfig };","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n * @copyright Copyright (c) 2023 Jonas Heinrich\n *\n * @author Georg Ehrke \n * @author Jonas Heinrich \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 .\n *\n */\nimport Vue from 'vue';\nimport getTimezoneManager from '../services/timezoneDataProviderService.js';\nimport { getDateFromDateTimeValue } from '../utils/date.js';\nimport { AttendeeProperty, Property, DateTimeValue, DurationValue, RecurValue, AttachmentProperty, Parameter } from '@nextcloud/calendar-js';\nimport { getBySetPositionAndBySetFromDate, getWeekDayFromDate } from '../utils/recurrence.js';\nimport { copyCalendarObjectInstanceIntoEventComponent, getDefaultEventObject, mapEventComponentToEventObject } from '../models/event.js';\nimport { getAmountAndUnitForTimedEvents, getAmountHoursMinutesAndUnitForAllDayEvents, getTotalSecondsFromAmountAndUnitForTimedEvents, getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents, updateAlarms } from '../utils/alarms.js';\nimport { getClosestCSS3ColorNameForHex, getHexForColorName } from '../utils/color.js';\nimport { mapAlarmComponentToAlarmObject } from '../models/alarm.js';\nimport { getObjectAtRecurrenceId } from '../utils/calendarObject.js';\nimport logger from '../utils/logger.js';\nimport settings from './settings.js';\nimport { getRFCProperties } from '../models/rfcProps.js';\nimport { generateUrl } from '@nextcloud/router';\nimport { updateTalkParticipants } from '../services/talkService.js';\nconst state = {\n isNew: null,\n calendarObject: null,\n calendarObjectInstance: null,\n existingEvent: {\n objectId: null,\n recurrenceId: null\n }\n};\nconst mutations = {\n /**\n * Set a calendar-object-instance that will be opened in the editor (existing event)\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject The calendar-object currently being edited\n * @param {object} data.calendarObjectInstance The calendar-object-instance currently being edited\n * @param {string} data.objectId The objectId of the calendar-object\n * @param {number} data.recurrenceId The recurrence-id of the calendar-object-instance\n */\n setCalendarObjectInstanceForExistingEvent(state, _ref) {\n let {\n calendarObject,\n calendarObjectInstance,\n objectId,\n recurrenceId\n } = _ref;\n state.isNew = false;\n state.calendarObject = calendarObject;\n state.calendarObjectInstance = calendarObjectInstance;\n state.existingEvent.objectId = objectId;\n state.existingEvent.recurrenceId = recurrenceId;\n },\n /**\n * Set a calendar-object-instance that will be opened in the editor (new event)\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject The calendar-object currently being created\n * @param {object} data.calendarObjectInstance The calendar-object-instance currently being crated\n */\n setCalendarObjectInstanceForNewEvent(state, _ref2) {\n let {\n calendarObject,\n calendarObjectInstance\n } = _ref2;\n state.isNew = true;\n state.calendarObject = calendarObject;\n state.calendarObjectInstance = calendarObjectInstance;\n state.existingEvent.objectId = null;\n state.existingEvent.recurrenceId = null;\n },\n /**\n *\n * @param {object} state The Vuex state\n */\n resetCalendarObjectInstanceObjectIdAndRecurrenceId(state) {\n state.isNew = false;\n state.calendarObject = null;\n state.calendarObjectInstance = null;\n state.existingEvent.objectId = null;\n state.existingEvent.recurrenceId = null;\n },\n /**\n * Change the title of the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.title The new Title\n */\n changeTitle(state, _ref3) {\n let {\n calendarObjectInstance,\n title\n } = _ref3;\n calendarObjectInstance.eventComponent.title = title;\n calendarObjectInstance.title = title;\n },\n /**\n * Change the event's start\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {Date} data.startDate New start date to set\n */\n changeStartDate(state, _ref4) {\n let {\n calendarObjectInstance,\n startDate\n } = _ref4;\n calendarObjectInstance.eventComponent.startDate.year = startDate.getFullYear();\n calendarObjectInstance.eventComponent.startDate.month = startDate.getMonth() + 1;\n calendarObjectInstance.eventComponent.startDate.day = startDate.getDate();\n calendarObjectInstance.eventComponent.startDate.hour = startDate.getHours();\n calendarObjectInstance.eventComponent.startDate.minute = startDate.getMinutes();\n calendarObjectInstance.eventComponent.startDate.second = 0;\n const isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n const endDateObj = calendarObjectInstance.eventComponent.endDate.clone();\n const startDateObj = calendarObjectInstance.eventComponent.startDate.clone();\n if (isAllDay) {\n endDateObj.addDuration(DurationValue.fromSeconds(-1 * 60 * 60 * 24));\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(endDateObj.timezoneId);\n calendarObjectInstance.eventComponent.endDate = calendarObjectInstance.eventComponent.startDate.getInTimezone(timezone);\n calendarObjectInstance.endDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.endDate);\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n }\n } else {\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(endDateObj.timezoneId);\n calendarObjectInstance.eventComponent.endDate = calendarObjectInstance.eventComponent.startDate.getInTimezone(timezone);\n calendarObjectInstance.endDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.endDate);\n }\n }\n calendarObjectInstance.startDate = startDate;\n },\n /**\n * Change the timezone of the event's start\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.startTimezone New timezone to set for start\n */\n changeStartTimezone(state, _ref5) {\n let {\n calendarObjectInstance,\n startTimezone\n } = _ref5;\n const timezone = getTimezoneManager().getTimezoneForId(startTimezone);\n calendarObjectInstance.eventComponent.startDate.replaceTimezone(timezone);\n calendarObjectInstance.startTimezoneId = startTimezone;\n\n // Either both are floating or both have a timezone, but it can't be mixed\n if (startTimezone === 'floating' || calendarObjectInstance.endTimezoneId === 'floating') {\n calendarObjectInstance.eventComponent.endDate.replaceTimezone(timezone);\n calendarObjectInstance.endTimezoneId = startTimezone;\n }\n },\n /**\n * Change the event's end\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {Date} data.endDate New end date to set\n */\n changeEndDate(state, _ref6) {\n let {\n calendarObjectInstance,\n endDate\n } = _ref6;\n // If the event is using DURATION, endDate is dynamically generated.\n // In order to alter it, we need to explicitly set DTEND\n const endDateObject = calendarObjectInstance.eventComponent.endDate;\n calendarObjectInstance.eventComponent.endDate = endDateObject;\n calendarObjectInstance.eventComponent.endDate.year = endDate.getFullYear();\n calendarObjectInstance.eventComponent.endDate.month = endDate.getMonth() + 1;\n calendarObjectInstance.eventComponent.endDate.day = endDate.getDate();\n calendarObjectInstance.eventComponent.endDate.hour = endDate.getHours();\n calendarObjectInstance.eventComponent.endDate.minute = endDate.getMinutes();\n calendarObjectInstance.eventComponent.endDate.second = 0;\n const isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n const endDateObj = calendarObjectInstance.eventComponent.endDate.clone();\n const startDateObj = calendarObjectInstance.eventComponent.startDate.clone();\n if (isAllDay) {\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(startDateObj.timezoneId);\n calendarObjectInstance.eventComponent.startDate = calendarObjectInstance.eventComponent.endDate.getInTimezone(timezone);\n calendarObjectInstance.startDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.startDate);\n }\n\n // endDate is inclusive, but DTEND needs to be exclusive, so always add one day\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n } else {\n // Is end before start?\n if (endDateObj.compare(startDateObj) === -1) {\n // Is end more than one day before start?\n endDateObj.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(startDateObj.timezoneId);\n calendarObjectInstance.eventComponent.startDate = calendarObjectInstance.eventComponent.endDate.getInTimezone(timezone);\n calendarObjectInstance.startDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.startDate);\n } else {\n // add one day to endDate if the endDate is before the startDate which allows to easily create events that reach over or to 0:00\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n endDate = new Date(endDate.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n }\n calendarObjectInstance.endDate = endDate;\n },\n /**\n * Change the timezone of the event's end\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.endTimezone New timezone to set for end\n */\n changeEndTimezone(state, _ref7) {\n let {\n calendarObjectInstance,\n endTimezone\n } = _ref7;\n const timezone = getTimezoneManager().getTimezoneForId(endTimezone);\n calendarObjectInstance.eventComponent.endDate.replaceTimezone(timezone);\n calendarObjectInstance.endTimezoneId = endTimezone;\n\n // Either both are floating or both have a timezone, but it can't be mixed\n if (endTimezone === 'floating' || calendarObjectInstance.startTimezoneId === 'floating') {\n calendarObjectInstance.eventComponent.startDate.replaceTimezone(timezone);\n calendarObjectInstance.startTimezoneId = endTimezone;\n }\n },\n /**\n * Switch from a timed event to allday or vice versa\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n toggleAllDay(state, _ref8) {\n let {\n calendarObjectInstance\n } = _ref8;\n if (!calendarObjectInstance.eventComponent.canModifyAllDay()) {\n return;\n }\n const isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n calendarObjectInstance.eventComponent.startDate.isDate = !isAllDay;\n calendarObjectInstance.eventComponent.endDate.isDate = !isAllDay;\n calendarObjectInstance.isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n\n // isAllDay = old value\n if (isAllDay) {\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(-1 * 60 * 60 * 24));\n } else {\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n }\n },\n /**\n * Is private\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n toggleIsPrivate(state, _ref9) {\n let {\n calendarObjectInstance,\n isPrivate\n } = _ref9;\n calendarObjectInstance.eventComponent.isPrivate = isPrivate;\n calendarObjectInstance.isPrivate = isPrivate;\n },\n /**\n * Changes the time of a timed event to the default values\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n changeTimeToDefaultForTimedEvents(state, _ref10) {\n let {\n calendarObjectInstance\n } = _ref10;\n const startDate = calendarObjectInstance.eventComponent.startDate;\n const endDate = calendarObjectInstance.eventComponent.endDate;\n if (startDate.hour === 0 && startDate.minute === 0 && endDate.hour === 0 && endDate.minute === 0) {\n startDate.hour = 10;\n endDate.hour = 11;\n calendarObjectInstance.startDate = getDateFromDateTimeValue(startDate);\n calendarObjectInstance.endDate = getDateFromDateTimeValue(endDate);\n }\n },\n /**\n * Change the location of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.location New location to set\n */\n changeLocation(state, _ref11) {\n let {\n calendarObjectInstance,\n location\n } = _ref11;\n // Special case: delete Apple-specific location property to avoid inconsistencies\n calendarObjectInstance.eventComponent.deleteAllProperties('X-APPLE-STRUCTURED-LOCATION');\n calendarObjectInstance.eventComponent.location = location;\n calendarObjectInstance.location = location;\n },\n /**\n * Change the client of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.client New client to set\n */\n\n changeClient(state, _ref12) {\n let {\n calendarObjectInstance,\n client\n } = _ref12;\n calendarObjectInstance.eventComponent.client = client;\n calendarObjectInstance.client = client;\n },\n /**\n * Change the embalmer (Thanato) of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.embalmer New embalmer to set\n */\n\n changeEmbalmer(state, _ref13) {\n let {\n calendarObjectInstance,\n embalmer\n } = _ref13;\n calendarObjectInstance.eventComponent.embalmer = embalmer;\n calendarObjectInstance.embalmer = embalmer;\n },\n /**\n * Change the description of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.description New description to set\n */\n changeDescription(state, _ref14) {\n let {\n calendarObjectInstance,\n description\n } = _ref14;\n // To avoid inconsistencies (bug #3863), remove all parameters (e.g., ALTREP) upon modification\n const descriptionProperty = calendarObjectInstance.eventComponent.getFirstProperty('Description');\n if (descriptionProperty) {\n for (const parameter of descriptionProperty.getParametersIterator()) {\n descriptionProperty.deleteParameter(parameter.name);\n }\n }\n\n // Delete custom description properties\n calendarObjectInstance.eventComponent.deleteAllProperties('X-ALT-DESC');\n calendarObjectInstance.eventComponent.description = description;\n calendarObjectInstance.description = description;\n },\n /**\n * Change the access class of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.accessClass New access class to set\n */\n changeAccessClass(state, _ref15) {\n let {\n calendarObjectInstance,\n accessClass\n } = _ref15;\n calendarObjectInstance.eventComponent.accessClass = accessClass;\n calendarObjectInstance.accessClass = accessClass;\n },\n /**\n * Change the status of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.status New status to set\n */\n changeStatus(state, _ref16) {\n let {\n calendarObjectInstance,\n status\n } = _ref16;\n calendarObjectInstance.eventComponent.status = status;\n calendarObjectInstance.status = status;\n },\n /**\n * Change the time-transparency of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.timeTransparency New time-transparency to set\n */\n changeTimeTransparency(state, _ref17) {\n let {\n calendarObjectInstance,\n timeTransparency\n } = _ref17;\n calendarObjectInstance.eventComponent.timeTransparency = timeTransparency;\n calendarObjectInstance.timeTransparency = timeTransparency;\n },\n /**\n * Change the customized color of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string | null} data.customColor New color to set\n */\n changeCustomColor(state, _ref18) {\n let {\n calendarObjectInstance,\n customColor\n } = _ref18;\n if (customColor === null) {\n calendarObjectInstance.eventComponent.deleteAllProperties('COLOR');\n Vue.set(calendarObjectInstance, 'customColor', null);\n return;\n }\n const cssColorName = getClosestCSS3ColorNameForHex(customColor);\n const hexColorOfCssName = getHexForColorName(cssColorName);\n\n // Abort if either is undefined\n if (!cssColorName || !hexColorOfCssName) {\n console.error('Setting custom color failed');\n console.error('customColor: ', customColor);\n console.error('cssColorName: ', cssColorName);\n console.error('hexColorOfCssName: ', hexColorOfCssName);\n return;\n }\n calendarObjectInstance.eventComponent.color = cssColorName;\n Vue.set(calendarObjectInstance, 'customColor', hexColorOfCssName);\n },\n /**\n * Adds an attendee to the event and sets the organizer if not present already\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.commonName Displayname of attendee\n * @param {string} data.uri Email address of attendee\n * @param {string} data.calendarUserType Calendar-user-type of attendee (INDIVIDUAL, GROUP, RESOURCE, ROOM)\n * @param {string} data.participationStatus Participation Status of attendee\n * @param {string} data.role Role of Attendee\n * @param {boolean} data.rsvp Whether or not to request a response from the attendee\n * @param {string=} data.language Preferred language of the attendee\n * @param {string=} data.timezoneId Preferred timezone of the attendee\n * @param {object=} data.organizer Principal of the organizer to be set if not present\n * @param data.member\n */\n addAttendee(state, _ref19) {\n let {\n calendarObjectInstance,\n commonName,\n uri,\n calendarUserType = null,\n participationStatus = null,\n role = null,\n rsvp = null,\n language = null,\n timezoneId = null,\n organizer = null,\n member = null\n } = _ref19;\n const attendee = AttendeeProperty.fromNameAndEMail(commonName, uri);\n if (calendarUserType !== null) {\n attendee.userType = calendarUserType;\n }\n if (participationStatus !== null) {\n attendee.participationStatus = participationStatus;\n }\n if (role !== null) {\n attendee.role = role;\n }\n if (rsvp !== null) {\n attendee.rsvp = rsvp;\n }\n if (language !== null) {\n attendee.language = language;\n }\n if (timezoneId !== null) {\n attendee.updateParameterIfExist('TZID', timezoneId);\n }\n if (member !== null) {\n attendee.updateParameterIfExist('MEMBER', member);\n }\n\n // TODO - use real addAttendeeFrom method\n calendarObjectInstance.eventComponent.addProperty(attendee);\n calendarObjectInstance.attendees.push({\n commonName,\n participationStatus,\n role,\n rsvp,\n uri,\n attendeeProperty: attendee\n });\n if (!calendarObjectInstance.organizer && organizer) {\n this.commit('setOrganizer', {\n calendarObjectInstance,\n commonName: organizer.displayname,\n email: organizer.emailAddress\n });\n }\n },\n /**\n * Removes an attendee from the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.attendee The attendee object to remove\n */\n removeAttendee(state, _ref20) {\n let {\n calendarObjectInstance,\n attendee\n } = _ref20;\n calendarObjectInstance.eventComponent.removeAttendee(attendee.attendeeProperty);\n\n // Also remove members if attendee is a group\n if (attendee.attendeeProperty.userType === 'GROUP') {\n attendee.members.forEach(function (member) {\n calendarObjectInstance.eventComponent.removeAttendee(member.attendeeProperty);\n const index = calendarObjectInstance.attendees.indexOf(member);\n if (index !== -1) {\n calendarObjectInstance.attendees.splice(index, 1);\n }\n });\n }\n const index = calendarObjectInstance.attendees.indexOf(attendee);\n if (index !== -1) {\n calendarObjectInstance.attendees.splice(index, 1);\n }\n },\n /**\n * Changes an attendees' participation status\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.attendee The attendee object\n * @param {string} data.participationStatus New Participation Status of attendee\n */\n changeAttendeesParticipationStatus(state, _ref21) {\n let {\n attendee,\n participationStatus\n } = _ref21;\n attendee.attendeeProperty.participationStatus = participationStatus;\n attendee.participationStatus = participationStatus;\n },\n /**\n * Changes an attendees' role\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.attendee The attendee object\n * @param {string} data.role New role of attendee\n */\n changeAttendeesRole(state, _ref22) {\n let {\n attendee,\n role\n } = _ref22;\n attendee.attendeeProperty.role = role;\n attendee.role = role;\n },\n /**\n * Changes an attendees' RVSP\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.attendee The attendee object\n */\n toggleAttendeeRSVP(state, _ref23) {\n let {\n attendee\n } = _ref23;\n const oldRSVP = attendee.attendeeProperty.rsvp;\n attendee.attendeeProperty.rsvp = !oldRSVP;\n attendee.rsvp = !oldRSVP;\n },\n /**\n * Set the event's organizer\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string=} data.commonName Displayname of organizer\n * @param {string} data.email Email-address of organizer\n */\n setOrganizer(state, _ref24) {\n let {\n calendarObjectInstance,\n commonName = null,\n email\n } = _ref24;\n calendarObjectInstance.eventComponent.setOrganizerFromNameAndEMail(commonName, email);\n Vue.set(calendarObjectInstance, 'organizer', {});\n Vue.set(calendarObjectInstance.organizer, 'commonName', commonName);\n Vue.set(calendarObjectInstance.organizer, 'uri', email);\n Vue.set(calendarObjectInstance.organizer, 'attendeeProperty', calendarObjectInstance.eventComponent.getFirstProperty('ORGANIZER'));\n },\n /**\n * Adds a category to the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.category Category to add\n */\n addCategory(state, _ref25) {\n let {\n calendarObjectInstance,\n category\n } = _ref25;\n calendarObjectInstance.eventComponent.addCategory(category);\n calendarObjectInstance.categories.push(category);\n },\n /**\n * Removes a category from the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.category Category to remove\n */\n removeCategory(state, _ref26) {\n let {\n calendarObjectInstance,\n category\n } = _ref26;\n calendarObjectInstance.eventComponent.removeCategory(category);\n const index = calendarObjectInstance.categories.indexOf(category);\n if (index !== -1) {\n calendarObjectInstance.categories.splice(index, 1);\n }\n },\n /**\n * Change the interval of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.interval The new interval to set\n */\n changeRecurrenceInterval(state, _ref27) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n interval\n } = _ref27;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.interval = interval;\n recurrenceRule.interval = interval;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the frequency of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.frequency The new frequency to set\n */\n changeRecurrenceFrequency(state, _ref28) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n } = _ref28;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.frequency = frequency;\n recurrenceRule.frequency = frequency;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the count limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.count The new count to set\n */\n changeRecurrenceCount(state, _ref29) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n count\n } = _ref29;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.count = count;\n recurrenceRule.count = count;\n recurrenceRule.until = null;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {Date} data.until The new until to set\n */\n changeRecurrenceUntil(state, _ref30) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n until\n } = _ref30;\n if (recurrenceRule.recurrenceRuleValue) {\n // RFC 5545, setion 3.3.10: until must be in UTC if the start time is timezone-aware\n if (calendarObjectInstance.startTimezoneId !== 'floating') {\n recurrenceRule.recurrenceRuleValue.until = DateTimeValue.fromJSDate(until, {\n zone: 'utc'\n });\n } else {\n recurrenceRule.recurrenceRuleValue.until = DateTimeValue.fromJSDate(until);\n }\n recurrenceRule.until = until;\n recurrenceRule.count = null;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Changes the recurrence-rule to never end\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n changeRecurrenceToInfinite(state, _ref31) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref31;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setToInfinite();\n recurrenceRule.until = null;\n recurrenceRule.count = null;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n resetRecurrenceByParts(state, _ref32) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref32;\n if (recurrenceRule.recurrenceRuleValue) {\n const parts = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH', 'BYSETPOS'];\n for (const part of parts) {\n recurrenceRule.recurrenceRuleValue.setComponent(part, []);\n }\n Vue.set(recurrenceRule, 'byDay', []);\n Vue.set(recurrenceRule, 'byMonth', []);\n Vue.set(recurrenceRule, 'byMonthDay', []);\n Vue.set(recurrenceRule, 'bySetPosition', null);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForWeekly(state, _ref33) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref33;\n if (recurrenceRule.recurrenceRuleValue) {\n const byDay = getWeekDayFromDate(calendarObjectInstance.startDate);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', [byDay]);\n recurrenceRule.byDay.push(byDay);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForMonthly(state, _ref34) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref34;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonthDay = calendarObjectInstance.startDate.getDate().toString();\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTHDAY', [byMonthDay]);\n recurrenceRule.byMonthDay.push(byMonthDay);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForMonthlyBySetPosition(state, _ref35) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref35;\n if (recurrenceRule.recurrenceRuleValue) {\n const {\n byDay,\n bySetPosition\n } = getBySetPositionAndBySetFromDate(calendarObjectInstance.startDate);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', [byDay]);\n recurrenceRule.recurrenceRuleValue.setComponent('BYSETPOS', [bySetPosition]);\n recurrenceRule.byDay.push(byDay);\n recurrenceRule.bySetPosition = bySetPosition;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForYearly(state, _ref36) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref36;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonth = calendarObjectInstance.startDate.getMonth() + 1; // Javascript months are zero-based\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTH', [byMonth]);\n recurrenceRule.byMonth.push(byMonth);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byDay The new until to set\n */\n addByDayToRecurrenceRule(state, _ref37) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byDay\n } = _ref37;\n if (recurrenceRule.recurrenceRuleValue) {\n const byDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYDAY');\n const index = byDayList.indexOf(byDay);\n if (index === -1) {\n byDayList.push(byDay);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', byDayList);\n }\n const index2 = recurrenceRule.byDay.indexOf(byDay);\n if (index2 === -1) {\n recurrenceRule.byDay.push(byDay);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byDay The new until to set\n */\n removeByDayFromRecurrenceRule(state, _ref38) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byDay\n } = _ref38;\n if (recurrenceRule.recurrenceRuleValue) {\n const byDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYDAY');\n const index = byDayList.indexOf(byDay);\n if (index !== -1) {\n byDayList.splice(index, 1);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', byDayList);\n }\n const index2 = recurrenceRule.byDay.indexOf(byDay);\n if (index2 !== -1) {\n recurrenceRule.byDay.splice(index2, 1);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonthDay The new until to set\n */\n addByMonthDayToRecurrenceRule(state, _ref39) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonthDay\n } = _ref39;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonthDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTHDAY');\n const index = byMonthDayList.indexOf(byMonthDay);\n if (index === -1) {\n byMonthDayList.push(byMonthDay);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTHDAY', byMonthDayList);\n }\n const index2 = recurrenceRule.byMonthDay.indexOf(byMonthDay);\n if (index2 === -1) {\n recurrenceRule.byMonthDay.push(byMonthDay);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonthDay The new until to set\n */\n removeByMonthDayFromRecurrenceRule(state, _ref40) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonthDay\n } = _ref40;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonthDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTHDAY');\n const index = byMonthDayList.indexOf(byMonthDay);\n if (index !== -1) {\n byMonthDayList.splice(index, 1);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTHDAY', byMonthDayList);\n }\n const index2 = recurrenceRule.byMonthDay.indexOf(byMonthDay);\n if (index2 !== -1) {\n recurrenceRule.byMonthDay.splice(index2, 1);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonth The new until to set\n */\n addByMonthToRecurrenceRule(state, _ref41) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonth\n } = _ref41;\n if (recurrenceRule.recurrenceRuleValue) {\n console.debug('addByMonthToRecurrenceRule', byMonth);\n const byMonthList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTH');\n const index = byMonthList.indexOf(byMonth);\n if (index === -1) {\n byMonthList.push(byMonth);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTH', byMonthList);\n }\n const index2 = recurrenceRule.byMonth.indexOf(byMonth);\n if (index2 === -1) {\n recurrenceRule.byMonth.push(byMonth);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonth The new until to set\n */\n removeByMonthFromRecurrenceRule(state, _ref42) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonth\n } = _ref42;\n if (recurrenceRule.recurrenceRuleValue) {\n console.debug('removeByMonthFromRecurrenceRule', byMonth);\n const byMonthList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTH');\n const index = byMonthList.indexOf(byMonth);\n if (index !== -1) {\n byMonthList.splice(index, 1);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTH', byMonthList);\n }\n const index2 = recurrenceRule.byMonth.indexOf(byMonth);\n if (index2 !== -1) {\n recurrenceRule.byMonth.splice(index2, 1);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string[]} data.byDay The new until to set\n */\n changeRecurrenceByDay(state, _ref43) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byDay\n } = _ref43;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', byDay);\n Vue.set(recurrenceRule, 'byDay', byDay);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.bySetPosition The new until to set\n */\n changeRecurrenceBySetPosition(state, _ref44) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n bySetPosition\n } = _ref44;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setComponent('BYSETPOS', [bySetPosition]);\n Vue.set(recurrenceRule, 'bySetPosition', bySetPosition);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n unsetRecurrenceBySetPosition(state, _ref45) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref45;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setComponent('BYSETPOS', []);\n Vue.set(recurrenceRule, 'bySetPosition', null);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Remove the recurrence-rule from the calendarObjectInstance\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n removeRecurrenceRuleFromCalendarObjectInstance(state, _ref46) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref46;\n if (recurrenceRule.recurrenceRuleValue) {\n calendarObjectInstance.eventComponent.deleteAllProperties('RRULE');\n Vue.set(calendarObjectInstance, 'recurrenceRule', getDefaultEventObject().recurrenceRule);\n console.debug(calendarObjectInstance);\n console.debug(recurrenceRule);\n }\n },\n /**\n * Add a new recurrence-rule to the calendarObjectInstance\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n addRecurrenceRuleFromCalendarObjectInstance(state, _ref47) {\n let {\n calendarObjectInstance\n } = _ref47;\n const recurrenceValue = RecurValue.fromData({});\n const recurrenceProperty = new Property('RRULE', recurrenceValue);\n calendarObjectInstance.eventComponent.addProperty(recurrenceProperty);\n calendarObjectInstance.recurrenceRule.recurrenceRuleValue = recurrenceValue;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n markRecurrenceRuleAsSupported(state, _ref48) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref48;\n recurrenceRule.isUnsupported = false;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.type New type of alarm\n */\n changeAlarmType(state, _ref49) {\n let {\n calendarObjectInstance,\n alarm,\n type\n } = _ref49;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.action = type;\n alarm.type = type;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {number} data.amount New amount of timed event\n */\n changeAlarmAmountTimed(state, _ref50) {\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref50;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountAndUnitForTimedEvents(amount, alarm.relativeUnitTimed, alarm.relativeIsBefore);\n alarm.relativeAmountTimed = amount;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.unit New unit of timed event\n */\n changeAlarmUnitTimed(state, _ref51) {\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref51;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountAndUnitForTimedEvents(alarm.relativeAmountTimed, unit, alarm.relativeIsBefore);\n alarm.relativeUnitTimed = unit;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {number} data.amount New amount of all-day event\n */\n changeAlarmAmountAllDay(state, _ref52) {\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref52;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(amount, alarm.relativeHoursAllDay, alarm.relativeMinutesAllDay, alarm.relativeUnitAllDay);\n alarm.relativeAmountAllDay = amount;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.unit New Unit of all-day event\n */\n changeAlarmUnitAllDay(state, _ref53) {\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref53;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(alarm.relativeAmountAllDay, alarm.relativeHoursAllDay, alarm.relativeMinutesAllDay, unit);\n alarm.relativeUnitAllDay = unit;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {number} data.hours New Hour\n * @param {number} data.minutes New Minutes\n */\n changeAlarmHoursMinutesAllDay(state, _ref54) {\n let {\n calendarObjectInstance,\n alarm,\n hours,\n minutes\n } = _ref54;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(alarm.relativeAmountAllDay, hours, minutes, alarm.relativeUnitAllDay);\n alarm.relativeHoursAllDay = hours;\n alarm.relativeMinutesAllDay = minutes;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {Date} data.date New date object\n */\n changeAlarmAbsoluteDate(state, _ref55) {\n let {\n calendarObjectInstance,\n alarm,\n date\n } = _ref55;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.year = date.getFullYear();\n alarm.alarmComponent.trigger.value.month = date.getMonth() + 1;\n alarm.alarmComponent.trigger.value.day = date.getDate();\n alarm.alarmComponent.trigger.value.hour = date.getHours();\n alarm.alarmComponent.trigger.value.minute = date.getMinutes();\n alarm.alarmComponent.trigger.value.second = 0;\n alarm.absoluteDate = date;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.timezoneId New timezoneId\n */\n changeAlarmAbsoluteTimezoneId(state, _ref56) {\n let {\n calendarObjectInstance,\n alarm,\n timezoneId\n } = _ref56;\n if (alarm.alarmComponent) {\n const timezone = getTimezoneManager().getTimezoneForId(timezoneId);\n alarm.alarmComponent.trigger.value.replaceTimezone(timezone);\n alarm.absoluteTimezoneId = timezoneId;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n changeAlarmFromRelativeToAbsolute(state, _ref57) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref57;\n if (alarm.alarmComponent) {\n const triggerDateTime = calendarObjectInstance.eventComponent.startDate.clone();\n // The trigger of an alarm must be DATE-TIME, startDate can be either.\n triggerDateTime.isDate = false;\n triggerDateTime.addDuration(alarm.alarmComponent.trigger.value);\n alarm.alarmComponent.setTriggerFromAbsolute(triggerDateTime);\n alarm.absoluteDate = getDateFromDateTimeValue(alarm.alarmComponent.trigger.value);\n alarm.absoluteTimezoneId = alarm.alarmComponent.trigger.value.timezoneId;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n changeAlarmFromAbsoluteToRelative(state, _ref58) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref58;\n if (alarm.alarmComponent) {\n const duration = alarm.alarmComponent.trigger.value.subtractDateWithTimezone(calendarObjectInstance.eventComponent.startDate);\n alarm.alarmComponent.setTriggerFromRelative(duration);\n alarm.relativeIsBefore = alarm.alarmComponent.trigger.value.isNegative;\n alarm.relativeIsRelatedToStart = true;\n alarm.relativeTrigger = duration.totalSeconds;\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.alarm The alarm object\n */\n resetAlarmRelativeParts(state, _ref59) {\n let {\n alarm\n } = _ref59;\n alarm.relativeIsBefore = null;\n alarm.relativeIsRelatedToStart = null;\n alarm.relativeUnitTimed = null;\n alarm.relativeAmountTimed = null;\n alarm.relativeUnitAllDay = null;\n alarm.relativeAmountAllDay = null;\n alarm.relativeHoursAllDay = null;\n alarm.relativeMinutesAllDay = null;\n alarm.relativeTrigger = null;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.alarm The alarm object\n */\n resetAlarmAbsoluteParts(state, _ref60) {\n let {\n alarm\n } = _ref60;\n alarm.absoluteDate = null;\n alarm.absoluteTimezoneId = null;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n updateAlarmAllDayParts(state, _ref61) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref61;\n if (alarm.alarmComponent) {\n const totalSeconds = alarm.alarmComponent.trigger.value.totalSeconds;\n const allDayParts = getAmountHoursMinutesAndUnitForAllDayEvents(totalSeconds);\n alarm.relativeUnitAllDay = allDayParts.unit;\n alarm.relativeAmountAllDay = allDayParts.amount;\n alarm.relativeHoursAllDay = allDayParts.hours;\n alarm.relativeMinutesAllDay = allDayParts.minutes;\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n updateAlarmTimedParts(state, _ref62) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref62;\n if (alarm.alarmComponent) {\n const totalSeconds = alarm.alarmComponent.trigger.value.totalSeconds;\n const timedParts = getAmountAndUnitForTimedEvents(totalSeconds);\n alarm.relativeUnitTimed = timedParts.unit;\n alarm.relativeAmountTimed = timedParts.amount;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.type Type of alarm\n * @param {number} data.totalSeconds Total amount of seconds for new alarm\n */\n addAlarmToCalendarObjectInstance(state, _ref63) {\n let {\n calendarObjectInstance,\n type,\n totalSeconds\n } = _ref63;\n if (calendarObjectInstance.eventComponent) {\n const eventComponent = calendarObjectInstance.eventComponent;\n const duration = DurationValue.fromSeconds(totalSeconds);\n const alarmComponent = eventComponent.addRelativeAlarm(type, duration);\n const alarmObject = mapAlarmComponentToAlarmObject(alarmComponent);\n calendarObjectInstance.alarms.push(alarmObject);\n console.debug(alarmObject.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n removeAlarmFromCalendarObjectInstance(state, _ref64) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref64;\n if (alarm.alarmComponent) {\n calendarObjectInstance.eventComponent.removeAlarm(alarm.alarmComponent);\n const index = calendarObjectInstance.alarms.indexOf(alarm);\n if (index !== -1) {\n calendarObjectInstance.alarms.splice(index, 1);\n }\n }\n },\n /**\n * @deprecated\n * @param state\n * @param calendarObjectInstance.calendarObjectInstance\n * @param calendarObjectInstance\n * @param calendarObjectInstance.sharedData\n * @param sharedData\n */\n addAttachmentBySharedData(state, _ref65) {\n let {\n calendarObjectInstance,\n sharedData\n } = _ref65;\n const attachment = AttachmentProperty.fromLink(sharedData.url);\n const fileName = sharedData.fileName;\n\n // hot-fix needed temporary, becase calendar-js has no fileName get-setter\n const parameterFileName = new Parameter('FILENAME', fileName);\n // custom has-preview parameter from dav file\n const xNcHasPreview = new Parameter('X-NC-HAS-PREVIEW', sharedData['has-preview'].toString());\n // custom file id parameter from dav file\n const xNcFileId = new Parameter('X-NC-FILE-ID', sharedData.fileid.toString());\n // custom share-types parameter from dav file\n const xNcSharedTypes = new Parameter('X-NC-SHARED-TYPES', sharedData['share-types']['share-type'] ? sharedData['share-types']['share-type'].join(',') : '');\n attachment.setParameter(parameterFileName);\n attachment.setParameter(xNcFileId);\n attachment.setParameter(xNcHasPreview);\n attachment.setParameter(xNcSharedTypes);\n attachment.isNew = true;\n attachment.shareTypes = sharedData['share-types']['share-type'] ? sharedData['share-types']['share-type'].join(',') : '';\n attachment.fileName = fileName;\n attachment.xNcFileId = sharedData.fileid;\n attachment.xNcHasPreview = sharedData['has-preview'];\n attachment.formatType = sharedData.getcontenttype;\n attachment.uri = sharedData.url ? sharedData.url : generateUrl(\"/f/\".concat(sharedData.fileid));\n calendarObjectInstance.eventComponent.addProperty(attachment);\n calendarObjectInstance.attachments.push(attachment);\n\n // console.log(attachment)\n },\n addAttachmentWithProperty(state, _ref66) {\n var _ref67, _sharedData$shareTyp, _sharedData$shareTyp2, _sharedData$shareTyp3;\n let {\n calendarObjectInstance,\n sharedData\n } = _ref66;\n const attachment = {};\n const fileName = sharedData.fileName;\n attachment.isNew = true;\n attachment.shareTypes = (_ref67 = typeof (sharedData === null || sharedData === void 0 || (_sharedData$shareTyp = sharedData['share-types']) === null || _sharedData$shareTyp === void 0 ? void 0 : _sharedData$shareTyp['share-type']) === 'number' ? sharedData === null || sharedData === void 0 || (_sharedData$shareTyp2 = sharedData['share-types']) === null || _sharedData$shareTyp2 === void 0 || (_sharedData$shareTyp2 = _sharedData$shareTyp2['share-type']) === null || _sharedData$shareTyp2 === void 0 ? void 0 : _sharedData$shareTyp2.toString() : sharedData === null || sharedData === void 0 || (_sharedData$shareTyp3 = sharedData['share-types']) === null || _sharedData$shareTyp3 === void 0 || (_sharedData$shareTyp3 = _sharedData$shareTyp3['share-type']) === null || _sharedData$shareTyp3 === void 0 ? void 0 : _sharedData$shareTyp3.join(',')) !== null && _ref67 !== void 0 ? _ref67 : null;\n attachment.fileName = fileName;\n attachment.xNcFileId = sharedData.fileid;\n attachment.xNcHasPreview = sharedData['has-preview'];\n attachment.formatType = sharedData.getcontenttype;\n attachment.uri = sharedData.url ? sharedData.url : generateUrl(\"/f/\".concat(sharedData.fileid));\n const attachmentProperty = AttachmentProperty.fromLink(attachment.uri, attachment.formatType);\n const parameterFileName = new Parameter('FILENAME', fileName);\n const xNcHasPreview = new Parameter('X-NC-HAS-PREVIEW', attachment.xNcHasPreview.toString());\n const xNcFileId = new Parameter('X-NC-FILE-ID', attachment.xNcFileId.toString());\n // ADD X-NC-SHARED-TYPES only if sharet-type not empty\n if (attachment.shareTypes !== null) {\n const xNcSharedTypes = new Parameter('X-NC-SHARED-TYPES', attachment.shareTypes);\n attachmentProperty.setParameter(xNcSharedTypes);\n }\n attachmentProperty.setParameter(parameterFileName);\n attachmentProperty.setParameter(xNcFileId);\n attachmentProperty.setParameter(xNcHasPreview);\n attachmentProperty.uri = attachment.uri;\n attachment.attachmentProperty = attachmentProperty;\n calendarObjectInstance.eventComponent.addProperty(attachmentProperty);\n calendarObjectInstance.attachments.push(attachment);\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.attachment The attachment object\n */\n deleteAttachment(state, _ref68) {\n let {\n calendarObjectInstance,\n attachment\n } = _ref68;\n try {\n const index = calendarObjectInstance.attachments.indexOf(attachment);\n if (index !== -1) {\n calendarObjectInstance.attachments.splice(index, 1);\n }\n calendarObjectInstance.eventComponent.removeAttachment(attachment.attachmentProperty);\n } catch {}\n }\n};\nconst getters = {};\nconst actions = {\n /**\n * Returns the closest existing recurrence-id of a calendar-object\n * close to the given date.\n * This is either the next occurrence in the future or\n * in case there are no more future occurrences the closest\n * occurrence in the past\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {string} data.objectId The objectId of the calendar-object to edit\n * @param {Date} data.closeToDate The date to get a close occurrence to\n * @return {Promise}\n */\n async resolveClosestRecurrenceIdForCalendarObject(_ref69, _ref70) {\n let {\n state,\n dispatch,\n commit\n } = _ref69;\n let {\n objectId,\n closeToDate\n } = _ref70;\n const calendarObject = await dispatch('getEventByObjectId', {\n objectId\n });\n const iterator = calendarObject.calendarComponent.getVObjectIterator();\n const firstVObject = iterator.next().value;\n const d = DateTimeValue.fromJSDate(closeToDate, true);\n return firstVObject.recurrenceManager.getClosestOccurrence(d).getReferenceRecurrenceId().unixTime;\n },\n /**\n * Gets the calendar-object and calendar-object-instance\n * for a given objectId and recurrenceId.\n *\n * If the recurrenceId does not represent a valid instance,\n * an error will be thrown.\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {string} data.objectId The objectId of the calendar-object to edit\n * @param {number} data.recurrenceId The recurrence-id to edit\n * @return {Promise<{calendarObject: object, calendarObjectInstance: object}>}\n */\n async getCalendarObjectInstanceByObjectIdAndRecurrenceId(_ref71, _ref72) {\n let {\n state,\n dispatch,\n commit\n } = _ref71;\n let {\n objectId,\n recurrenceId\n } = _ref72;\n if (state.existingEvent.objectId === objectId && state.existingEvent.recurrenceId === recurrenceId) {\n return Promise.resolve({\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n });\n }\n const recurrenceIdDate = new Date(recurrenceId * 1000);\n const calendarObject = await dispatch('getEventByObjectId', {\n objectId\n });\n const eventComponent = getObjectAtRecurrenceId(calendarObject, recurrenceIdDate);\n if (eventComponent === null) {\n throw new Error('Not a valid recurrence-id');\n }\n const calendarObjectInstance = mapEventComponentToEventObject(eventComponent);\n commit('setCalendarObjectInstanceForExistingEvent', {\n calendarObject,\n calendarObjectInstance,\n objectId,\n recurrenceId\n });\n return {\n calendarObject,\n calendarObjectInstance\n };\n },\n /**\n * Gets the new calendar-object-instance.\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.isAllDay Whether or not the new event is supposed to be all-day\n * @param {number} data.start The start of the new event (unixtime)\n * @param {number} data.end The end of the new event (unixtime)\n * @param {string} data.timezoneId The timezoneId of the new event\n * @return {Promise<{calendarObject: object, calendarObjectInstance: object}>}\n */\n async getCalendarObjectInstanceForNewEvent(_ref73, _ref74) {\n let {\n state,\n dispatch,\n commit\n } = _ref73;\n let {\n isAllDay,\n start,\n end,\n timezoneId\n } = _ref74;\n if (state.isNew === true) {\n return Promise.resolve({\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n });\n }\n const calendarObject = await dispatch('createNewEvent', {\n start,\n end,\n isAllDay,\n timezoneId\n });\n const startDate = new Date(start * 1000);\n const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate);\n const calendarObjectInstance = mapEventComponentToEventObject(eventComponent);\n\n // Add an alarm if the user set a default one in the settings. If\n // not, defaultReminder will not be a number (rather the string \"none\").\n const defaultReminder = parseInt(settings.state.defaultReminder);\n if (!isNaN(defaultReminder)) {\n commit('addAlarmToCalendarObjectInstance', {\n calendarObjectInstance,\n type: 'DISPLAY',\n totalSeconds: defaultReminder\n });\n logger.debug(\"Added defaultReminder (\".concat(defaultReminder, \"s) to newly created event\"));\n }\n\n // Add default status\n const rfcProps = getRFCProperties();\n const status = rfcProps.status.defaultValue;\n commit('changeStatus', {\n calendarObjectInstance,\n status\n });\n commit('setCalendarObjectInstanceForNewEvent', {\n calendarObject,\n calendarObjectInstance\n });\n return {\n calendarObject,\n calendarObjectInstance\n };\n },\n /**\n * Updates the existing calendar-object-instance.\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.isAllDay Whether or not the new event is supposed to be all-day\n * @param {number} data.start The start of the new event (unixtime)\n * @param {number} data.end The end of the new event (unixtime)\n * @param {string} data.timezoneId The timezoneId of the new event\n * @return {Promise<{calendarObject: object, calendarObjectInstance: object}>}\n */\n async updateCalendarObjectInstanceForNewEvent(_ref75, _ref76) {\n let {\n state,\n dispatch,\n commit\n } = _ref75;\n let {\n isAllDay,\n start,\n end,\n timezoneId\n } = _ref76;\n await dispatch('updateTimeOfNewEvent', {\n calendarObjectInstance: state.calendarObjectInstance,\n start,\n end,\n isAllDay,\n timezoneId\n });\n commit('setCalendarObjectInstanceForNewEvent', {\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n });\n return {\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n };\n },\n /**\n * Saves changes made to a single calendar-object-instance\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.thisAndAllFuture Whether or not to save changes for all future occurrences or just this one\n * @param {string} data.calendarId The new calendar-id to store it in\n * @return {Promise}\n */\n async saveCalendarObjectInstance(_ref77, _ref78) {\n let {\n state,\n dispatch,\n commit\n } = _ref77;\n let {\n thisAndAllFuture,\n calendarId\n } = _ref78;\n const eventComponent = state.calendarObjectInstance.eventComponent;\n const calendarObject = state.calendarObject;\n updateAlarms(eventComponent);\n updateTalkParticipants(eventComponent);\n let additionalFieldWasUpdated = eventComponent.isPrivate != null || eventComponent.client != null;\n if (eventComponent.isDirty() || additionalFieldWasUpdated) {\n const isForkedItem = eventComponent.primaryItem !== null;\n let original = null;\n let fork = null;\n\n // We check if two things apply:\n // - primaryItem !== null -> Is this a fork or not?\n // - eventComponent.canCreateRecurrenceExceptions() - Can we create a recurrence-exception for this item\n if (isForkedItem && eventComponent.canCreateRecurrenceExceptions()) {\n [original, fork] = eventComponent.createRecurrenceException(thisAndAllFuture);\n }\n await dispatch('updateCalendarObject', {\n calendarObject\n });\n if (original !== null && fork !== null && original.root !== fork.root) {\n await dispatch('createCalendarObjectFromFork', {\n eventComponent: fork,\n calendarId\n });\n }\n }\n if (calendarId !== state.calendarObject.calendarId) {\n await dispatch('moveCalendarObject', {\n calendarObject,\n newCalendarId: calendarId\n });\n }\n },\n /**\n * Duplicate calendar-object-instance\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @return {Promise}\n */\n async duplicateCalendarObjectInstance(_ref79) {\n let {\n state,\n dispatch,\n commit\n } = _ref79;\n const oldCalendarObjectInstance = state.calendarObjectInstance;\n const oldEventComponent = oldCalendarObjectInstance.eventComponent;\n const startDate = oldEventComponent.startDate.getInUTC();\n const endDate = oldEventComponent.endDate.getInUTC();\n const calendarObject = await dispatch('createNewEvent', {\n start: startDate.unixTime,\n end: endDate.unixTime,\n timezoneId: oldEventComponent.startDate.timezoneId,\n isAllDay: oldEventComponent.isAllDay()\n });\n const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate.jsDate);\n copyCalendarObjectInstanceIntoEventComponent(oldCalendarObjectInstance, eventComponent);\n const calendarObjectInstance = mapEventComponentToEventObject(eventComponent);\n await commit('setCalendarObjectInstanceForNewEvent', {\n calendarObject,\n calendarObjectInstance\n });\n },\n /**\n * Deletes a calendar-object-instance\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.thisAndAllFuture Whether or not to delete all future occurrences or just this one\n * @return {Promise}\n */\n async deleteCalendarObjectInstance(_ref80, _ref81) {\n let {\n state,\n dispatch,\n commit\n } = _ref80;\n let {\n thisAndAllFuture\n } = _ref81;\n const eventComponent = state.calendarObjectInstance.eventComponent;\n const isRecurrenceSetEmpty = eventComponent.removeThisOccurrence(thisAndAllFuture);\n const calendarObject = state.calendarObject;\n if (isRecurrenceSetEmpty) {\n await dispatch('deleteCalendarObject', {\n calendarObject\n });\n } else {\n await dispatch('updateCalendarObject', {\n calendarObject\n });\n }\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {Date} data2.startDate The new start-date\n */\n changeStartDate(_ref82, _ref83) {\n let {\n commit\n } = _ref82;\n let {\n calendarObjectInstance,\n startDate\n } = _ref83;\n const difference = startDate.getTime() - calendarObjectInstance.startDate.getTime();\n const endDate = new Date(calendarObjectInstance.endDate.getTime() + difference);\n commit('changeStartDate', {\n calendarObjectInstance,\n startDate\n });\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate\n });\n },\n /**\n * Change the timezone of the event's start\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data2.startTimezone New timezone to set for start\n */\n changeStartTimezone(_ref84, _ref85) {\n let {\n commit\n } = _ref84;\n let {\n calendarObjectInstance,\n startTimezone\n } = _ref85;\n commit('changeStartTimezone', {\n calendarObjectInstance,\n startTimezone\n });\n\n // Simulate a change of the start time to trigger the comparison\n // of start and end and trigger an update of end if necessary\n commit('changeStartDate', {\n calendarObjectInstance,\n startDate: calendarObjectInstance.startDate\n });\n },\n /**\n * Change the timezone of the event's end\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data2.endTimezone New timezone to set for end\n */\n changeEndTimezone(_ref86, _ref87) {\n let {\n commit\n } = _ref86;\n let {\n calendarObjectInstance,\n endTimezone\n } = _ref87;\n commit('changeEndTimezone', {\n calendarObjectInstance,\n endTimezone\n });\n\n // Simulate a change of the end time to trigger the comparison\n // of start and end and trigger an update of start if necessary\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate: calendarObjectInstance.endDate\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {Function} data.dispatch The Vuex dispatch function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n * @param {string} data2.frequency The new frequency to set\n */\n changeRecurrenceFrequency(_ref88, _ref89) {\n let {\n commit,\n dispatch\n } = _ref88;\n let {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n } = _ref89;\n console.debug(calendarObjectInstance);\n console.debug(recurrenceRule);\n console.debug(frequency);\n if (recurrenceRule.frequency === 'NONE' && frequency !== 'NONE') {\n // Add a new recurrence-rule\n commit('addRecurrenceRuleFromCalendarObjectInstance', {\n calendarObjectInstance\n });\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceFrequency', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule,\n frequency\n });\n commit('changeRecurrenceInterval', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule,\n interval: 1\n });\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule\n });\n dispatch('setDefaultRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n });\n console.debug(\"changed from none to \".concat(frequency));\n } else if (recurrenceRule.frequency !== 'NONE' && frequency === 'NONE') {\n console.debug('calling removeRecurrenceRuleFromCalendarObjectInstance');\n // Remove the recurrence-rule\n commit('removeRecurrenceRuleFromCalendarObjectInstance', {\n calendarObjectInstance,\n recurrenceRule\n });\n } else {\n // Change frequency of existing recurrence-rule\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceFrequency', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule,\n frequency\n });\n dispatch('setDefaultRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n });\n }\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n * @param {string} data2.frequency The new frequency to set\n */\n setDefaultRecurrenceByParts(_ref90, _ref91) {\n let {\n commit\n } = _ref90;\n let {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n } = _ref91;\n switch (frequency) {\n case 'WEEKLY':\n commit('setDefaultRecurrenceByPartsForWeekly', {\n calendarObjectInstance,\n recurrenceRule\n });\n break;\n case 'MONTHLY':\n commit('setDefaultRecurrenceByPartsForMonthly', {\n calendarObjectInstance,\n recurrenceRule\n });\n break;\n case 'YEARLY':\n commit('setDefaultRecurrenceByPartsForYearly', {\n calendarObjectInstance,\n recurrenceRule\n });\n break;\n }\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n setRecurrenceToInfinite(_ref92, _ref93) {\n let {\n commit\n } = _ref92;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref93;\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n changeMonthlyRecurrenceFromByDayToBySetPosition(_ref94, _ref95) {\n let {\n commit\n } = _ref94;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref95;\n console.debug('changeMonthlyRecurrenceFromByDayToBySetPosition');\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('setDefaultRecurrenceByPartsForMonthlyBySetPosition', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n changeMonthlyRecurrenceFromBySetPositionToByDay(_ref96, _ref97) {\n let {\n commit\n } = _ref96;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref97;\n console.debug('changeMonthlyRecurrenceFromBySetPositionToByDay');\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('setDefaultRecurrenceByPartsForMonthly', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n enableYearlyRecurrenceBySetPosition(_ref98, _ref99) {\n let {\n commit\n } = _ref98;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref99;\n commit('setDefaultRecurrenceByPartsForMonthlyBySetPosition', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n disableYearlyRecurrenceBySetPosition(_ref100, _ref101) {\n let {\n commit\n } = _ref100;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref101;\n commit('changeRecurrenceByDay', {\n calendarObjectInstance,\n recurrenceRule,\n byDay: []\n });\n commit('unsetRecurrenceBySetPosition', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n enableRecurrenceLimitByUntil(_ref102, _ref103) {\n let {\n commit\n } = _ref102;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref103;\n let until;\n switch (recurrenceRule.frequency) {\n // Defaults to 7 days\n case 'DAILY':\n until = new Date(calendarObjectInstance.startDate.getTime() + 7 * 24 * 60 * 60 * 1000);\n break;\n\n // Defaults to 4 weeks\n case 'WEEKLY':\n until = new Date(calendarObjectInstance.startDate.getTime() + 4 * 7 * 24 * 60 * 60 * 1000);\n break;\n\n // Defaults to 10 year\n case 'YEARLY':\n until = new Date(calendarObjectInstance.startDate.getFullYear() + 10, calendarObjectInstance.startDate.getMonth(), calendarObjectInstance.startDate.getDate(), 23, 59, 59);\n break;\n\n // Defaults to 12 months\n case 'MONTHLY':\n default:\n until = new Date(calendarObjectInstance.startDate.getFullYear() + 1, calendarObjectInstance.startDate.getMonth(), calendarObjectInstance.startDate.getDate(), 23, 59, 59);\n break;\n }\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceUntil', {\n calendarObjectInstance,\n recurrenceRule,\n until\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n enableRecurrenceLimitByCount(_ref104, _ref105) {\n let {\n commit\n } = _ref104;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref105;\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceCount', {\n calendarObjectInstance,\n recurrenceRule,\n count: 2 // Default value is two\n });\n },\n changeAlarmAmountTimed(_ref106, _ref107) {\n let {\n commit\n } = _ref106;\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref107;\n commit('changeAlarmAmountTimed', {\n calendarObjectInstance,\n alarm,\n amount\n });\n commit('updateAlarmAllDayParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmUnitTimed(_ref108, _ref109) {\n let {\n commit\n } = _ref108;\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref109;\n commit('changeAlarmUnitTimed', {\n calendarObjectInstance,\n alarm,\n unit\n });\n commit('updateAlarmAllDayParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmAmountAllDay(_ref110, _ref111) {\n let {\n commit\n } = _ref110;\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref111;\n commit('changeAlarmAmountAllDay', {\n calendarObjectInstance,\n alarm,\n amount\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmUnitAllDay(_ref112, _ref113) {\n let {\n commit\n } = _ref112;\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref113;\n commit('changeAlarmUnitAllDay', {\n calendarObjectInstance,\n alarm,\n unit\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmHoursMinutesAllDay(_ref114, _ref115) {\n let {\n commit\n } = _ref114;\n let {\n calendarObjectInstance,\n alarm,\n hours,\n minutes\n } = _ref115;\n commit('changeAlarmHoursMinutesAllDay', {\n calendarObjectInstance,\n alarm,\n hours,\n minutes\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmFromRelativeToAbsolute(_ref116, _ref117) {\n let {\n commit\n } = _ref116;\n let {\n calendarObjectInstance,\n alarm\n } = _ref117;\n commit('changeAlarmFromRelativeToAbsolute', {\n calendarObjectInstance,\n alarm\n });\n commit('resetAlarmRelativeParts', {\n alarm\n });\n },\n changeAlarmFromAbsoluteToRelative(_ref118, _ref119) {\n let {\n commit\n } = _ref118;\n let {\n calendarObjectInstance,\n alarm\n } = _ref119;\n commit('changeAlarmFromAbsoluteToRelative', {\n calendarObjectInstance,\n alarm\n });\n commit('updateAlarmAllDayParts', {\n calendarObjectInstance,\n alarm\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n commit('resetAlarmAbsoluteParts', {\n alarm\n });\n },\n toggleAllDay(_ref120, _ref121) {\n let {\n commit,\n getters\n } = _ref120;\n let {\n calendarObjectInstance\n } = _ref121;\n commit('toggleAllDay', {\n calendarObjectInstance\n });\n if (!calendarObjectInstance.isAllDay) {\n if (calendarObjectInstance.startTimezoneId === 'floating') {\n const startTimezone = getters.getResolvedTimezone;\n commit('changeStartTimezone', {\n calendarObjectInstance,\n startTimezone\n });\n }\n commit('changeTimeToDefaultForTimedEvents', {\n calendarObjectInstance\n });\n }\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke \n *\n * @author John Molakvoæ \n *\n * @author Thomas Citharel \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 .\n *\n */\nimport Vue from 'vue';\nimport { mapCalendarJsToCalendarObject, setClientValueToIcsAndReturnIcs, setCustomKeyValuesArrayToIcsAndReturnIcs } from '../models/calendarObject.js';\nimport logger from '../utils/logger.js';\nimport { createEvent, getParserManager, getTimezoneManager, DateTimeValue } from '@nextcloud/calendar-js';\nconst state = {\n calendarObjects: {},\n modificationCount: 0\n};\nconst mutations = {\n /**\n * Adds an array of calendar-objects to the store\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object[]} data.calendarObjects Calendar-objects to add\n */\n appendCalendarObjects(state, _ref) {\n let {\n calendarObjects = []\n } = _ref;\n for (const calendarObject of calendarObjects) {\n if (!state.calendarObjects[calendarObject.id]) {\n Vue.set(state.calendarObjects, calendarObject.id, calendarObject);\n }\n }\n },\n /**\n * Adds one calendar-object to the store\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to add\n */\n appendCalendarObject(state, _ref2) {\n let {\n calendarObject\n } = _ref2;\n if (!state.calendarObjects[calendarObject.id]) {\n Vue.set(state.calendarObjects, calendarObject.id, calendarObject);\n }\n },\n /**\n * Updates a calendar-object id\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to update\n */\n updateCalendarObjectId(state, _ref3) {\n let {\n calendarObject\n } = _ref3;\n if (calendarObject.dav === null) {\n calendarObject.id = null;\n } else {\n calendarObject.id = btoa(calendarObject.dav.url);\n }\n },\n /**\n * Updates a calendar-object's calendarId\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {string} data.calendarObjectId Id of calendar-object to update\n * @param {string} data.calendarId New calendarId\n */\n updateCalendarObjectIdCalendarId(state, _ref4) {\n let {\n calendarObjectId,\n calendarId\n } = _ref4;\n state.calendarObjects[calendarObjectId].calendarId = calendarId;\n },\n /**\n * Resets a calendar-object to it's original server state\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to reset\n */\n resetCalendarObjectToDav(state, _ref5) {\n let {\n calendarObject\n } = _ref5;\n calendarObject = state.calendarObjects[calendarObject.id];\n\n // If this object does not exist on the server yet, there is nothing to do\n if (!calendarObject || !calendarObject.existsOnServer) {\n return;\n }\n const parserManager = getParserManager();\n const parser = parserManager.getParserForFileType('text/calendar');\n parser.parse(calendarObject.dav.data);\n const itemIterator = parser.getItemIterator();\n const firstVCalendar = itemIterator.next().value;\n if (firstVCalendar) {\n calendarObject.calendarComponent = firstVCalendar;\n }\n },\n /**\n * Removes a calendar-object from the store\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to delete\n */\n deleteCalendarObject(state, _ref6) {\n let {\n calendarObject\n } = _ref6;\n Vue.delete(state.calendarObjects, calendarObject.id);\n },\n /**\n * Increments the modification count\n *\n * @param {object} state The store data\n */\n incrementModificationCount(state) {\n state.modificationCount++;\n }\n};\nconst getters = {\n /**\n * Gets a calendar-object based on its id\n *\n * @param {object} state The store data\n * @return {function({String}): CalendarObject}\n */\n getCalendarObjectById: state => id => state.calendarObjects[id]\n};\nconst actions = {\n /**\n * Moves a calendar-object to a different calendar\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {CalendarObject} data.calendarObject Calendar-object to delete\n * @param {string} data.newCalendarId Calendar-Id of calendar to move this calendar-object to\n * @return {Promise}\n */\n async moveCalendarObject(context, _ref7) {\n let {\n calendarObject,\n newCalendarId\n } = _ref7;\n if (!calendarObject.existsOnServer) {\n return;\n }\n const oldCalendarObjectId = calendarObject.id;\n const oldCalendarId = calendarObject.calendarId;\n if (oldCalendarId === newCalendarId) {\n logger.error('Old calendar Id and new calendar Id are the same, nothing to move …');\n return;\n }\n const newCalendar = context.getters.getCalendarById(newCalendarId);\n if (!newCalendar) {\n logger.error('Calendar to move to not found, aborting …');\n return;\n }\n await calendarObject.dav.move(newCalendar.dav);\n // Update calendarId in calendarObject manually as it is not stored in dav\n context.commit('updateCalendarObjectIdCalendarId', {\n calendarObjectId: calendarObject.id,\n calendarId: newCalendarId\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: newCalendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: newCalendarId,\n calendarObjectId: calendarObject.id\n });\n context.commit('deleteCalendarObjectFromCalendar', {\n calendar: {\n id: oldCalendarId\n },\n calendarObjectId: oldCalendarObjectId\n });\n context.commit('removeCalendarObjectIdFromAllTimeRangesOfCalendar', {\n calendarId: oldCalendarId,\n calendarObjectId: oldCalendarObjectId\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Updates a calendar-object\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {CalendarObject} data.calendarObject Calendar-object to delete\n * @return {Promise}\n */\n async updateCalendarObject(context, _ref8) {\n let {\n calendarObject\n } = _ref8;\n let eventComponent = calendarObject.calendarComponent.getFirstComponent('VEVENT');\n if (calendarObject.existsOnServer) {\n let icsValue = calendarObject.calendarComponent.toICS();\n if (eventComponent != null) {\n if (eventComponent.client != null) {\n let newClientKeyValue = \"CLIENT:\" + eventComponent.client;\n icsValue = icsValue.replace(/CLIENT:\\d+/, newClientKeyValue);\n }\n if (eventComponent.isPrivate != null) {\n let isPrivateValue = eventComponent.isPrivate ? \"1\" : \"0\";\n let newIsPrivateKeyValue = \"ISPRIVATE:\" + isPrivateValue;\n let regex = /ISPRIVATE:\\d+/;\n if (regex.test(icsValue)) {\n icsValue = icsValue.replace(regex, newIsPrivateKeyValue);\n } else {\n const customKeyValue = {\n \"ISPRIVATE\": isPrivateValue\n };\n icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue, customKeyValue);\n }\n }\n }\n calendarObject.dav.data = icsValue;\n await calendarObject.dav.update();\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendarObject.calendarId,\n calendarObjectId: calendarObject.id\n });\n context.commit('resetCalendarObjectToDav', {\n calendarObject\n });\n context.commit('incrementModificationCount');\n return;\n // TODO - catch conflicts\n }\n const calendar = context.getters.getCalendarById(calendarObject.calendarId);\n let icsValue = calendarObject.calendarComponent.toICS();\n if (eventComponent != null) {\n const customKeyValue = {\n \"CLIENT\": eventComponent.client,\n \"EMBALMER\": eventComponent.embalmer,\n \"ISPRIVATE\": eventComponent.isPrivate ? \"1\" : \"0\"\n };\n icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue, customKeyValue);\n }\n calendarObject.dav = await calendar.dav.createVObject(icsValue);\n calendarObject.existsOnServer = true;\n context.commit('updateCalendarObjectId', {\n calendarObject\n });\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: calendarObject.calendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendarObject.calendarId,\n calendarObjectId: calendarObject.id\n });\n context.commit('resetCalendarObjectToDav', {\n calendarObject\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Creates a new calendar-object from an recurrence-exception fork\n *\n * @param {object} context The Vuex context\n * @param {object} data destructuring object\n * @param {EventComponent} data.eventComponent EventComponent to store\n * @param {string} data.calendarId The calendar-id to store it in\n * @return {Promise}\n */\n async createCalendarObjectFromFork(context, _ref9) {\n let {\n eventComponent,\n calendarId\n } = _ref9;\n const calendar = context.getters.getCalendarById(calendarId);\n const calendarObject = mapCalendarJsToCalendarObject(eventComponent.root, calendar.id);\n calendarObject.dav = await calendar.dav.createVObject(calendarObject.calendarComponent.toICS());\n calendarObject.existsOnServer = true;\n context.commit('updateCalendarObjectId', {\n calendarObject\n });\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: calendarObject.calendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendar.id,\n calendarObjectId: calendarObject.id\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Deletes a calendar-object\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {CalendarObject} data.calendarObject Calendar-object to delete\n * @return {Promise}\n */\n async deleteCalendarObject(context, _ref10) {\n let {\n calendarObject\n } = _ref10;\n // If this calendar-object was not created on the server yet,\n // no need to send requests to the server\n if (calendarObject.existsOnServer) {\n await calendarObject.dav.delete();\n }\n context.commit('deleteCalendarObject', {\n calendarObject\n });\n context.commit('deleteCalendarObjectFromCalendar', {\n calendar: {\n id: calendarObject.calendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('removeCalendarObjectIdFromAnyTimeRange', {\n calendarObjectId: calendarObject.id\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Creates a new calendar object based on start, end, timezone and isAllDay\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {number} data.start Timestamp for start of new event\n * @param {number} data.end Timestamp for end of new event\n * @param {string} data.timezoneId asd\n * @param {boolean} data.isAllDay foo\n * @return {Promise}\n */\n createNewEvent(context, _ref11) {\n let {\n start,\n end,\n timezoneId,\n isAllDay\n } = _ref11;\n const timezoneManager = getTimezoneManager();\n const timezone = timezoneManager.getTimezoneForId(timezoneId);\n const startDate = new Date(start * 1000);\n const endDate = new Date(end * 1000);\n const startDateTime = DateTimeValue.fromJSDate(startDate, true).getInTimezone(timezone);\n const endDateTime = DateTimeValue.fromJSDate(endDate, true).getInTimezone(timezone);\n if (isAllDay) {\n startDateTime.isDate = true;\n endDateTime.isDate = true;\n }\n const calendar = createEvent(startDateTime, endDateTime);\n for (const vObject of calendar.getVObjectIterator()) {\n vObject.undirtify();\n }\n const firstCalendar = context.getters.sortedCalendars[0].id;\n return Promise.resolve(mapCalendarJsToCalendarObject(calendar, firstCalendar));\n },\n /**\n * Updates the time of the new calendar object\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {Function} data.dispatch The Vuex dispatch function\n * @param {object} data2 destructuring object\n * @param {CalendarObject} data2.calendarObjectInstance Calendar-object to\n * @param {number} data2.start Timestamp for start of new event\n * @param {number} data2.end Timestamp for end of new event\n * @param {string} data2.timezoneId asd\n * @param {boolean} data2.isAllDay foo\n */\n updateTimeOfNewEvent(_ref12, _ref13) {\n let {\n commit,\n dispatch\n } = _ref12;\n let {\n calendarObjectInstance,\n start,\n end,\n timezoneId,\n isAllDay\n } = _ref13;\n const isDirty = calendarObjectInstance.eventComponent.isDirty();\n const startDate = new Date(start * 1000);\n const endDate = new Date(end * 1000);\n if (calendarObjectInstance.isAllDay !== isAllDay) {\n commit('toggleAllDay', {\n calendarObjectInstance\n });\n }\n dispatch('changeStartTimezone', {\n calendarObjectInstance,\n startTimezone: timezoneId\n });\n dispatch('changeEndTimezone', {\n calendarObjectInstance,\n endTimezone: timezoneId\n });\n commit('changeStartDate', {\n calendarObjectInstance,\n startDate\n });\n if (isAllDay) {\n // The full-calendar end date is exclusive, but the end-date\n // that changeEndDate expects is inclusive, so we have to deduct one day.\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate: new Date(endDate.getTime() - 24 * 60 * 60 * 1000)\n });\n } else {\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate\n });\n }\n if (!isDirty) {\n calendarObjectInstance.eventComponent.undirtify();\n }\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @copyright Copyright (c) 2019 John Molakvoæ\r\n *\r\n * @copyright Copyright (c) 2019 Thomas Citharel\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @author Thomas Citharel \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nimport { createCalendar, createSubscription, findAll, findAllDeletedCalendars, findPublicCalendarsByTokens } from '../services/caldavService.js';\nimport { mapCDavObjectToCalendarObject } from '../models/calendarObject.js';\nimport { dateFactory, getUnixTimestampFromDate } from '../utils/date.js';\nimport { getDefaultCalendarObject, mapDavCollectionToCalendar } from '../models/calendar.js';\nimport pLimit from 'p-limit';\nimport { uidToHexColor } from '../utils/color.js';\nimport { translate as t } from '@nextcloud/l10n';\nimport getTimezoneManager from '../services/timezoneDataProviderService.js';\nimport { CalendarComponent, Timezone, TimezoneComponent } from '@nextcloud/calendar-js';\nimport { CALDAV_BIRTHDAY_CALENDAR, IMPORT_STAGE_IMPORTING, IMPORT_STAGE_PROCESSING } from '../models/consts.js';\nimport { showError } from '@nextcloud/dialogs';\nconst state = {\n calendars: [],\n trashBin: undefined,\n scheduleInbox: undefined,\n deletedCalendars: [],\n deletedCalendarObjects: [],\n calendarsById: {},\n initialCalendarsLoaded: false,\n editCalendarModal: undefined,\n widgetView: 'dayGridMonth',\n widgetDate: 'now',\n widgetEventDetailsOpen: false,\n widgetEventDetails: {},\n widgetRef: undefined\n};\nconst mutations = {\n /**\r\n * Adds calendar into state\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to add\r\n */\n addCalendar(state, _ref) {\n let {\n calendar\n } = _ref;\n const object = getDefaultCalendarObject(calendar);\n if (!state.calendars.some(existing => existing.id === object.id)) {\n state.calendars.push(object);\n }\n Vue.set(state.calendarsById, object.id, object);\n },\n addTrashBin(state, _ref2) {\n let {\n trashBin\n } = _ref2;\n state.trashBin = trashBin;\n },\n setWidgetView(state, _ref3) {\n let {\n viewName\n } = _ref3;\n state.widgetView = viewName;\n },\n setWidgetDate(state, _ref4) {\n let {\n widgetDate\n } = _ref4;\n state.widgetDate = widgetDate;\n },\n setWidgetRef(state, _ref5) {\n let {\n widgetRef\n } = _ref5;\n state.widgetRef = widgetRef;\n },\n setSelectedEvent(state, _ref6) {\n let {\n object,\n recurrenceId\n } = _ref6;\n state.widgetEventDetailsOpen = true;\n state.widgetEventDetails = {\n object,\n recurrenceId\n };\n },\n closeWidgetEventDetails(state) {\n state.widgetEventDetailsOpen = false;\n },\n addScheduleInbox(state, _ref7) {\n let {\n scheduleInbox\n } = _ref7;\n state.scheduleInbox = scheduleInbox;\n },\n /**\r\n * Adds deleted calendar into state\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar calendar the calendar to add\r\n */\n addDeletedCalendar(state, _ref8) {\n let {\n calendar\n } = _ref8;\n if (state.deletedCalendars.some(c => c.url === calendar.url)) {\n // This calendar is already known\n return;\n }\n state.deletedCalendars.push(calendar);\n },\n /**\r\n * Removes a deleted calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the deleted calendar to remove\r\n */\n removeDeletedCalendar(state, _ref9) {\n let {\n calendar\n } = _ref9;\n state.deletedCalendars = state.deletedCalendars.filter(c => c !== calendar);\n },\n /**\r\n * Removes a deleted calendar object\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.vobject the deleted calendar object to remove\r\n */\n removeDeletedCalendarObject(state, _ref10) {\n let {\n vobject\n } = _ref10;\n state.deletedCalendarObjects = state.deletedCalendarObjects.filter(vo => vo.id !== vobject.id);\n },\n /**\r\n * Adds a deleted vobject into state\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.vobject the calendar vobject to add\r\n */\n addDeletedCalendarObject(state, _ref11) {\n let {\n vobject\n } = _ref11;\n if (state.deletedCalendarObjects.some(c => c.uri === vobject.uri)) {\n // This vobject is already known\n return;\n }\n state.deletedCalendarObjects.push(vobject);\n },\n /**\r\n * Deletes a calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to delete\r\n */\n deleteCalendar(state, _ref12) {\n let {\n calendar\n } = _ref12;\n state.calendars.splice(state.calendars.indexOf(calendar), 1);\n Vue.delete(state.calendarsById, calendar.id);\n },\n /**\r\n * Toggles a calendar's visibility\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to toggle\r\n */\n toggleCalendarEnabled(state, _ref13) {\n let {\n calendar\n } = _ref13;\n state.calendarsById[calendar.id].enabled = !state.calendarsById[calendar.id].enabled;\n },\n /**\r\n * Renames a calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to rename\r\n * @param {string} data.newName the new name of the calendar\r\n */\n renameCalendar(state, _ref14) {\n let {\n calendar,\n newName\n } = _ref14;\n state.calendarsById[calendar.id].displayName = newName;\n },\n /**\r\n * Changes calendar's color\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to rename\r\n * @param {string} data.newColor the new color of the calendar\r\n */\n changeCalendarColor(state, _ref15) {\n let {\n calendar,\n newColor\n } = _ref15;\n state.calendarsById[calendar.id].color = newColor;\n },\n /**\r\n * Changes calendar's order\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to rename\r\n * @param {string} data.newOrder the new order of the calendar\r\n */\n changeCalendarOrder(state, _ref16) {\n let {\n calendar,\n newOrder\n } = _ref16;\n state.calendarsById[calendar.id].order = newOrder;\n },\n /**\r\n * Adds multiple calendar-objects to calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to append objects to\r\n * @param {string[]} data.calendarObjectIds The calendar object ids to append\r\n */\n appendCalendarObjectsToCalendar(state, _ref17) {\n let {\n calendar,\n calendarObjectIds\n } = _ref17;\n for (const calendarObjectId of calendarObjectIds) {\n if (state.calendarsById[calendar.id].calendarObjects.indexOf(calendarObjectId) === -1) {\n state.calendarsById[calendar.id].calendarObjects.push(calendarObjectId);\n }\n }\n },\n /**\r\n * Adds calendar-object to calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to append objects to\r\n * @param {string} data.calendarObjectId The calendar object id to append\r\n */\n addCalendarObjectToCalendar(state, _ref18) {\n let {\n calendar,\n calendarObjectId\n } = _ref18;\n if (state.calendarsById[calendar.id].calendarObjects.indexOf(calendarObjectId) === -1) {\n state.calendarsById[calendar.id].calendarObjects.push(calendarObjectId);\n }\n },\n /**\r\n * Removes calendar-object from calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to delete objects from\r\n * @param {string} data.calendarObjectId The calendar object ids to delete\r\n */\n deleteCalendarObjectFromCalendar(state, _ref19) {\n let {\n calendar,\n calendarObjectId\n } = _ref19;\n const index = state.calendarsById[calendar.id].calendarObjects.indexOf(calendarObjectId);\n if (index !== -1) {\n state.calendarsById[calendar.id].calendarObjects.slice(index, 1);\n }\n },\n /**\r\n * Adds fetched time-range to calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to append a time-range to\r\n * @param {number} data.fetchedTimeRangeId The time-range-id to append\r\n */\n addFetchedTimeRangeToCalendar(state, _ref20) {\n let {\n calendar,\n fetchedTimeRangeId\n } = _ref20;\n state.calendarsById[calendar.id].fetchedTimeRanges.push(fetchedTimeRangeId);\n },\n /**\r\n * Removes fetched time-range from calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to remove a time-range from\r\n * @param {number} data.fetchedTimeRangeId The time-range-id to remove\r\n */\n deleteFetchedTimeRangeFromCalendar(state, _ref21) {\n let {\n calendar,\n fetchedTimeRangeId\n } = _ref21;\n const index = state.calendarsById[calendar.id].fetchedTimeRanges.indexOf(fetchedTimeRangeId);\n if (index !== -1) {\n state.calendarsById[calendar.id].fetchedTimeRanges.slice(index, 1);\n }\n },\n /**\r\n * Shares calendar with a user or group\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar\r\n * @param {string} data.user the userId\r\n * @param {string} data.displayName the displayName\r\n * @param {string} data.uri the sharing principalScheme uri\r\n * @param {boolean} data.isGroup is this a group?\r\n * @param {boolean} data.isCircle is this a circle?\r\n */\n shareCalendar(state, _ref22) {\n let {\n calendar,\n user,\n displayName,\n uri,\n isGroup,\n isCircle\n } = _ref22;\n const newSharee = {\n displayName,\n id: user,\n writeable: false,\n isGroup,\n isCircle,\n uri\n };\n state.calendarsById[calendar.id].shares.push(newSharee);\n },\n /**\r\n * Removes Sharee from calendar shares list\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar\r\n * @param {string} data.uri the sharee uri\r\n */\n unshareCalendar(state, _ref23) {\n let {\n calendar,\n uri\n } = _ref23;\n calendar = state.calendars.find(search => search.id === calendar.id);\n const shareIndex = calendar.shares.findIndex(sharee => sharee.uri === uri);\n calendar.shares.splice(shareIndex, 1);\n },\n /**\r\n * Toggles sharee's writable permission\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar\r\n * @param {string} data.uri the sharee uri\r\n */\n toggleCalendarShareWritable(state, _ref24) {\n let {\n calendar,\n uri\n } = _ref24;\n calendar = state.calendars.find(search => search.id === calendar.id);\n const sharee = calendar.shares.find(sharee => sharee.uri === uri);\n sharee.writeable = !sharee.writeable;\n },\n /**\r\n * Publishes a calendar calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to publish\r\n * @param {string} data.publishURL published URL of calendar\r\n */\n publishCalendar(state, _ref25) {\n let {\n calendar,\n publishURL\n } = _ref25;\n calendar = state.calendars.find(search => search.id === calendar.id);\n calendar.publishURL = publishURL;\n },\n /**\r\n * Unpublishes a calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to unpublish\r\n */\n unpublishCalendar(state, _ref26) {\n let {\n calendar\n } = _ref26;\n calendar = state.calendars.find(search => search.id === calendar.id);\n calendar.publishURL = null;\n },\n /**\r\n * Marks initial loading of calendars as complete\r\n *\r\n * @param {object} state the store data\r\n */\n initialCalendarsLoaded(state) {\n state.initialCalendarsLoaded = true;\n },\n /**\r\n * Marks a calendar as loading\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to mark as loading\r\n */\n markCalendarAsLoading(state, _ref27) {\n let {\n calendar\n } = _ref27;\n state.calendarsById[calendar.id].loading = true;\n },\n /**\r\n * Marks a calendar as finished loading\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to mark as finished loading\r\n */\n markCalendarAsNotLoading(state, _ref28) {\n let {\n calendar\n } = _ref28;\n state.calendarsById[calendar.id].loading = false;\n },\n showEditCalendarModal(state, _ref29) {\n let {\n calendarId\n } = _ref29;\n state.editCalendarModal = {\n calendarId\n };\n },\n hideEditCalendarModal(state) {\n state.editCalendarModal = undefined;\n },\n setCalendarDeleteCountdown(state, _ref30) {\n let {\n calendar,\n countdown\n } = _ref30;\n Vue.set(state.calendarsById[calendar.id], 'countdown', countdown);\n },\n setCalendarDeleteHandles(state, _ref31) {\n let {\n calendar,\n deleteTimeout,\n deleteInterval\n } = _ref31;\n Vue.set(state.calendarsById[calendar.id], 'deleteTimeout', deleteTimeout);\n Vue.set(state.calendarsById[calendar.id], 'deleteInterval', deleteInterval);\n }\n};\nconst getters = {\n /**\r\n * List of sorted calendars and subscriptions\r\n *\r\n * @param {object} state the store data\r\n * @param {object} store the store\r\n * @param {object} rootState the rootState\r\n * @return {Array}\r\n */\n sortedCalendarsSubscriptions(state, store, rootState) {\n return state.calendars.filter(calendar => calendar.supportsEvents || rootState.settings.showTasks && calendar.supportsTasks).sort((a, b) => a.order - b.order);\n },\n /**\r\n * List of sorted calendars\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n sortedCalendars(state) {\n return state.calendars.filter(calendar => calendar.supportsEvents).filter(calendar => !calendar.readOnly).sort((a, b) => a.order - b.order);\n },\n /**\r\n * List of sorted calendars owned by the principal\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n ownSortedCalendars(state) {\n return state.calendars.filter(calendar => calendar.supportsEvents).filter(calendar => !calendar.readOnly).filter(calendar => !calendar.isSharedWithMe).sort((a, b) => a.order - b.order);\n },\n widgetView(state) {\n return state.widgetView;\n },\n widgetDate(state) {\n return state.widgetDate;\n },\n widgetEventDetailsOpen(state) {\n return state.widgetEventDetailsOpen;\n },\n widgetRef(state) {\n return state.widgetRef;\n },\n hasTrashBin(state) {\n return state.trashBin !== undefined && state.trashBin.retentionDuration !== 0;\n },\n trashBin(state) {\n return state.trashBin;\n },\n scheduleInbox: state => {\n return state.scheduleInbox;\n },\n /**\r\n * List of deleted sorted calendars\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n sortedDeletedCalendars(state) {\n return state.deletedCalendars.sort((a, b) => a.deletedAt - b.deletedAt);\n },\n /**\r\n * List of deleted calendars objects\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n deletedCalendarObjects(state) {\n const calendarUriMap = {};\n state.calendars.forEach(calendar => {\n const withoutTrail = calendar.url.replace(/\\/$/, '');\n const uri = withoutTrail.slice(withoutTrail.lastIndexOf('/') + 1);\n calendarUriMap[uri] = calendar;\n });\n return state.deletedCalendarObjects.map(obj => ({\n calendar: calendarUriMap[obj.dav._props['{http://nextcloud.com/ns}calendar-uri']],\n ...obj\n }));\n },\n /**\r\n * List of sorted subscriptions\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n sortedSubscriptions(state) {\n return state.calendars.filter(calendar => calendar.supportsEvents).filter(calendar => calendar.readOnly).sort((a, b) => a.order - b.order);\n },\n /**\r\n * List of enabled calendars and subscriptions\r\n *\r\n * @param {object} state the store data\r\n * @param {object} store the store\r\n * @param {object} rootState the rootState\r\n * @return {Array}\r\n */\n enabledCalendars(state, store, rootState) {\n return state.calendars.filter(calendar => calendar.supportsEvents || rootState.settings.showTasks && calendar.supportsTasks).filter(calendar => calendar.enabled);\n },\n /**\r\n * Gets a calendar by it's Id\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getCalendarById: state => calendarId => state.calendarsById[calendarId],\n /**\r\n * Gets a calendar by its url\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getCalendarByUrl: state => url => state.calendars.find(calendar => calendar.url === url),\n /**\r\n * Gets the contact's birthday calendar or null\r\n *\r\n * @param {object} state the store data\r\n * @return {object | null}\r\n */\n getBirthdayCalendar: state => {\n for (const calendar of state.calendars) {\n const url = calendar.url.slice(0, -1);\n const lastSlash = url.lastIndexOf('/');\n const uri = url.slice(lastSlash + 1);\n if (uri === CALDAV_BIRTHDAY_CALENDAR) {\n return calendar;\n }\n }\n return null;\n },\n /**\r\n * Whether or not a birthday calendar exists\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} getters the vuex getters\r\n * @return {boolean}\r\n */\n hasBirthdayCalendar: (state, getters) => {\n return !!getters.getBirthdayCalendar;\n },\n /**\r\n *\r\n * @param {object} state the store data\r\n * @param {object} getters the store getters\r\n * @return {function({Boolean}, {Boolean}, {Boolean}): {Object}[]}\r\n */\n sortedCalendarFilteredByComponents: (state, getters) => (vevent, vjournal, vtodo) => {\n return getters.sortedCalendars.filter(calendar => {\n if (vevent && !calendar.supportsEvents) {\n return false;\n }\n if (vjournal && !calendar.supportsJournals) {\n return false;\n }\n if (vtodo && !calendar.supportsTasks) {\n return false;\n }\n return true;\n });\n },\n editCalendarModal: state => state.editCalendarModal\n};\nconst actions = {\n /**\r\n * Retrieve and commit calendars and other collections\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} context.state the store state\r\n * @param {object} context.getters the store getters\r\n * @return {Promise} the results\r\n */\n async loadCollections(_ref32) {\n let {\n commit,\n state,\n getters\n } = _ref32;\n const {\n calendars,\n trashBins,\n scheduleInboxes,\n subscriptions\n } = await findAll();\n console.info('calendar home scanned', calendars, trashBins, subscriptions);\n calendars.map(calendar => mapDavCollectionToCalendar(calendar, getters.getCurrentUserPrincipal)).forEach(calendar => {\n commit('addCalendar', {\n calendar\n });\n });\n if (trashBins.length) {\n commit('addTrashBin', {\n trashBin: trashBins[0]\n });\n }\n if (scheduleInboxes.length) {\n commit('addScheduleInbox', {\n scheduleInbox: scheduleInboxes[0]\n });\n }\n commit('initialCalendarsLoaded');\n return {\n calendars: state.calendars,\n trashBin: state.trashBin\n };\n },\n /**\r\n * Retrieve and commit deleted calendars\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @return {Promise} the calendars\r\n */\n async loadDeletedCalendars(_ref33) {\n let {\n commit\n } = _ref33;\n const calendars = await findAllDeletedCalendars();\n calendars.forEach(calendar => commit('addDeletedCalendar', {\n calendar\n }));\n },\n /**\r\n * Retrieve and commit deleted calendar objects\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} context.state the store state\r\n */\n async loadDeletedCalendarObjects(_ref34) {\n let {\n commit,\n state\n } = _ref34;\n const vobjects = await state.trashBin.findDeletedObjects();\n console.info('vobjects loaded', {\n vobjects\n });\n vobjects.forEach(vobject => {\n try {\n const calendarObject = mapCDavObjectToCalendarObject(vobject, undefined);\n commit('addDeletedCalendarObject', {\n vobject: calendarObject\n });\n } catch (error) {\n console.error('could not convert calendar object', vobject, error);\n }\n });\n },\n /**\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} data The data destructuring object\r\n * @param {string[]} data.tokens The tokens to load\r\n * @return {Promise}\r\n */\n async getPublicCalendars(_ref35, _ref36) {\n let {\n commit\n } = _ref35;\n let {\n tokens\n } = _ref36;\n const calendars = await findPublicCalendarsByTokens(tokens);\n const calendarObjects = [];\n for (const davCalendar of calendars) {\n const calendar = mapDavCollectionToCalendar(davCalendar);\n commit('addCalendar', {\n calendar\n });\n calendarObjects.push(calendar);\n }\n commit('initialCalendarsLoaded');\n return calendarObjects;\n },\n /**\r\n * Append a new calendar to array of existing calendars\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.displayName The name of the new calendar\r\n * @param {object} data.color The color of the new calendar\r\n * @param {object} data.order The order of the new calendar\r\n * @param {string[]} data.components The supported components of the calendar\r\n * @param {string=} data.timezone The timezoneId\r\n * @return {Promise}\r\n */\n async appendCalendar(context, _ref37) {\n let {\n displayName,\n color,\n order,\n components = ['VEVENT'],\n timezone = null\n } = _ref37;\n if (timezone === null) {\n timezone = context.getters.getResolvedTimezone;\n }\n let timezoneIcs = null;\n const timezoneObject = getTimezoneManager().getTimezoneForId(timezone);\n if (timezoneObject !== Timezone.utc && timezoneObject !== Timezone.floating) {\n const calendar = CalendarComponent.fromEmpty();\n calendar.addComponent(TimezoneComponent.fromICALJs(timezoneObject.toICALJs()));\n timezoneIcs = calendar.toICS(false);\n }\n const response = await createCalendar(displayName, color, components, order, timezoneIcs);\n const calendar = mapDavCollectionToCalendar(response, context.getters.getCurrentUserPrincipal);\n context.commit('addCalendar', {\n calendar\n });\n },\n /**\r\n * Append a new subscription to array of existing calendars\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {string} data.displayName Name of new subscription\r\n * @param {string} data.color Color of new subscription\r\n * @param {string} data.order Order of new subscription\r\n * @param {string} data.source Source of new subscription\r\n * @return {Promise}\r\n */\n async appendSubscription(context, _ref38) {\n let {\n displayName,\n color,\n order,\n source\n } = _ref38;\n const response = await createSubscription(displayName, color, source, order);\n const calendar = mapDavCollectionToCalendar(response, context.getters.getCurrentUserPrincipal);\n context.commit('addCalendar', {\n calendar\n });\n },\n /**\r\n * Delete a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to delete\r\n * @return {Promise}\r\n */\n async deleteCalendar(context, _ref39) {\n let {\n calendar\n } = _ref39;\n await calendar.dav.delete();\n context.commit('deleteCalendar', {\n calendar\n });\n },\n /**\r\n * Delete a calendar in the trash bin\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to delete\r\n * @return {Promise}\r\n */\n async deleteCalendarPermanently(context, _ref40) {\n let {\n calendar\n } = _ref40;\n await calendar.delete({\n 'X-NC-CalDAV-No-Trashbin': 1\n });\n context.commit('removeDeletedCalendar', {\n calendar\n });\n },\n deleteCalendarAfterTimeout(context, _ref41) {\n let {\n calendar,\n countdown = 7\n } = _ref41;\n context.commit('setCalendarDeleteCountdown', {\n calendar,\n countdown\n });\n const deleteInterval = setInterval(() => {\n countdown--;\n if (countdown < 0) {\n countdown = 0;\n }\n context.commit('setCalendarDeleteCountdown', {\n calendar,\n countdown\n });\n }, 1000);\n const deleteTimeout = setTimeout(async () => {\n try {\n await context.dispatch('deleteCalendar', {\n calendar\n });\n } catch (error) {\n showError(t('calendar', 'An error occurred, unable to delete the calendar.'));\n console.error(error);\n } finally {\n clearInterval(deleteInterval);\n }\n }, 7000);\n context.commit('setCalendarDeleteHandles', {\n calendar,\n deleteInterval,\n deleteTimeout\n });\n },\n cancelCalendarDeletion(context, _ref42) {\n let {\n calendar\n } = _ref42;\n if (calendar.deleteInterval) clearInterval(calendar.deleteInterval);\n if (calendar.deleteTimeout) clearTimeout(calendar.deleteTimeout);\n context.commit('setCalendarDeleteHandles', {\n calendar,\n deleteInterval: undefined,\n deleteTimeout: undefined\n });\n },\n async restoreCalendar(_ref43, _ref44) {\n let {\n commit,\n state\n } = _ref43;\n let {\n calendar\n } = _ref44;\n await state.trashBin.restore(calendar.url);\n commit('removeDeletedCalendar', {\n calendar\n });\n },\n async restoreCalendarObject(_ref45, _ref46) {\n var _component$startDate, _component$endDate;\n let {\n commit,\n state,\n getters\n } = _ref45;\n let {\n vobject\n } = _ref46;\n await state.trashBin.restore(vobject.uri);\n\n // Clean up the data locally\n commit('removeDeletedCalendarObject', {\n vobject\n });\n\n // Delete cached time range that includes the restored event\n const calendarObject = mapCDavObjectToCalendarObject(vobject.dav, undefined);\n const component = calendarObject.calendarComponent.getFirstComponent(vobject.objectType);\n const timeRange = getters.getTimeRangeForCalendarCoveringRange(vobject.calendar.id, (_component$startDate = component.startDate) === null || _component$startDate === void 0 ? void 0 : _component$startDate.unixTime, (_component$endDate = component.endDate) === null || _component$endDate === void 0 ? void 0 : _component$endDate.unixTime);\n if (timeRange) {\n commit('deleteFetchedTimeRangeFromCalendar', {\n calendar: vobject.calendar,\n fetchedTimeRangeId: timeRange.id\n });\n commit('removeTimeRange', {\n timeRangeId: timeRange.id\n });\n }\n\n // Trigger calendar refresh\n commit('incrementModificationCount');\n },\n /**\r\n * Deletes a calendar-object permanently\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {vobject} data.vobject Calendar-object to delete\r\n * @return {Promise}\r\n */\n async deleteCalendarObjectPermanently(context, _ref47) {\n let {\n vobject\n } = _ref47;\n await vobject.dav.delete({\n 'X-NC-CalDAV-No-Trashbin': 1\n });\n context.commit('removeDeletedCalendarObject', {\n vobject\n });\n },\n /**\r\n * Toggle whether a calendar is enabled\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to modify\r\n * @return {Promise}\r\n */\n async toggleCalendarEnabled(context, _ref48) {\n let {\n calendar\n } = _ref48;\n context.commit('markCalendarAsLoading', {\n calendar\n });\n calendar.dav.enabled = !calendar.dav.enabled;\n try {\n await calendar.dav.update();\n context.commit('markCalendarAsNotLoading', {\n calendar\n });\n context.commit('toggleCalendarEnabled', {\n calendar\n });\n } catch (error) {\n context.commit('markCalendarAsNotLoading', {\n calendar\n });\n throw error;\n }\n },\n /**\r\n * Rename a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to modify\r\n * @param {string} data.newName the new name of the calendar\r\n * @return {Promise}\r\n */\n async renameCalendar(context, _ref49) {\n let {\n calendar,\n newName\n } = _ref49;\n calendar.dav.displayname = newName;\n await calendar.dav.update();\n context.commit('renameCalendar', {\n calendar,\n newName\n });\n },\n /**\r\n * Change a calendar's color\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to modify\r\n * @param {string} data.newColor the new color of the calendar\r\n * @return {Promise}\r\n */\n async changeCalendarColor(context, _ref50) {\n let {\n calendar,\n newColor\n } = _ref50;\n calendar.dav.color = newColor;\n await calendar.dav.update();\n context.commit('changeCalendarColor', {\n calendar,\n newColor\n });\n },\n /**\r\n * Share calendar with User or Group\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to share\r\n * @param {string} data.user the userId\r\n * @param {string} data.displayName the displayName\r\n * @param {string} data.uri the sharing principalScheme uri\r\n * @param {boolean} data.isGroup is this a group?\r\n * @param {boolean} data.isCircle is this a circle?\r\n */\n async shareCalendar(context, _ref51) {\n let {\n calendar,\n user,\n displayName,\n uri,\n isGroup,\n isCircle\n } = _ref51;\n // Share calendar with entered group or user\n await calendar.dav.share(uri);\n context.commit('shareCalendar', {\n calendar,\n user,\n displayName,\n uri,\n isGroup,\n isCircle\n });\n },\n /**\r\n * Toggle permissions of calendar Sharees writeable rights\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @param {string} data.uri the sharing principalScheme uri\r\n */\n async toggleCalendarShareWritable(context, _ref52) {\n let {\n calendar,\n uri\n } = _ref52;\n const sharee = calendar.shares.find(sharee => sharee.uri === uri);\n await calendar.dav.share(uri, !sharee.writeable);\n context.commit('toggleCalendarShareWritable', {\n calendar,\n uri\n });\n },\n /**\r\n * Remove sharee from calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @param {string} data.uri the sharing principalScheme uri\r\n */\n async unshareCalendar(context, _ref53) {\n let {\n calendar,\n uri\n } = _ref53;\n await calendar.dav.unshare(uri);\n context.commit('unshareCalendar', {\n calendar,\n uri\n });\n },\n /**\r\n * Publish a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @return {Promise}\r\n */\n async publishCalendar(context, _ref54) {\n let {\n calendar\n } = _ref54;\n await calendar.dav.publish();\n const publishURL = calendar.dav.publishURL;\n context.commit('publishCalendar', {\n calendar,\n publishURL\n });\n },\n /**\r\n * Unpublish a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @return {Promise}\r\n */\n async unpublishCalendar(context, _ref55) {\n let {\n calendar\n } = _ref55;\n await calendar.dav.unpublish();\n context.commit('unpublishCalendar', {\n calendar\n });\n },\n /**\r\n * Retrieve the events of the specified calendar\r\n * and commit the results\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to get events from\r\n * @param {Date} data.from the date to start querying events from\r\n * @param {Date} data.to the last date to query events from\r\n * @return {Promise}\r\n */\n async getEventsFromCalendarInTimeRange(context, _ref56) {\n let {\n calendar,\n from,\n to\n } = _ref56;\n context.commit('markCalendarAsLoading', {\n calendar\n });\n const response = await calendar.dav.findByTypeInTimeRange('VEVENT', from, to);\n let responseTodo = [];\n if (context.rootState.settings.showTasks) {\n responseTodo = await calendar.dav.findByTypeInTimeRange('VTODO', from, to);\n }\n context.commit('addTimeRange', {\n calendarId: calendar.id,\n from: getUnixTimestampFromDate(from),\n to: getUnixTimestampFromDate(to),\n lastFetched: getUnixTimestampFromDate(dateFactory()),\n calendarObjectIds: []\n });\n const insertId = context.getters.getLastTimeRangeInsertId;\n context.commit('addFetchedTimeRangeToCalendar', {\n calendar,\n fetchedTimeRangeId: insertId\n });\n const calendarObjects = [];\n const calendarObjectIds = [];\n for (const r of response.concat(responseTodo)) {\n try {\n const calendarObject = mapCDavObjectToCalendarObject(r, calendar.id);\n calendarObjects.push(calendarObject);\n calendarObjectIds.push(calendarObject.id);\n } catch (e) {\n console.error(\"could not convert calendar object of calendar \".concat(calendar.id), e, {\n response: r\n });\n }\n }\n context.commit('appendCalendarObjects', {\n calendarObjects\n });\n context.commit('appendCalendarObjectsToCalendar', {\n calendar,\n calendarObjectIds\n });\n context.commit('appendCalendarObjectIdsToTimeFrame', {\n timeRangeId: insertId,\n calendarObjectIds\n });\n context.commit('markCalendarAsNotLoading', {\n calendar\n });\n return context.rootState.fetchedTimeRanges.lastTimeRangeInsertId;\n },\n /**\r\n * Retrieve one object\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {string} data.objectId Id of the object to fetch\r\n * @return {Promise}\r\n */\n async getEventByObjectId(context, _ref57) {\n let {\n objectId\n } = _ref57;\n // TODO - we should still check if the calendar-object is up to date\n // - Just send head and compare etags\n if (context.getters.getCalendarObjectById(objectId)) {\n return Promise.resolve(context.getters.getCalendarObjectById(objectId));\n }\n\n // This might throw an exception, but we will leave it up to the methods\n // calling this action to properly handle it\n const objectPath = atob(objectId);\n const lastSlashIndex = objectPath.lastIndexOf('/');\n const calendarPath = objectPath.slice(0, lastSlashIndex + 1);\n const objectFileName = objectPath.slice(lastSlashIndex + 1);\n const calendarId = btoa(calendarPath);\n if (!context.state.calendarsById[calendarId]) {\n return Promise.reject(new Error(''));\n }\n const calendar = context.state.calendarsById[calendarId];\n const vObject = await calendar.dav.find(objectFileName);\n const calendarObject = mapCDavObjectToCalendarObject(vObject, calendar.id);\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: calendarId\n },\n calendarObjectId: calendarObject.id\n });\n return calendarObject;\n },\n /**\r\n * Import events into calendar\r\n *\r\n * @param {object} context the store mutations\r\n */\n async importEventsIntoCalendar(context) {\n context.commit('changeStage', IMPORT_STAGE_IMPORTING);\n\n // Create a copy\n const files = context.rootState.importFiles.importFiles.slice();\n let totalCount = 0;\n for (const file of files) {\n totalCount += file.parser.getItemCount();\n const calendarId = context.rootState.importFiles.importCalendarRelation[file.id];\n if (calendarId === 'new') {\n const displayName = file.parser.getName() || t('calendar', 'Imported {filename}', {\n filename: file.name\n });\n const color = file.parser.getColor() || uidToHexColor(displayName);\n const components = [];\n if (file.parser.containsVEvents()) {\n components.push('VEVENT');\n }\n if (file.parser.containsVJournals()) {\n components.push('VJOURNAL');\n }\n if (file.parser.containsVTodos()) {\n components.push('VTODO');\n }\n const response = await createCalendar(displayName, color, components, 0);\n const calendar = mapDavCollectionToCalendar(response, context.getters.getCurrentUserPrincipal);\n context.commit('addCalendar', {\n calendar\n });\n context.commit('setCalendarForFileId', {\n fileId: file.id,\n calendarId: calendar.id\n });\n }\n }\n context.commit('setTotal', totalCount);\n const limit = pLimit(3);\n const requests = [];\n for (const file of files) {\n const calendarId = context.rootState.importFiles.importCalendarRelation[file.id];\n const calendar = context.getters.getCalendarById(calendarId);\n for (const item of file.parser.getItemIterator()) {\n requests.push(limit(async () => {\n const ics = item.toICS();\n let davObject;\n try {\n davObject = await calendar.dav.createVObject(ics);\n } catch (error) {\n context.commit('incrementDenied');\n console.error(error);\n return;\n }\n const calendarObject = mapCDavObjectToCalendarObject(davObject, calendarId);\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar,\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendar.id,\n calendarObjectId: calendarObject.id\n });\n context.commit('incrementAccepted');\n }));\n }\n }\n await Promise.all(requests);\n context.commit('changeStage', IMPORT_STAGE_PROCESSING);\n },\n /**\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} context.state the store state\r\n * @param {object} data The data destructuring object\r\n * @param {object} data.newOrder The object containing String => Number with the new order\r\n * @return {Promise}\r\n */\n async updateCalendarListOrder(_ref58, _ref59) {\n let {\n state,\n commit\n } = _ref58;\n let {\n newOrder\n } = _ref59;\n // keep a record of the original order in case we need to do a rollback\n\n const limit = pLimit(3);\n const requests = [];\n const calendarsToUpdate = [];\n for (const key in newOrder) {\n requests.push(limit(async () => {\n const calendar = state.calendarsById[key];\n\n // Do not update unless necessary\n if (calendar.dav.order === newOrder[key]) {\n return;\n }\n calendar.dav.order = newOrder[key];\n await calendar.dav.update();\n calendarsToUpdate.push({\n calendar,\n newOrder: newOrder[key]\n });\n }));\n }\n await Promise.all(requests);\n for (const {\n calendar,\n newOrder\n } of calendarsToUpdate) {\n console.debug(calendar, newOrder);\n commit('changeCalendarOrder', {\n calendar,\n newOrder\n });\n }\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nconst state = {\n contacts: [],\n contactByEMail: {}\n};\nconst mutations = {\n /**\r\n * Append a single contact to the store\r\n *\r\n * @param {object} state The store data\r\n * @param {object} data The destructuring object\r\n * @param {object} data.contact The contact to append to the store\r\n */\n appendContact(state, _ref) {\n let {\n contact\n } = _ref;\n if (state.contacts.indexOf(contact) === -1) {\n state.contacts.push(contact);\n }\n for (const email of contact.emails) {\n // In the unlikely case that multiple contacts\n // share the same email address, we will just follow\n // first come, first served.\n if (state.contactByEMail[email] === undefined) {\n Vue.set(state.contactByEMail, email, contact);\n }\n }\n },\n /**\r\n * Removes a single contact from the store\r\n *\r\n * @param {object} state The store data\r\n * @param {object} data The destructuring object\r\n * @param {object} data.contact The contact to remove from the store\r\n */\n removeContact(state, _ref2) {\n let {\n contact\n } = _ref2;\n for (const email of contact.emails) {\n if (state.contactByEMail[email] === contact) {\n Vue.delete(state.contactByEMail, email);\n }\n }\n const index = state.contacts.indexOf(contact);\n if (index !== -1) {\n state.contacts.splice(index, 1);\n }\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nconst state = {\n minimumDate: '1970-01-01T00:00:00Z',\n maximumDate: '2037-12-31T23:59:59Z'\n};\nconst mutations = {\n /**\r\n * Initialize restrictions imposed by CalDAV server\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.minimumDate The minimum-date allowed by the CalDAV server\r\n * @param {string} data.maximumDate The maximum-date allowed by the CalDAV server\r\n */\n loadDavRestrictionsFromServer(state, _ref) {\n let {\n minimumDate,\n maximumDate\n } = _ref;\n state.minimumDate = minimumDate;\n state.maximumDate = maximumDate;\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nconst state = {\n lastTimeRangeInsertId: -1,\n fetchedTimeRanges: [],\n fetchedTimeRangesById: {}\n};\nconst mutations = {\n /**\r\n * Adds a fetched time-range to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarId Calendar-id which objects have been fetched\r\n * @param {number} data.from timestamp of start\r\n * @param {number} data.to timestamp of end\r\n * @param {number} data.lastFetched timestamp of last-fetched\r\n * @param {string[]} data.calendarObjectIds array of calendarObjectIds\r\n */\n addTimeRange(state, _ref) {\n let {\n calendarId,\n from,\n to,\n lastFetched,\n calendarObjectIds\n } = _ref;\n const fetchedTimeRange = {\n id: ++state.lastTimeRangeInsertId,\n calendarId,\n from,\n to,\n lastFetched,\n calendarObjectIds\n };\n state.fetchedTimeRanges.push(fetchedTimeRange);\n Vue.set(state.fetchedTimeRangesById, fetchedTimeRange.id, fetchedTimeRange);\n },\n /**\r\n * Removes a fetched time-range from the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId Id of time-range to remove\r\n */\n removeTimeRange(state, _ref2) {\n let {\n timeRangeId\n } = _ref2;\n const obj = state.fetchedTimeRangesById[timeRangeId];\n const index = state.fetchedTimeRanges.indexOf(obj);\n if (index !== -1) {\n state.fetchedTimeRanges.splice(index, 1);\n Vue.delete(state.fetchedTimeRangesById, timeRangeId);\n }\n },\n /**\r\n * Adds a calendar-object-id to an already fetched time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the time-range\r\n * @param {string[]} data.calendarObjectIds The array of ids of the calendar-object to add\r\n */\n appendCalendarObjectIdsToTimeFrame(state, _ref3) {\n let {\n timeRangeId,\n calendarObjectIds\n } = _ref3;\n for (const calendarObjectId of calendarObjectIds) {\n if (state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.indexOf(calendarObjectId) === -1) {\n state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.push(calendarObjectId);\n }\n }\n },\n /**\r\n * Adds a calendar-object-id to an already fetched time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the time-range\r\n * @param {string} data.calendarObjectId The id of the calendar-object to add\r\n */\n appendCalendarObjectIdToTimeRange(state, _ref4) {\n let {\n timeRangeId,\n calendarObjectId\n } = _ref4;\n state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.push(calendarObjectId);\n },\n /**\r\n * Removes a calendar-object-id from an already fetched time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the timerange\r\n * @param {string} data.calendarObjectId The id of the calendar-object to remove\r\n */\n removeCalendarObjectIdFromTimeRange(state, _ref5) {\n let {\n timeRangeId,\n calendarObjectId\n } = _ref5;\n const index = state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.indexOf(calendarObjectId);\n if (index !== -1) {\n state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.splice(index, 1);\n }\n },\n /**\r\n * Removes a calendar-object-id from any time-range it may occur in\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarObjectId The id of the calendar-object to remove\r\n */\n removeCalendarObjectIdFromAnyTimeRange(state, _ref6) {\n let {\n calendarObjectId\n } = _ref6;\n for (const timeRange of state.fetchedTimeRanges) {\n const index = timeRange.calendarObjectIds.indexOf(calendarObjectId);\n if (index !== -1) {\n timeRange.calendarObjectIds.splice(index, 1);\n }\n }\n },\n /**\r\n * Updates the last-fetched timestamp of a time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the timerange\r\n * @param {number} data.lastFetched Timestamp of last-fetched\r\n */\n updateTimestampOfLastFetched(state, _ref7) {\n let {\n timeRangeId,\n lastFetched\n } = _ref7;\n state.fetchedTimeRangesById[timeRangeId].lastFetched = lastFetched;\n },\n /**\r\n * Adds a calendar-object-id to all time-ranges of a given caloendar\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarObjectId The id of the calendar-object\r\n * @param {string} data.calendarId The id of the calendar\r\n */\n addCalendarObjectIdToAllTimeRangesOfCalendar(state, _ref8) {\n let {\n calendarObjectId,\n calendarId\n } = _ref8;\n for (const timerange of state.fetchedTimeRanges) {\n if (timerange.calendarId !== calendarId) {\n continue;\n }\n if (timerange.calendarObjectIds.indexOf(calendarObjectId) === -1) {\n timerange.calendarObjectIds.push(calendarObjectId);\n }\n }\n },\n /**\r\n * Removes a calendar-object-id to all time-ranges of a given caloendar\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarObjectId The id of the calendar-object\r\n * @param {string} data.calendarId The id of the calendar\r\n */\n removeCalendarObjectIdFromAllTimeRangesOfCalendar(state, _ref9) {\n let {\n calendarObjectId,\n calendarId\n } = _ref9;\n for (const timerange of state.fetchedTimeRanges) {\n if (timerange.calendarId !== calendarId) {\n continue;\n }\n const index = timerange.calendarObjectIds.indexOf(calendarObjectId);\n if (index !== -1) {\n timerange.calendarObjectIds.splice(index, 1);\n }\n }\n },\n /**\r\n * clear FetchedTimeRanges Store\r\n *\r\n * @param {object} state The vuex state\r\n */\n clearFetchedTimeRanges(state) {\n state.lastTimeRangeInsertId = -1;\n state.fetchedTimeRanges = [];\n state.fetchedTimeRangesById = {};\n }\n};\nconst getters = {\n /**\r\n * Get all time-ranges for a calendar\r\n *\r\n * @param {object} state The vuex state\r\n * @return {function({String}): {Object}[]}\r\n */\n getAllTimeRangesForCalendar: state => calendarId => state.fetchedTimeRanges.filter(f => f.calendarId === calendarId),\n /**\r\n * Get time-range covering\r\n *\r\n * @param {object} state The vuex state\r\n * @return {function({Number}, {Number}, {Number}): {Object}|false}\r\n */\n getTimeRangeForCalendarCoveringRange: state => (calendarId, requestedFrom, requestedTo) => {\n return state.fetchedTimeRanges.find(f => {\n return f.calendarId === calendarId && f.from <= requestedFrom && f.to >= requestedTo;\n });\n },\n /**\r\n * Get all time-ranges that have been last fetched before a given time\r\n *\r\n * @param {object} state The vuex state\r\n * @return {function({Number}): {Object}[]}\r\n */\n getAllTimeRangesOlderThan: state => olderThan => state.fetchedTimeRanges.filter(f => f.lastFetched <= olderThan),\n /**\r\n *\r\n * @param {object} state The vuex state\r\n * @return {number}\r\n */\n getLastTimeRangeInsertId: state => state.lastTimeRangeInsertId,\n /**\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} getters The vuex getters\r\n * @return {function({Number}): {CalendarObject}[]}\r\n */\n getCalendarObjectsByTimeRangeId: (state, getters) => timeRangeId => {\n if (!state.fetchedTimeRangesById[timeRangeId]) {\n return [];\n }\n return state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.map(calendarObjectId => {\n return getters.getCalendarObjectById(calendarObjectId);\n });\n }\n};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Team Popcorn \r\n *\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Team Popcorn \r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nconst state = {\n lastFileInsertId: -1,\n importFiles: [],\n importFilesById: {},\n importCalendarRelation: {}\n};\nconst mutations = {\n /**\r\n * Adds a file to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.contents Contents of file\r\n * @param {number} data.lastModified Timestamp of last modification\r\n * @param {string} data.name Name of file\r\n * @param {AbstractParser} data.parser The parser\r\n * @param {number} data.size Size of file\r\n * @param {string} data.type mime-type of file\r\n */\n addFile(state, _ref) {\n let {\n contents,\n lastModified,\n name,\n parser,\n size,\n type\n } = _ref;\n const file = {\n id: ++state.lastFileInsertId,\n contents,\n lastModified,\n name,\n parser,\n size,\n type\n };\n state.importFiles.push(file);\n Vue.set(state.importFilesById, file.id, file);\n },\n /**\r\n * Sets a calendar for the file\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.fileId Id of file to select calendar for\r\n * @param {string} data.calendarId Id of calendar to import file into\r\n */\n setCalendarForFileId(state, _ref2) {\n let {\n fileId,\n calendarId\n } = _ref2;\n Vue.set(state.importCalendarRelation, fileId, calendarId);\n },\n /**\r\n * Removes all files from state\r\n *\r\n * @param {object} state The vuex state\r\n */\n removeAllFiles(state) {\n Vue.set(state, 'importFiles', []);\n Vue.set(state, 'importFilesById', {});\n Vue.set(state, 'importCalendarRelation', {});\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Team Popcorn \r\n *\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Team Popcorn \r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { IMPORT_STAGE_DEFAULT } from '../models/consts.js';\nconst state = {\n total: 0,\n accepted: 0,\n denied: 0,\n stage: IMPORT_STAGE_DEFAULT\n};\nconst mutations = {\n /**\r\n * Increment the number of calendar-objects accepted\r\n *\r\n * @param {object} state the store data\r\n */\n incrementAccepted(state) {\n state.accepted++;\n },\n /**\r\n * Increment the number of calendar-objects denied\r\n *\r\n * @param {object} state the store data\r\n */\n incrementDenied(state) {\n state.denied++;\n },\n /**\r\n * Set the total number of calendar-objects\r\n *\r\n * @param {object} state the store data\r\n * @param {number} total the total number of calendar-objects to import\r\n */\n setTotal(state, total) {\n state.total = total;\n },\n /**\r\n * Change stage to the indicated one\r\n *\r\n * @param {object} state the store data\r\n * @param {string} stage the name of the stage, see /src/models/consts.js\r\n */\n changeStage(state, stage) {\n state.stage = stage;\n },\n /**\r\n * Reset to the default state\r\n *\r\n * @param {object} state the store data\r\n */\n resetState(state) {\n state.total = 0;\n state.accepted = 0;\n state.denied = 0;\n state.stage = IMPORT_STAGE_DEFAULT;\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @author Thomas Citharel \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nimport Vuex from 'vuex';\nimport calendarObjectInstance from './calendarObjectInstance.js';\nimport calendarObjects from './calendarObjects.js';\nimport calendars from './calendars.js';\nimport contacts from './contacts.js';\nimport davRestrictions from './davRestrictions.js';\nimport fetchedTimeRanges from './fetchedTimeRanges.js';\nimport importFiles from './importFiles.js';\nimport importState from './importState.js';\nimport principals from './principals.js';\nimport settings from './settings.js';\nimport userRole from './userRole.js';\nVue.use(Vuex);\nexport default new Vuex.Store({\n modules: {\n calendarObjectInstance,\n calendarObjects,\n calendars,\n contacts,\n davRestrictions,\n fetchedTimeRanges,\n importFiles,\n importState,\n principals,\n settings,\n userRole\n }\n // // Throw errors when the state is edited outside of mutations\n // strict: true\n});","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nimport { findPrincipalByUrl, getCurrentUserPrincipal } from '../services/caldavService.js';\nimport logger from '../utils/logger.js';\nimport { getDefaultPrincipalObject, mapDavToPrincipal } from '../models/principal.js';\nconst state = {\n principals: [],\n principalsById: {},\n currentUserPrincipal: null\n};\nconst mutations = {\n /**\r\n * Adds a principal to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {object} data.principal The principal to add\r\n */\n addPrincipal(state, _ref) {\n let {\n principal\n } = _ref;\n const object = getDefaultPrincipalObject(principal);\n if (state.principalsById[object.id]) {\n return;\n }\n state.principals.push(object);\n Vue.set(state.principalsById, object.id, object);\n },\n /**\r\n * Adds the current user principal to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data destructuring object\r\n * @param {string} data.principalId principalId of the current-user-principal\r\n */\n setCurrentUserPrincipal(state, _ref2) {\n let {\n principalId\n } = _ref2;\n state.currentUserPrincipal = principalId;\n },\n /**\r\n * Changes the schedule-default-calendar-URL of a principal\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {object} data.principal The principal to modify\r\n * @param {string} data.scheduleDefaultCalendarUrl The new schedule-default-calendar-URL\r\n */\n changePrincipalScheduleDefaultCalendarUrl(state, _ref3) {\n let {\n principal,\n scheduleDefaultCalendarUrl\n } = _ref3;\n Vue.set(state.principalsById[principal.id], 'scheduleDefaultCalendarUrl', scheduleDefaultCalendarUrl);\n }\n};\nconst getters = {\n /**\r\n * Gets a principal object by its url\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getPrincipalByUrl: state => url => state.principals.find(principal => principal.url === url),\n /**\r\n * Gets a principal object by its id\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getPrincipalById: state => id => state.principalsById[id],\n /**\r\n * Gets the principal object of the current-user-principal\r\n *\r\n * @param {object} state the store data\r\n * @return {{Object}}\r\n */\n getCurrentUserPrincipal: state => state.principalsById[state.currentUserPrincipal],\n /**\r\n * Gets the email-address of the current-user-principal\r\n *\r\n * @param {object} state the store data\r\n * @return {string|undefined}\r\n */\n getCurrentUserPrincipalEmail: state => {\n var _state$principalsById;\n return (_state$principalsById = state.principalsById[state.currentUserPrincipal]) === null || _state$principalsById === void 0 ? void 0 : _state$principalsById.emailAddress;\n }\n};\nconst actions = {\n /**\r\n * Fetches a principal from the DAV server and commits it to the state\r\n *\r\n * @param {object} context The vuex context\r\n * @param {string} url The URL of the principal\r\n * @return {Promise}\r\n */\n async fetchPrincipalByUrl(context, _ref4) {\n let {\n url\n } = _ref4;\n // Don't refetch principals we already have\n if (context.getters.getPrincipalByUrl(url)) {\n return;\n }\n const principal = await findPrincipalByUrl(url);\n if (!principal) {\n // TODO - handle error\n return;\n }\n context.commit('addPrincipal', {\n principal: mapDavToPrincipal(principal)\n });\n },\n /**\r\n * Fetches the current-user-principal\r\n *\r\n * @param {object} context The vuex context\r\n * @return {Promise}\r\n */\n async fetchCurrentUserPrincipal(context) {\n const currentUserPrincipal = getCurrentUserPrincipal();\n if (!currentUserPrincipal) {\n // TODO - handle error\n return;\n }\n const principal = mapDavToPrincipal(currentUserPrincipal);\n context.commit('addPrincipal', {\n principal\n });\n context.commit('setCurrentUserPrincipal', {\n principalId: principal.id\n });\n logger.debug(\"Current user principal is \".concat(principal.url));\n },\n /**\r\n * Change a principal's schedule-default-calendar-URL\r\n *\r\n * @param {object} context The vuex context\r\n * @param {object} data The destructuring object\r\n * @param {object} data.principal The principal to modify\r\n * @param {string} data.scheduleDefaultCalendarUrl The new schedule-default-calendar-URL\r\n * @return {Promise}\r\n */\n async changePrincipalScheduleDefaultCalendarUrl(context, _ref5) {\n let {\n principal,\n scheduleDefaultCalendarUrl\n } = _ref5;\n principal.dav.scheduleDefaultCalendarUrl = scheduleDefaultCalendarUrl;\n await principal.dav.update();\n context.commit('changePrincipalScheduleDefaultCalendarUrl', {\n principal,\n scheduleDefaultCalendarUrl\n });\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n * @copyright Copyright (c) 2022 Informatyka Boguslawski sp. z o.o. sp.k., http://www.ib.pl/\r\n *\r\n * @author Georg Ehrke \r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { enableBirthdayCalendar } from '../services/caldavService.js';\nimport { mapDavCollectionToCalendar } from '../models/calendar.js';\nimport { detectTimezone } from '../services/timezoneDetectionService.js';\nimport { setConfig as setCalendarJsConfig } from '@nextcloud/calendar-js';\nimport { setConfig } from '../services/settings.js';\nimport { logInfo } from '../utils/logger.js';\nimport getTimezoneManager from '../services/timezoneDataProviderService.js';\nimport * as AttachmentService from '../services/attachmentService.js';\nconst state = {\n // env\n appVersion: null,\n firstRun: null,\n talkEnabled: false,\n disableAppointments: false,\n publicCalendars: null,\n // user-defined calendar settings\n eventLimit: null,\n showTasks: null,\n showWeekends: null,\n showWeekNumbers: null,\n skipPopover: null,\n slotDuration: null,\n defaultReminder: null,\n tasksEnabled: false,\n timezone: 'automatic',\n hideEventExport: false,\n forceEventAlarmType: false,\n canSubscribeLink: true,\n showResources: true,\n // user-defined Nextcloud settings\n momentLocale: 'en',\n attachmentsFolder: '/Calendar',\n attachmentsFolderCreated: false\n};\nconst mutations = {\n /**\r\n * Updates the user's setting for event limit\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleEventLimitEnabled(state) {\n state.eventLimit = !state.eventLimit;\n },\n /**\r\n * Updates the user's setting for visibility of event popover\r\n *\r\n * @param {object} state The Vuex state\r\n */\n togglePopoverEnabled(state) {\n state.skipPopover = !state.skipPopover;\n },\n /**\r\n * Updates the user's setting for visibility of weekends\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleTasksEnabled(state) {\n state.showTasks = !state.showTasks;\n },\n /**\r\n * Updates the user's setting for visibility of weekends\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleWeekendsEnabled(state) {\n state.showWeekends = !state.showWeekends;\n },\n /**\r\n * Updates the user's setting for visibility of week numbers\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleWeekNumberEnabled(state) {\n state.showWeekNumbers = !state.showWeekNumbers;\n },\n /**\r\n * Updates the user's preferred slotDuration\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.slotDuration The new slot duration\r\n */\n setSlotDuration(state, _ref) {\n let {\n slotDuration\n } = _ref;\n state.slotDuration = slotDuration;\n },\n /**\r\n * Updates the user's preferred defaultReminder\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.defaultReminder The new default reminder length\r\n */\n setDefaultReminder(state, _ref2) {\n let {\n defaultReminder\n } = _ref2;\n state.defaultReminder = defaultReminder;\n },\n /**\r\n * Updates the user's timezone\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.timezoneId The new timezone\r\n */\n setTimezone(state, _ref3) {\n let {\n timezoneId\n } = _ref3;\n state.timezone = timezoneId;\n },\n /**\r\n * Updates the user's attachments folder\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.attachmentsFolder The new attachments folder\r\n */\n setAttachmentsFolder(state, _ref4) {\n let {\n attachmentsFolder\n } = _ref4;\n state.attachmentsFolder = attachmentsFolder;\n state.attachmentsFolderCreated = false;\n },\n /**\r\n * Update wheter the user's attachments folder has been created\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {boolean} data.attachmentsFolderCreated True if the folder has been created\r\n */\n setAttachmentsFolderCreated(state, _ref5) {\n let {\n attachmentsFolderCreated\n } = _ref5;\n state.attachmentsFolderCreated = attachmentsFolderCreated;\n },\n /**\r\n * Initialize settings\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.appVersion The version of the Nextcloud app\r\n * @param {boolean} data.eventLimit Whether or not to limit number of visible events in grid view\r\n * @param {boolean} data.firstRun Whether or not this is the first run\r\n * @param {boolean} data.showWeekNumbers Whether or not to show week numbers\r\n * @param {boolean} data.showTasks Whether or not to display tasks with a due-date\r\n * @param {boolean} data.showWeekends Whether or not to display weekends\r\n * @param {boolean} data.skipPopover Whether or not to skip the simple event popover\r\n * @param {string} data.slotDuration The duration of one slot in the agendaView\r\n * @param {string} data.defaultReminder The default reminder to set on newly created events\r\n * @param {boolean} data.talkEnabled Whether or not the talk app is enabled\r\n * @param {boolean} data.tasksEnabled Whether ot not the tasks app is enabled\r\n * @param {string} data.timezone The timezone to view the calendar in. Either an Olsen timezone or \"automatic\"\r\n * @param {boolean} data.hideEventExport\r\n * @param {string} data.forceEventAlarmType\r\n * @param {boolean} data.disableAppointments Allow to disable the appointments feature\r\n * @param {boolean} data.canSubscribeLink\r\n * @param {string} data.attachmentsFolder Default user's attachments folder\r\n * @param {boolean} data.showResources Show or hide the resources tab\r\n * @param {string} data.publicCalendars\r\n */\n loadSettingsFromServer(state, _ref6) {\n let {\n appVersion,\n eventLimit,\n firstRun,\n showWeekNumbers,\n showTasks,\n showWeekends,\n skipPopover,\n slotDuration,\n defaultReminder,\n talkEnabled,\n tasksEnabled,\n timezone,\n hideEventExport,\n forceEventAlarmType,\n disableAppointments,\n canSubscribeLink,\n attachmentsFolder,\n showResources,\n publicCalendars\n } = _ref6;\n logInfo(\"\\nInitial settings:\\n\\t- AppVersion: \".concat(appVersion, \"\\n\\t- EventLimit: \").concat(eventLimit, \"\\n\\t- FirstRun: \").concat(firstRun, \"\\n\\t- ShowWeekNumbers: \").concat(showWeekNumbers, \"\\n\\t- ShowTasks: \").concat(showTasks, \"\\n\\t- ShowWeekends: \").concat(showWeekends, \"\\n\\t- SkipPopover: \").concat(skipPopover, \"\\n\\t- SlotDuration: \").concat(slotDuration, \"\\n\\t- DefaultReminder: \").concat(defaultReminder, \"\\n\\t- TalkEnabled: \").concat(talkEnabled, \"\\n\\t- TasksEnabled: \").concat(tasksEnabled, \"\\n\\t- Timezone: \").concat(timezone, \"\\n\\t- HideEventExport: \").concat(hideEventExport, \"\\n\\t- ForceEventAlarmType: \").concat(forceEventAlarmType, \"\\n\\t- disableAppointments: \").concat(disableAppointments, \"\\n\\t- CanSubscribeLink: \").concat(canSubscribeLink, \"\\n\\t- attachmentsFolder: \").concat(attachmentsFolder, \"\\n\\t- ShowResources: \").concat(showResources, \"\\n\\t- PublicCalendars: \").concat(publicCalendars, \"\\n\"));\n state.appVersion = appVersion;\n state.eventLimit = eventLimit;\n state.firstRun = firstRun;\n state.showWeekNumbers = showWeekNumbers;\n state.showTasks = showTasks;\n state.showWeekends = showWeekends;\n state.skipPopover = skipPopover;\n state.slotDuration = slotDuration;\n state.defaultReminder = defaultReminder;\n state.talkEnabled = talkEnabled;\n state.tasksEnabled = tasksEnabled;\n state.timezone = timezone;\n state.hideEventExport = hideEventExport;\n state.forceEventAlarmType = forceEventAlarmType;\n state.disableAppointments = disableAppointments;\n state.canSubscribeLink = canSubscribeLink;\n state.attachmentsFolder = attachmentsFolder;\n state.showResources = showResources;\n state.publicCalendars = publicCalendars;\n },\n /**\r\n * Sets the name of the moment.js locale to be used\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.locale The moment.js locale to be used\r\n */\n setMomentLocale(state, _ref7) {\n let {\n locale\n } = _ref7;\n logInfo(\"Updated moment locale: \".concat(locale));\n state.momentLocale = locale;\n }\n};\nconst getters = {\n isTalkEnabled: state => state.talkEnabled,\n /**\r\n * Gets the resolved timezone.\r\n * If the timezone is set to automatic, it returns the user's current timezone\r\n * Otherwise, it returns the Olsen timezone stored\r\n *\r\n * @param {object} state The Vuex state\r\n * @return {string}\r\n */\n getResolvedTimezone: state => state.timezone === 'automatic' ? detectTimezone() : state.timezone,\n /**\r\n * Gets the resolved timezone object.\r\n * Falls back to UTC if timezone is invalid.\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} getters The vuex getters\r\n * @return {object} The calendar-js timezone object\r\n */\n getResolvedTimezoneObject: (state, getters) => {\n const timezone = getters.getResolvedTimezone;\n let timezoneObject = getTimezoneManager().getTimezoneForId(timezone);\n if (!timezoneObject) {\n timezoneObject = getTimezoneManager().getTimezoneForId('UTC');\n }\n return timezoneObject;\n }\n};\nconst actions = {\n /**\r\n * Updates the user's setting for visibility of birthday calendar\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.getters The Vuex Getters\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {Function} vuex.dispatch The Vuex dispatch Function\r\n * @return {Promise}\r\n */\n async toggleBirthdayCalendarEnabled(_ref8) {\n let {\n getters,\n commit,\n dispatch\n } = _ref8;\n if (getters.hasBirthdayCalendar) {\n const calendar = getters.getBirthdayCalendar;\n await dispatch('deleteCalendar', {\n calendar\n });\n } else {\n const davCalendar = await enableBirthdayCalendar();\n const calendar = mapDavCollectionToCalendar(davCalendar);\n commit('addCalendar', {\n calendar\n });\n }\n },\n /**\r\n * Updates the user's setting for event limit\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @return {Promise}\r\n */\n async toggleEventLimitEnabled(_ref9) {\n let {\n state,\n commit\n } = _ref9;\n const newState = !state.eventLimit;\n const value = newState ? 'yes' : 'no';\n await setConfig('eventLimit', value);\n commit('toggleEventLimitEnabled');\n },\n /**\r\n * Updates the user's setting for visibility of event popover\r\n *\r\n * @param {object} context The Vuex context\r\n * @param {object} context.state The store state\r\n * @param {object} context.commit The store mutations\r\n * @return {Promise}\r\n */\n async togglePopoverEnabled(_ref10) {\n let {\n state,\n commit\n } = _ref10;\n const newState = !state.skipPopover;\n const value = newState ? 'yes' : 'no';\n await setConfig('skipPopover', value);\n commit('togglePopoverEnabled');\n },\n /**\r\n * Updates the user's setting for visibility of weekends\r\n *\r\n * @param {object} context The Vuex context\r\n * @param {object} context.state The store state\r\n * @param {object} context.commit The store mutations\r\n * @return {Promise}\r\n */\n async toggleWeekendsEnabled(_ref11) {\n let {\n state,\n commit\n } = _ref11;\n const newState = !state.showWeekends;\n const value = newState ? 'yes' : 'no';\n await setConfig('showWeekends', value);\n commit('toggleWeekendsEnabled');\n },\n /**\r\n * Updates the user's setting for visibility of tasks\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @return {Promise}\r\n */\n async toggleTasksEnabled(_ref12) {\n let {\n state,\n commit\n } = _ref12;\n const newState = !state.showTasks;\n const value = newState ? 'yes' : 'no';\n await setConfig('showTasks', value);\n commit('toggleTasksEnabled');\n commit('clearFetchedTimeRanges');\n commit('incrementModificationCount');\n },\n /**\r\n * Updates the user's setting for visibility of week numbers\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @return {Promise}\r\n */\n async toggleWeekNumberEnabled(_ref13) {\n let {\n state,\n commit\n } = _ref13;\n const newState = !state.showWeekNumbers;\n const value = newState ? 'yes' : 'no';\n await setConfig('showWeekNr', value);\n commit('toggleWeekNumberEnabled');\n },\n /**\r\n * Updates the view to be used as initial view when opening\r\n * the calendar app again\r\n *\r\n * @param {object} context The Vuex destructuring object\r\n * @param {object} data The destructuring object\r\n * @param {string} data.initialView New view to be used as initial view\r\n * @return {Promise}\r\n */\n async setInitialView(context, _ref14) {\n let {\n initialView\n } = _ref14;\n await setConfig('view', initialView);\n },\n /**\r\n * Updates the user's preferred slotDuration\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.slotDuration The new slot duration\r\n */\n async setSlotDuration(_ref15, _ref16) {\n let {\n state,\n commit\n } = _ref15;\n let {\n slotDuration\n } = _ref16;\n if (state.slotDuration === slotDuration) {\n return;\n }\n await setConfig('slotDuration', slotDuration);\n commit('setSlotDuration', {\n slotDuration\n });\n },\n /**\r\n * Updates the user's preferred defaultReminder\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.defaultReminder The new default reminder\r\n */\n async setDefaultReminder(_ref17, _ref18) {\n let {\n state,\n commit\n } = _ref17;\n let {\n defaultReminder\n } = _ref18;\n if (state.defaultReminder === defaultReminder) {\n return;\n }\n await setConfig('defaultReminder', defaultReminder);\n commit('setDefaultReminder', {\n defaultReminder\n });\n },\n /**\r\n * Updates the user's timezone\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.timezoneId The new timezone\r\n * @return {Promise}\r\n */\n async setTimezone(_ref19, _ref20) {\n let {\n state,\n commit\n } = _ref19;\n let {\n timezoneId\n } = _ref20;\n if (state.timezone === timezoneId) {\n return;\n }\n await setConfig('timezone', timezoneId);\n commit('setTimezone', {\n timezoneId\n });\n },\n /**\r\n * Updates the user's attachments folder\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.attachmentsFolder The new attachments folder\r\n * @return {Promise}\r\n */\n async setAttachmentsFolder(_ref21, _ref22) {\n let {\n state,\n commit\n } = _ref21;\n let {\n attachmentsFolder\n } = _ref22;\n if (state.attachmentsFolder === attachmentsFolder) {\n return;\n }\n await setConfig('attachmentsFolder', attachmentsFolder);\n commit('setAttachmentsFolder', {\n attachmentsFolder\n });\n },\n /**\r\n * Create the user's attachment folder if it doesn't exist and return its path\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {Function} vuex.dispatch The Vuex commit function\r\n * @param {object} vuex.getters The Vuex getters object\r\n * @return {Promise} The path of the user's attachments folder\r\n */\n async createAttachmentsFolder(_ref23) {\n let {\n state,\n commit,\n dispatch,\n getters\n } = _ref23;\n if (state.attachmentsFolderCreated) {\n return state.attachmentsFolder;\n }\n const userId = getters.getCurrentUserPrincipal.dav.userId;\n const path = await AttachmentService.createFolder(state.attachmentsFolder, userId);\n if (path !== state.attachmentsFolder) {\n await dispatch('setAttachmentsFolder', {\n attachmentsFolder: path\n });\n }\n commit('setAttachmentsFolderCreated', {\n attachmentsFolderCreated: true\n });\n return path;\n },\n /**\r\n * Initializes the calendar-js configuration\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n */\n initializeCalendarJsConfig(_ref24) {\n let {\n state\n } = _ref24;\n setCalendarJsConfig('PRODID', \"-//IDN nextcloud.com//Calendar app \".concat(state.appVersion, \"//EN\"));\n setCalendarJsConfig('property-list-significant-change', ['SUMMARY', 'LOCATION', 'DESCRIPTION', 'CLIENT']);\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","import roleService from \"../services/roleService\";\nconst state = {\n roles: [] // Store the roles here\n};\nconst mutations = {\n setUserRole(state, roles) {\n state.roles = roles;\n }\n};\nconst actions = {\n async fetchUserRoles(_ref) {\n let {\n commit\n } = _ref;\n try {\n // Pass commit to the service\n await roleService.fetchAndCommitRoles(commit);\n } catch (error) {}\n }\n};\nconst getters = {\n isAdmin: state => state.roles.includes(\"admin\"),\n canAccessPreviousEvent: state => state.roles.includes(\"Ligne\") == false && state.roles.includes(\"ligne\") == false\n};\nexport default {\n namespaced: true,\n state,\n mutations,\n actions,\n getters\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport { AttendeeProperty, Property } from '@nextcloud/calendar-js';\nimport { translate as t } from '@nextcloud/l10n';\n\n/**\r\n * Get the factor for a given unit\r\n *\r\n * @param {string} unit The name of the unit to get the factor of\r\n * @return {number}\r\n */\nexport function getFactorForAlarmUnit(unit) {\n switch (unit) {\n case 'seconds':\n return 1;\n case 'minutes':\n return 60;\n case 'hours':\n return 60 * 60;\n case 'days':\n return 24 * 60 * 60;\n case 'weeks':\n return 7 * 24 * 60 * 60;\n default:\n return 1;\n }\n}\n\n/**\r\n * Gets the amount of days / weeks, unit from total seconds\r\n *\r\n * @param {number} totalSeconds Total amount of seconds\r\n * @return {{amount: number, unit: string}}\r\n */\nexport function getAmountAndUnitForTimedEvents(totalSeconds) {\n // Before or after the event is handled somewhere else,\n // so make sure totalSeconds is positive\n totalSeconds = Math.abs(totalSeconds);\n\n // Handle the special case of 0, so we don't show 0 weeks\n if (totalSeconds === 0) {\n return {\n amount: 0,\n unit: 'minutes'\n };\n }\n if (totalSeconds % (7 * 24 * 60 * 60) === 0) {\n return {\n amount: totalSeconds / (7 * 24 * 60 * 60),\n unit: 'weeks'\n };\n }\n if (totalSeconds % (24 * 60 * 60) === 0) {\n return {\n amount: totalSeconds / (24 * 60 * 60),\n unit: 'days'\n };\n }\n if (totalSeconds % (60 * 60) === 0) {\n return {\n amount: totalSeconds / (60 * 60),\n unit: 'hours'\n };\n }\n if (totalSeconds % 60 === 0) {\n return {\n amount: totalSeconds / 60,\n unit: 'minutes'\n };\n }\n return {\n amount: totalSeconds,\n unit: 'seconds'\n };\n}\n\n/**\r\n * Get the total amount of seconds based on amount and unit for timed events\r\n *\r\n * @param {number} amount Amount of unit\r\n * @param {string} unit Minutes/Hours/Days/Weeks\r\n * @param {boolean=} isBefore Whether the reminder is before or after the event\r\n * @return {number}\r\n */\nexport function getTotalSecondsFromAmountAndUnitForTimedEvents(amount, unit) {\n let isBefore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n return amount * getFactorForAlarmUnit(unit) * (isBefore ? -1 : 1);\n}\n\n/**\r\n * Gets the amount of days / weeks, unit, hours and minutes from total seconds\r\n *\r\n * @param {number} totalSeconds Total amount of seconds\r\n * @return {{amount: *, unit: *, hours: *, minutes: *}}\r\n */\nexport function getAmountHoursMinutesAndUnitForAllDayEvents(totalSeconds) {\n const dayFactor = getFactorForAlarmUnit('days');\n const hourFactor = getFactorForAlarmUnit('hours');\n const minuteFactor = getFactorForAlarmUnit('minutes');\n const isNegative = totalSeconds < 0;\n totalSeconds = Math.abs(totalSeconds);\n let dayPart = Math.floor(totalSeconds / dayFactor);\n const hourPart = totalSeconds % dayFactor;\n if (hourPart !== 0) {\n if (isNegative) {\n dayPart++;\n }\n }\n let amount = 0;\n let unit = null;\n if (dayPart === 0) {\n unit = 'days';\n } else if (dayPart % 7 === 0) {\n amount = dayPart / 7;\n unit = 'weeks';\n } else {\n amount = dayPart;\n unit = 'days';\n }\n let hours = Math.floor(hourPart / hourFactor);\n const minutePart = hourPart % hourFactor;\n let minutes = Math.floor(minutePart / minuteFactor);\n if (isNegative) {\n hours = 24 - hours;\n if (minutes !== 0) {\n hours--;\n minutes = 60 - minutes;\n }\n }\n return {\n amount,\n unit,\n hours,\n minutes\n };\n}\n\n/**\r\n * Get the total amount of seconds for all-day events\r\n *\r\n * @param {number} amount amount of unit\r\n * @param {number} hours Time of reminder\r\n * @param {number} minutes Time of reminder\r\n * @param {string} unit days/weeks\r\n * @return {number}\r\n */\nexport function getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(amount, hours, minutes, unit) {\n if (unit === 'weeks') {\n amount *= 7;\n unit = 'days';\n }\n\n // 0 is on the same day of the all-day event => positive\n // 1 ... n before the event is negative\n const isNegative = amount > 0;\n if (isNegative) {\n // If it's negative, we need to subtract one day\n amount--;\n // Convert days to seconds\n amount *= getFactorForAlarmUnit(unit);\n let invertedHours = 24 - hours;\n let invertedMinutes = 0;\n if (minutes !== 0) {\n invertedHours--;\n invertedMinutes = 60 - minutes;\n }\n amount += invertedHours * getFactorForAlarmUnit('hours');\n amount += invertedMinutes * getFactorForAlarmUnit('minutes');\n amount *= -1;\n } else {\n // Convert days to seconds\n amount *= getFactorForAlarmUnit('days');\n amount += hours * getFactorForAlarmUnit('hours');\n amount += minutes * getFactorForAlarmUnit('minutes');\n }\n return amount;\n}\n\n/**\r\n * Propagate data from an event component to all EMAIL alarm components.\r\n * An alarm component must contain a description, summary and all attendees to be notified.\r\n * We don't have a separate UI for maintaining attendees of an alarm, so we just copy them from the event.\r\n *\r\n * https://www.rfc-editor.org/rfc/rfc5545#section-3.6.6\r\n *\r\n * @param {AbstractRecurringComponent} eventComponent\r\n */\nexport function updateAlarms(eventComponent) {\n for (const alarmComponent of eventComponent.getAlarmIterator()) {\n if (alarmComponent.action !== 'EMAIL' && alarmComponent.action !== 'DISPLAY') {\n continue;\n }\n alarmComponent.deleteAllProperties('SUMMARY');\n const summaryProperty = eventComponent.getFirstProperty('SUMMARY');\n if (summaryProperty) {\n alarmComponent.addProperty(summaryProperty.clone());\n } else {\n const defaultSummary = t('calendar', 'Untitled event');\n alarmComponent.addProperty(new Property('SUMMARY', defaultSummary));\n }\n if (!alarmComponent.hasProperty('DESCRIPTION')) {\n const defaultDescription = t('calendar', 'This is an event reminder.');\n alarmComponent.addProperty(new Property('DESCRIPTION', defaultDescription));\n }\n alarmComponent.deleteAllProperties('ATTENDEE');\n for (const attendee of eventComponent.getAttendeeIterator()) {\n if (['RESOURCE', 'ROOM'].includes(attendee.userType)) {\n continue;\n }\n\n // Only copy the email address (value) of the attendee\n alarmComponent.addProperty(new AttendeeProperty('ATTENDEE', attendee.value));\n }\n }\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Gets the ByDay and BySetPosition\r\n *\r\n * @param {Date} jsDate The date to get the weekday of\r\n * @return {object}\r\n */\nexport function getBySetPositionAndBySetFromDate(jsDate) {\n const byDay = getWeekDayFromDate(jsDate);\n let bySetPosition = 1;\n let dayOfMonth = jsDate.getDate();\n for (; dayOfMonth > 7; dayOfMonth -= 7) {\n bySetPosition++;\n }\n return {\n byDay,\n bySetPosition\n };\n}\n\n/**\r\n * Gets the string-representation of the weekday of a given date\r\n *\r\n * @param {Date} jsDate The date to get the weekday of\r\n * @return {string}\r\n */\nexport function getWeekDayFromDate(jsDate) {\n switch (jsDate.getDay()) {\n case 0:\n return 'SU';\n case 1:\n return 'MO';\n case 2:\n return 'TU';\n case 3:\n return 'WE';\n case 4:\n return 'TH';\n case 5:\n return 'FR';\n case 6:\n return 'SA';\n default:\n throw TypeError('Invalid date-object given');\n }\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { linkTo } from '@nextcloud/router';\n\n/**\r\n * Get URL to modify config-key\r\n *\r\n * @param {string} key URL of config-key to modify\r\n * @return {string}\r\n */\nexport function getLinkToConfig(key) {\n return [linkTo('calendar', 'index.php'), 'v1/config', key].join('/');\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"calendar-src_store_index_js.js?v=fcfc2d6839479e13e5cc","mappings":";;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;AC3KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACtIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;AClFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AClHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACxYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACnNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACj8EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;AC9cA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACx3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC9QA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACnGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACpjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC3OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["webpack:///calendar/src\\models\\alarm.js","webpack:///calendar/src\\models\\attachment.js","webpack:///calendar/src\\models\\attendee.js","webpack:///calendar/src\\models\\calendar.js","webpack:///calendar/src\\models\\calendarObject.js","webpack:///calendar/src\\models\\calendarShare.js","webpack:///calendar/src\\models\\event.js","webpack:///calendar/src\\models\\principal.js","webpack:///calendar/src\\models\\recurrenceRule.js","webpack:///calendar/src\\services\\attachmentService.js","webpack:///calendar/src\\services\\roleService.js","webpack:///calendar/src\\services\\settings.js","webpack:///calendar/src\\store\\calendarObjectInstance.js","webpack:///calendar/src\\store\\calendarObjects.js","webpack:///calendar/src\\store\\calendars.js","webpack:///calendar/src\\store\\contacts.js","webpack:///calendar/src\\store\\davRestrictions.js","webpack:///calendar/src\\store\\fetchedTimeRanges.js","webpack:///calendar/src\\store\\importFiles.js","webpack:///calendar/src\\store\\importState.js","webpack:///calendar/src\\store\\index.js","webpack:///calendar/src\\store\\principals.js","webpack:///calendar/src\\store\\settings.js","webpack:///calendar/src\\store\\userRole.js","webpack:///calendar/src\\utils\\alarms.js","webpack:///calendar/src\\utils\\recurrence.js","webpack:///calendar/src\\utils\\settings.js"],"sourcesContent":["/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getAmountAndUnitForTimedEvents, getAmountHoursMinutesAndUnitForAllDayEvents } from '../utils/alarms.js';\nimport { getDateFromDateTimeValue } from '../utils/date.js';\n\n/**\r\n * Creates a complete alarm object based on given props\r\n *\r\n * @param {object} props The alarm properties already provided\r\n * @return {object}\r\n */\nconst getDefaultAlarmObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js alarm component\n alarmComponent: null,\n // Type of alarm: DISPLAY, EMAIL, AUDIO\n type: null,\n // Whether or not the alarm is relative\n isRelative: false,\n // Date object of an absolute alarm (if it's absolute, it must be DATE-TIME)\n absoluteDate: null,\n // The time zone id of for absolute alarms\n absoluteTimezoneId: null,\n // Whether or not the relative alarm is before the event,\n relativeIsBefore: null,\n // Whether or not the alarm is relative to the event's start\n relativeIsRelatedToStart: null,\n // TIMED EVENTS:\n // Unit (seconds, minutes, hours, ...) if this alarm is inside a timed event\n relativeUnitTimed: null,\n // The amount of unit if this alarm is inside a timed event\n relativeAmountTimed: null,\n // ALL-DAY EVENTS:\n // Unit (seconds, minutes, hours, ...) if this alarm is inside an all-day event\n relativeUnitAllDay: null,\n // The amount of unit if this alarm is inside a all-day event\n relativeAmountAllDay: null,\n // The hours to display alarm for in an all-day event (e.g. 1 day before at 9:00 am)\n relativeHoursAllDay: null,\n // The minutes to display alarm for in an all-day event (e.g. 1 day before at 9:30 am)\n relativeMinutesAllDay: null,\n // The total amount of seconds for a relative alarm\n relativeTrigger: null\n }, props);\n};\n\n/**\r\n * Map an alarm component to our alarm object\r\n *\r\n * @param {AlarmComponent} alarmComponent The calendar-js alarm-component to turn into an alarm object\r\n * @return {object}\r\n */\nconst mapAlarmComponentToAlarmObject = alarmComponent => {\n if (alarmComponent.trigger.isRelative()) {\n const relativeIsBefore = alarmComponent.trigger.value.isNegative;\n const relativeIsRelatedToStart = alarmComponent.trigger.related === 'START';\n const {\n amount: relativeAmountTimed,\n unit: relativeUnitTimed\n } = getAmountAndUnitForTimedEvents(alarmComponent.trigger.value.totalSeconds);\n const {\n unit: relativeUnitAllDay,\n amount: relativeAmountAllDay,\n hours: relativeHoursAllDay,\n minutes: relativeMinutesAllDay\n } = getAmountHoursMinutesAndUnitForAllDayEvents(alarmComponent.trigger.value.totalSeconds);\n const relativeTrigger = alarmComponent.trigger.value.totalSeconds;\n return getDefaultAlarmObject({\n alarmComponent,\n type: alarmComponent.action,\n isRelative: alarmComponent.trigger.isRelative(),\n relativeIsBefore,\n relativeIsRelatedToStart,\n relativeUnitTimed,\n relativeAmountTimed,\n relativeUnitAllDay,\n relativeAmountAllDay,\n relativeHoursAllDay,\n relativeMinutesAllDay,\n relativeTrigger\n });\n } else {\n const absoluteDate = getDateFromDateTimeValue(alarmComponent.trigger.value);\n return getDefaultAlarmObject({\n alarmComponent,\n type: alarmComponent.action,\n isRelative: alarmComponent.trigger.isRelative(),\n absoluteDate,\n absoluteTimezoneId: alarmComponent.trigger.value.timezoneId\n });\n }\n};\nexport { getDefaultAlarmObject, mapAlarmComponentToAlarmObject };","/**\r\n * @copyright Copyright (c) 2022 Mikhail Sazanov\r\n *\r\n * @author Mikhail Sazanov \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Creates a complete attachment object based on given props\r\n *\r\n * @param {object} props The attachment properties already provided\r\n * @return {object}\r\n */\nconst getDefaultAttachmentObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js attachment property\n attachmentProperty: null,\n // The file name of the attachment\n fileName: null,\n // The attachment mime type\n formatType: null,\n // The uri of the attachment\n uri: null,\n // The value from calendar object\n value: null,\n // Preview of file\n xNcHasPreview: null,\n // File id in NC\n xNcFileId: null\n }, props);\n};\n\n/**\r\n * Maps a calendar-js attachment property to our attachment object\r\n *\r\n * @param {attachmentProperty} attachmentProperty The calendar-js attachmentProperty to turn into a attachment object\r\n * @return {object}\r\n */\nconst mapAttachmentPropertyToAttchmentObject = attachmentProperty => {\n return getDefaultAttachmentObject({\n attachmentProperty,\n fileName: attachmentProperty.getParameterFirstValue('FILENAME'),\n formatType: attachmentProperty.formatType,\n uri: attachmentProperty.uri,\n value: attachmentProperty.value,\n xNcHasPreview: attachmentProperty.getParameterFirstValue('X-NC-HAS-PREVIEW') === 'true',\n xNcFileId: attachmentProperty.getParameterFirstValue('X-NC-FILE-ID')\n });\n};\nexport { getDefaultAttachmentObject, mapAttachmentPropertyToAttchmentObject };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n * @copyright Copyright (c) 2023 Jonas Heinrich\r\n *\r\n * @author Georg Ehrke \r\n * @author Jonas Heinrich \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Creates a complete attendee object based on given props\r\n *\r\n * TODO:\r\n * - we should eventually support delegatedFrom and delegatedTo\r\n *\r\n * @param {object} props The attendee properties already provided\r\n * @return {object}\r\n */\nconst getDefaultAttendeeObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js attendee property\n attendeeProperty: null,\n // The display-name of the attendee\n commonName: null,\n // The calendar-user-type of the attendee\n calendarUserType: 'INDIVIDUAL',\n // The participation status of the attendee\n participationStatus: 'NEEDS-ACTION',\n // The role of the attendee\n role: 'REQ-PARTICIPANT',\n // The RSVP for the attendee\n rsvp: false,\n // The uri of the attendee\n uri: null,\n // Member address of the attendee\n member: null\n }, props);\n};\n\n/**\r\n * Maps a calendar-js attendee property to our attendee object\r\n *\r\n * @param {AttendeeProperty} attendeeProperty The calendar-js attendeeProperty to turn into a attendee object\r\n * @return {object}\r\n */\nconst mapAttendeePropertyToAttendeeObject = attendeeProperty => {\n return getDefaultAttendeeObject({\n attendeeProperty,\n commonName: attendeeProperty.commonName,\n calendarUserType: attendeeProperty.userType,\n participationStatus: attendeeProperty.participationStatus,\n role: attendeeProperty.role,\n rsvp: attendeeProperty.rsvp,\n uri: attendeeProperty.email,\n member: attendeeProperty.member\n });\n};\nexport { getDefaultAttendeeObject, mapAttendeePropertyToAttendeeObject };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { detectColor, uidToHexColor } from '../utils/color.js';\nimport { mapDavShareeToCalendarShareObject } from './calendarShare.js';\n\n/**\r\n * Creates a complete calendar-object based on given props\r\n *\r\n * @param {object} props Calendar-props already provided\r\n * @return {object}\r\n */\nconst getDefaultCalendarObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // Id of the calendar\n id: '',\n // Visible display name\n displayName: '',\n // Color of the calendar\n color: uidToHexColor(''),\n // Whether or not the calendar is visible in the grid\n enabled: true,\n // Whether or not the calendar is loading events at the moment\n loading: false,\n // Whether this calendar supports VEvents\n supportsEvents: true,\n // Whether this calendar supports VJournals\n supportsJournals: false,\n // Whether this calendar supports VTodos\n supportsTasks: false,\n // The principal uri of the owner\n owner: '',\n // Timezone set for this calendar\n timezone: null,\n // List of shares\n shares: [],\n // Published url\n publishURL: null,\n // Internal CalDAV url of this calendar\n url: '',\n // Whether this calendar is read-only\n readOnly: false,\n // The order of this calendar in the calendar-list\n order: 0,\n // Whether or not the calendar is shared with me\n isSharedWithMe: false,\n // Whether or not the calendar can be shared by me\n canBeShared: false,\n // Whether or not the calendar can be published by me\n canBePublished: false,\n // Reference to cdav-lib object\n dav: false,\n // All calendar-objects from this calendar that have already been fetched\n calendarObjects: [],\n // Time-ranges that have already been fetched for this calendar\n fetchedTimeRanges: []\n }, props);\n};\n\n/**\r\n * Map a dav collection to our calendar object model\r\n *\r\n * @param {object} calendar The calendar object from the cdav library\r\n * @param {object=} currentUserPrincipal The principal model of the current user principal\r\n * @return {object}\r\n */\nconst mapDavCollectionToCalendar = (calendar, currentUserPrincipal) => {\n const id = btoa(calendar.url);\n const displayName = calendar.displayname || getCalendarUriFromUrl(calendar.url);\n\n // calendar.color can be set to anything on the server,\n // so make sure it's something that remotely looks like a color\n let color = detectColor(calendar.color);\n if (!color) {\n // As fallback if we don't know what color that is supposed to be\n color = uidToHexColor(displayName);\n }\n const supportsEvents = calendar.components.includes('VEVENT');\n const supportsJournals = calendar.components.includes('VJOURNAL');\n const supportsTasks = calendar.components.includes('VTODO');\n const owner = calendar.owner;\n const readOnly = !calendar.isWriteable();\n const canBeShared = calendar.isShareable();\n const canBePublished = calendar.isPublishable();\n const order = calendar.order || 0;\n const url = calendar.url;\n const publishURL = calendar.publishURL || null;\n const timezone = calendar.timezone || null;\n let isSharedWithMe = false;\n if (!currentUserPrincipal) {\n // If the user is not authenticated, the calendar\n // will always be marked as shared with them\n isSharedWithMe = true;\n } else {\n isSharedWithMe = owner !== currentUserPrincipal.url;\n }\n let enabled;\n if (!currentUserPrincipal) {\n // If the user is not authenticated,\n // always enable the calendar\n enabled = true;\n } else if (typeof calendar.enabled === 'boolean') {\n // If calendar-enabled is set, we will just take that\n enabled = calendar.enabled;\n } else {\n // If there is no calendar-enabled,\n // we will display the calendar by default and set enabled\n enabled = true;\n calendar.enabled = true;\n }\n const shares = [];\n if (!!currentUserPrincipal && Array.isArray(calendar.shares)) {\n for (const share of calendar.shares) {\n if (share.href === currentUserPrincipal.principalScheme) {\n continue;\n }\n shares.push(mapDavShareeToCalendarShareObject(share));\n }\n }\n return getDefaultCalendarObject({\n id,\n displayName,\n color,\n order,\n url,\n enabled,\n supportsEvents,\n supportsJournals,\n supportsTasks,\n isSharedWithMe,\n owner,\n readOnly,\n publishURL,\n canBeShared,\n canBePublished,\n shares,\n timezone,\n dav: calendar\n });\n};\n\n/**\r\n * Gets the calendar uri from the url\r\n *\r\n * @param {string} url The url to get calendar uri from\r\n * @return {string}\r\n */\nfunction getCalendarUriFromUrl(url) {\n if (url.endsWith('/')) {\n url = url.substring(0, url.length - 1);\n }\n return url.substring(url.lastIndexOf('/') + 1);\n}\nexport { getDefaultCalendarObject, mapDavCollectionToCalendar };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getParserManager } from '@nextcloud/calendar-js';\nimport { COMPONENT_NAME_EVENT, COMPONENT_NAME_JOURNAL, COMPONENT_NAME_VTODO } from './consts.js';\n\n/**\r\n * Creates a complete calendar-object-object based on given props\r\n *\r\n * @param {object} props Calendar-object-props already provided\r\n * @return {object}\r\n */\nconst getDefaultCalendarObjectObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // Id of this calendar-object\n id: null,\n // Id of the associated calendar\n calendarId: null,\n // The cdav-library object storing the calendar-object\n dav: null,\n // The parsed calendar-js object\n calendarComponent: null,\n // The uid of the calendar-object\n uid: null,\n // The uri of the calendar-object\n uri: null,\n // The type of calendar-object\n objectType: null,\n // Whether or not the calendar-object is an event\n isEvent: false,\n // Whether or not the calendar-object is a journal\n isJournal: false,\n // Whether or not the calendar-object is a task\n isTodo: false,\n // Whether or not the calendar-object exists on the server\n existsOnServer: false\n }, props);\n};\n\n/**\r\n * Maps a calendar-object from c-dav to our calendar-object object\r\n *\r\n * @param {VObject} dav The c-dav VObject\r\n * @param {string} calendarId The calendar-id this object is associated with\r\n * @return {object}\r\n */\nconst mapCDavObjectToCalendarObject = (dav, calendarId) => {\n const parserManager = getParserManager();\n const parser = parserManager.getParserForFileType('text/calendar');\n\n // This should not be the case, but let's just be on the safe side\n if (typeof dav.data !== 'string' || dav.data.trim() === '') {\n throw new Error('Empty calendar object');\n }\n parser.parse(dav.data);\n const calendarComponentIterator = parser.getItemIterator();\n const calendarComponent = calendarComponentIterator.next().value;\n if (!calendarComponent) {\n throw new Error('Empty calendar object');\n }\n const vObjectIterator = calendarComponent.getVObjectIterator();\n const firstVObject = vObjectIterator.next().value;\n return getDefaultCalendarObjectObject({\n id: btoa(dav.url),\n calendarId,\n dav,\n calendarComponent,\n uid: firstVObject.uid,\n uri: dav.url,\n objectType: firstVObject.name,\n isEvent: firstVObject.name === COMPONENT_NAME_EVENT,\n isJournal: firstVObject.name === COMPONENT_NAME_JOURNAL,\n isTodo: firstVObject.name === COMPONENT_NAME_VTODO,\n existsOnServer: true\n });\n};\n\n/**\r\n * Maps a calendar-component from calendar-js to our calendar-object object\r\n *\r\n * @param {CalendarComponent} calendarComponent The calendarComponent to create the calendarObject from\r\n * @param {string=} calendarId The associated calendar if applicable\r\n * @return {object}\r\n */\nconst mapCalendarJsToCalendarObject = function (calendarComponent) {\n let calendarId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n const vObjectIterator = calendarComponent.getVObjectIterator();\n const firstVObject = vObjectIterator.next().value;\n if (!firstVObject) {\n throw new Error('Calendar object without vobjects');\n }\n return getDefaultCalendarObjectObject({\n calendarId,\n calendarComponent,\n uid: firstVObject.uid,\n objectType: firstVObject.name,\n isEvent: firstVObject.name === COMPONENT_NAME_EVENT,\n isJournal: firstVObject.name === COMPONENT_NAME_JOURNAL,\n isTodo: firstVObject.name === COMPONENT_NAME_VTODO\n });\n};\nconst getKeyValueIcsProperty = (key, value) => {\n return \"\".concat(key, \":\").concat(value, \"\\r\\n\");\n};\nconst setCustomKeyValueToIcsAndReturnIcs = (ics, key, value) => {\n const property = getKeyValueIcsProperty(key, value);\n ics = ics.replace('END:VEVENT', \"\".concat(property, \"END:VEVENT\"));\n return ics;\n};\nconst setCustomKeyValuesArrayToIcsAndReturnIcs = (ics, keyValueArray) => {\n for (var key in keyValueArray) {\n const value = keyValueArray[key] ? keyValueArray[key] : '';\n ics = setCustomKeyValueToIcsAndReturnIcs(ics, key, value);\n }\n return ics;\n};\nexport { getDefaultCalendarObjectObject, mapCDavObjectToCalendarObject, mapCalendarJsToCalendarObject, setCustomKeyValuesArrayToIcsAndReturnIcs, getKeyValueIcsProperty, setCustomKeyValueToIcsAndReturnIcs };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { PRINCIPAL_PREFIX_CIRCLE, PRINCIPAL_PREFIX_GROUP, PRINCIPAL_PREFIX_USER } from './consts.js';\n\n/**\r\n * Creates a complete calendar-share-object based on given props\r\n *\r\n * @param {object} props Calendar-share-props already provided\r\n * @return {object}\r\n */\nconst getDefaultCalendarShareObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // Unique identifier\n id: null,\n // Displayname of the sharee\n displayName: null,\n // Whether or not share is writable\n writeable: false,\n // Whether or not sharee is an individual user\n isUser: false,\n // Whether or not sharee is an admin-defined group\n isGroup: false,\n // Whether or not sharee is a user-defined group\n isCircle: false,\n // Uri necessary for deleting / updating share\n uri: null\n }, props);\n};\n\n/**\r\n * Map a dav collection to our calendar object model\r\n *\r\n * @param {object} sharee The sharee object from the cdav library shares\r\n * @return {object}\r\n */\nconst mapDavShareeToCalendarShareObject = sharee => {\n // sharee.href might contain non-latin characters, so let's uri encode it first\n const id = btoa(encodeURI(sharee.href));\n let displayName;\n if (sharee['common-name'] && sharee['common-name'].trim() !== '') {\n displayName = sharee['common-name'];\n } else if (sharee.href.startsWith(PRINCIPAL_PREFIX_GROUP)) {\n displayName = decodeURIComponent(sharee.href.slice(28));\n } else if (sharee.href.startsWith(PRINCIPAL_PREFIX_USER)) {\n displayName = decodeURIComponent(sharee.href.slice(27));\n } else {\n displayName = sharee.href;\n }\n const writeable = sharee.access[0].endsWith('read-write');\n const isUser = sharee.href.startsWith(PRINCIPAL_PREFIX_USER);\n const isGroup = sharee.href.startsWith(PRINCIPAL_PREFIX_GROUP);\n const isCircle = sharee.href.startsWith(PRINCIPAL_PREFIX_CIRCLE);\n const uri = sharee.href;\n return getDefaultCalendarShareObject({\n id,\n displayName,\n writeable,\n isUser,\n isGroup,\n isCircle,\n uri\n });\n};\nexport { getDefaultCalendarShareObject, mapDavShareeToCalendarShareObject };","/**\n * @copyright Copyright (c) 2020 Georg Ehrke\n *\n * @author Georg Ehrke \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 .\n *\n */\n\nimport { getDateFromDateTimeValue } from '../utils/date.js';\nimport { DurationValue, DateTimeValue } from '@nextcloud/calendar-js';\nimport { getHexForColorName, getClosestCSS3ColorNameForHex } from '../utils/color.js';\nimport { mapAlarmComponentToAlarmObject } from './alarm.js';\nimport { mapAttendeePropertyToAttendeeObject } from './attendee.js';\nimport { mapAttachmentPropertyToAttchmentObject } from './attachment.js';\nimport { getDefaultRecurrenceRuleObject, mapRecurrenceRuleValueToRecurrenceRuleObject } from './recurrenceRule.js';\n\n/**\n * Creates a complete calendar-object-instance-object based on given props\n *\n * @param {object} props The props already provided\n * @return {object}\n */\nconst getDefaultEventObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The real event-component coming from calendar-js\n eventComponent: null,\n // Title of the event\n title: null,\n // Start date of the event\n startDate: null,\n // Timezone of the start date\n startTimezoneId: null,\n // End date of the event\n endDate: null,\n // Timezone of the end date\n endTimezoneId: null,\n // Indicator whether or not event is all-day\n isAllDay: false,\n // Whether or not the user is allowed to toggle the all-day checkbox\n canModifyAllDay: true,\n // Location that the event takes places in\n location: null,\n //client of the event\n client: null,\n //embalmer(Thanato) of the event\n embalmer: null,\n //Private\n isPrivate: false,\n // description of the event\n description: null,\n // Access class of the event (PUBLIC, PRIVATE, CONFIDENTIAL)\n accessClass: null,\n // Status of the event (CONFIRMED, TENTATIVE, CANCELLED)\n status: null,\n // Whether or not to block this event in Free-Busy reports (TRANSPARENT, OPAQUE)\n timeTransparency: null,\n // The recurrence rule of this event. We only support one recurrence-rule\n recurrenceRule: getDefaultRecurrenceRuleObject(),\n // Whether or not this event has multiple recurrence-rules\n hasMultipleRRules: false,\n // Whether or not this is the master item\n isMasterItem: false,\n // Whether or not this is a recurrence-exception\n isRecurrenceException: false,\n // Whether or not the applied modifications require to update this and all future\n forceThisAndAllFuture: false,\n // Whether or not it's possible to create a recurrence-exception for this event\n canCreateRecurrenceException: false,\n // Attendees of this event\n attendees: [],\n // Organizer of the event\n organizer: null,\n // Alarm of the event\n alarms: [],\n // Custom color of the event\n customColor: null,\n // Categories\n categories: [],\n // Attachments of this event\n attachments: []\n }, props);\n};\n\n/**\n *\n * @param {EventComponent} eventComponent The calendar-js eventComponent\n * @return {object}\n */\nconst mapEventComponentToEventObject = eventComponent => {\n const eventObject = getDefaultEventObject({\n eventComponent,\n title: eventComponent.title,\n isAllDay: eventComponent.isAllDay(),\n isPrivate: false,\n canModifyAllDay: eventComponent.canModifyAllDay(),\n location: eventComponent.location,\n client: \"CLIENT\",\n embalmer: \"TEST\",\n description: eventComponent.description,\n accessClass: eventComponent.accessClass,\n status: eventComponent.status,\n timeTransparency: eventComponent.timeTransparency,\n categories: Array.from(eventComponent.getCategoryIterator()),\n isMasterItem: eventComponent.isMasterItem(),\n isRecurrenceException: eventComponent.isRecurrenceException(),\n canCreateRecurrenceException: eventComponent.canCreateRecurrenceExceptions()\n });\n\n /**\n * According to RFC5545, DTEND is exclusive. This is rather intuitive for timed-events\n * but rather unintuitive for all-day events\n *\n * That's why, when an event is all-day from 2019-10-03 to 2019-10-04,\n * it will be displayed as 2019-10-03 to 2019-10-03 in the editor.\n */\n eventObject.startDate = getDateFromDateTimeValue(eventComponent.startDate);\n eventObject.startTimezoneId = eventComponent.startDate.timezoneId;\n if (eventComponent.isAllDay()) {\n const endDate = eventComponent.endDate.clone();\n endDate.addDuration(DurationValue.fromSeconds(-1 * 60 * 60 * 24));\n eventObject.endDate = getDateFromDateTimeValue(endDate);\n } else {\n eventObject.endDate = getDateFromDateTimeValue(eventComponent.endDate);\n }\n eventObject.endTimezoneId = eventComponent.endDate.timezoneId;\n\n /**\n * Extract organizer if there is any\n */\n if (eventComponent.organizer) {\n const organizerProperty = eventComponent.getFirstProperty('ORGANIZER');\n eventObject.organizer = {\n commonName: organizerProperty.commonName,\n uri: organizerProperty.email,\n attendeeProperty: organizerProperty\n };\n }\n\n /**\n * Extract alarms\n */\n for (const alarm of eventComponent.getAlarmIterator()) {\n eventObject.alarms.push(mapAlarmComponentToAlarmObject(alarm));\n }\n\n /**\n * Extract attendees\n */\n for (const attendee of eventComponent.getAttendeeIterator()) {\n eventObject.attendees.push(mapAttendeePropertyToAttendeeObject(attendee));\n }\n\n /**\n * Extract attachments\n */\n\n for (const attachment of eventComponent.getPropertyIterator('ATTACH')) {\n eventObject.attachments.push(mapAttachmentPropertyToAttchmentObject(attachment));\n }\n\n /**\n * Extract recurrence-rule\n */\n const recurrenceRuleIterator = eventComponent.getPropertyIterator('RRULE');\n const recurrenceRuleFirstIteration = recurrenceRuleIterator.next();\n const firstRecurrenceRule = recurrenceRuleFirstIteration.value;\n if (firstRecurrenceRule) {\n eventObject.recurrenceRule = mapRecurrenceRuleValueToRecurrenceRuleObject(firstRecurrenceRule.getFirstValue(), eventComponent.startDate);\n eventObject.hasMultipleRRules = !recurrenceRuleIterator.next().done;\n }\n\n /**\n * Convert the CSS 3 color name to a hex color\n */\n if (eventComponent.hasProperty('COLOR')) {\n const hexColor = getHexForColorName(eventComponent.getFirstPropertyFirstValue('COLOR'));\n if (hexColor !== null) {\n eventObject.customColor = hexColor;\n }\n }\n if (eventComponent.hasProperty('CLIENT')) {\n eventObject.client = eventComponent.getFirstPropertyFirstValue('CLIENT');\n }\n if (eventComponent.hasProperty('ISPRIVATE')) {\n eventObject.isPrivate = eventComponent.getFirstPropertyFirstValue('ISPRIVATE') === '1' ? true : false;\n }\n if (eventComponent.hasProperty('EMBALMER')) {\n eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER');\n }\n return eventObject;\n};\n\n/**\n * Copy data from a calendar-object-instance into a calendar-js event-component\n *\n * @param {object} eventObject The calendar-object-instance object\n * @param {EventComponent} eventComponent The calendar-js EventComponent object\n */\nconst copyCalendarObjectInstanceIntoEventComponent = (eventObject, eventComponent) => {\n eventComponent.title = eventObject.title;\n eventComponent.location = eventObject.location;\n eventComponent.client = eventObject.client;\n eventComponent.embalmer = eventObject.embalmer;\n eventComponent.isPrivate = eventObject.isPrivate;\n eventComponent.description = eventObject.description;\n eventComponent.accessClass = eventObject.accessClass;\n eventComponent.status = eventObject.status;\n eventComponent.timeTransparency = eventObject.timeTransparency;\n for (const category of eventObject.categories) {\n eventComponent.addCategory(category);\n }\n if (eventObject.organizer) {\n eventComponent.setOrganizerFromNameAndEMail(eventObject.organizer.commonName, eventObject.organizer.uri);\n }\n for (const alarm of eventObject.alarms) {\n if (alarm.isRelative) {\n const duration = DurationValue.fromSeconds(alarm.relativeTrigger);\n eventComponent.addRelativeAlarm(alarm.type, duration, alarm.relativeIsRelatedToStart);\n } else {\n const date = DateTimeValue.fromJSDate(alarm.absoluteDate);\n eventComponent.addAbsoluteAlarm(alarm.type, date);\n }\n }\n for (const attendee of eventObject.attendees) {\n eventComponent.addProperty(attendee.attendeeProperty);\n }\n for (const rule of eventObject.eventComponent.getPropertyIterator('RRULE')) {\n eventComponent.addProperty(rule);\n }\n if (eventObject.customColor) {\n eventComponent.color = getClosestCSS3ColorNameForHex(eventObject.customColor);\n }\n};\nexport { getDefaultEventObject, mapEventComponentToEventObject, copyCalendarObjectInstanceIntoEventComponent };","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport { PRINCIPAL_PREFIX_CALENDAR_RESOURCE, PRINCIPAL_PREFIX_CALENDAR_ROOM, PRINCIPAL_PREFIX_CIRCLE, PRINCIPAL_PREFIX_GROUP, PRINCIPAL_PREFIX_USER } from './consts.js';\n\n/**\r\n * Creates a complete principal-object based on given props\r\n *\r\n * @param {object} props Principal-props already provided\r\n * @return {any}\r\n */\nconst getDefaultPrincipalObject = props => Object.assign({}, {\n // Id of the principal\n id: null,\n // Calendar-user-type. This can be INDIVIDUAL, GROUP, RESOURCE or ROOM\n calendarUserType: 'INDIVIDUAL',\n // E-Mail address of principal used for scheduling\n emailAddress: null,\n // The principals display-name\n // TODO: this should be renamed to displayName\n displayname: null,\n // principalScheme\n principalScheme: null,\n // The internal user-id in case it is of type INDIVIDUAL and a user\n // TODO: userId is deprecrated, use principalId instead\n userId: null,\n // url to the DAV-principal-resource\n url: null,\n // The cdav-library object\n dav: null,\n // Whether or not this principal represents a circle\n isCircle: false,\n // Whether or not this principal represents a user\n isUser: false,\n // Whether or not this principal represents a group\n isGroup: false,\n // Whether or not this principal represents a calendar-resource\n isCalendarResource: false,\n // Whether or not this principal represents a calendar-room\n isCalendarRoom: false,\n // The id of the principal without prefix. e.g. userId / groupId / etc.\n principalId: null,\n // The url of the default calendar for invitations\n scheduleDefaultCalendarUrl: null\n}, props);\n\n/**\r\n * converts a dav principal into a vuex object\r\n *\r\n * @param {object} dav cdav-library Principal object\r\n * @return {object}\r\n */\nconst mapDavToPrincipal = dav => {\n const id = btoa(encodeURI(dav.url));\n const calendarUserType = dav.calendarUserType;\n const principalScheme = dav.principalScheme;\n const emailAddress = dav.email;\n const displayname = dav.displayname;\n const scheduleDefaultCalendarUrl = dav.scheduleDefaultCalendarUrl;\n const isUser = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_USER);\n const isGroup = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_GROUP);\n const isCircle = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_CIRCLE);\n const isCalendarResource = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_CALENDAR_RESOURCE);\n const isCalendarRoom = dav.principalScheme.startsWith(PRINCIPAL_PREFIX_CALENDAR_ROOM);\n let principalId = null;\n if (isUser) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_USER.length);\n } else if (isGroup) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_GROUP.length);\n } else if (isCircle) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_CIRCLE.length);\n } else if (isCalendarResource) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_CALENDAR_RESOURCE.length);\n } else if (isCalendarRoom) {\n principalId = dav.principalScheme.substring(PRINCIPAL_PREFIX_CALENDAR_ROOM.length);\n }\n const url = dav.principalUrl;\n const userId = dav.userId;\n return getDefaultPrincipalObject({\n id,\n calendarUserType,\n principalScheme,\n emailAddress,\n displayname,\n url,\n dav,\n isUser,\n isGroup,\n isCircle,\n isCalendarResource,\n isCalendarRoom,\n principalId,\n userId,\n scheduleDefaultCalendarUrl\n });\n};\nexport { getDefaultPrincipalObject, mapDavToPrincipal };","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { getWeekDayFromDate } from '../utils/recurrence.js';\nimport { getDateFromDateTimeValue } from '../utils/date.js';\n\n/**\r\n * Creates a complete recurrence-rule-object based on given props\r\n *\r\n * @param {object} props Recurrence-rule-object-props already provided\r\n * @return {object}\r\n */\nconst getDefaultRecurrenceRuleObject = function () {\n let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return Object.assign({}, {\n // The calendar-js recurrence-rule value\n recurrenceRuleValue: null,\n // The frequency of the recurrence-rule (DAILY, WEEKLY, ...)\n frequency: 'NONE',\n // The interval of the recurrence-rule, must be a positive integer\n interval: 1,\n // Positive integer if recurrence-rule limited by count, null otherwise\n count: null,\n // Date if recurrence-rule limited by date, null otherwise\n // We do not store a timezone here, since we only care about the date part\n until: null,\n // List of byDay components to limit/expand the recurrence-rule\n byDay: [],\n // List of byMonth components to limit/expand the recurrence-rule\n byMonth: [],\n // List of byMonthDay components to limit/expand the recurrence-rule\n byMonthDay: [],\n // A position to limit the recurrence-rule (e.g. -1 for last Friday)\n bySetPosition: null,\n // Whether or not the rule is not supported for editing\n isUnsupported: false\n }, props);\n};\n\n/**\r\n * Maps a calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapRecurrenceRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n switch (recurrenceRuleValue.frequency) {\n case 'DAILY':\n return mapDailyRuleValueToRecurrenceRuleObject(recurrenceRuleValue);\n case 'WEEKLY':\n return mapWeeklyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate);\n case 'MONTHLY':\n return mapMonthlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate);\n case 'YEARLY':\n return mapYearlyRuleValueToRecurrenceRuleObject(recurrenceRuleValue, baseDate);\n default:\n // SECONDLY, MINUTELY, HOURLY\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n isUnsupported: true\n });\n }\n};\nconst FORBIDDEN_BY_PARTS_DAILY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH', 'BYSETPOS'];\nconst FORBIDDEN_BY_PARTS_WEEKLY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH', 'BYSETPOS'];\nconst FORBIDDEN_BY_PARTS_MONTHLY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH'];\nconst FORBIDDEN_BY_PARTS_YEARLY = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO'];\nconst SUPPORTED_BY_DAY_WEEKLY = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];\n\n/**\r\n * Get all numbers between start and end as strings\r\n *\r\n * @param {number} start Lower end of range\r\n * @param {number} end Upper end of range\r\n * @return {string[]}\r\n */\nconst getRangeAsStrings = (start, end) => {\n return Array.apply(null, Array(end - start + 1)).map((_, n) => n + start).map(s => s.toString());\n};\nconst SUPPORTED_BY_MONTHDAY_MONTHLY = getRangeAsStrings(1, 31);\nconst SUPPORTED_BY_MONTH_YEARLY = getRangeAsStrings(1, 12);\n\n/**\r\n * Maps a daily calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @return {object}\r\n */\nconst mapDailyRuleValueToRecurrenceRuleObject = recurrenceRuleValue => {\n /**\r\n * We only support DAILY rules without any by-parts in the editor.\r\n * If the recurrence-rule contains any by-parts, mark it as unsupported.\r\n */\n const isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_DAILY);\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n isUnsupported\n });\n};\n\n/**\r\n * Maps a weekly calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapWeeklyRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n /**\r\n * For WEEKLY recurrences, our editor only allows BYDAY\r\n *\r\n * As defined in RFC5545 3.3.10. Recurrence Rule:\r\n * > Each BYDAY value can also be preceded by a positive (+n) or\r\n * > negative (-n) integer. If present, this indicates the nth\r\n * > occurrence of a specific day within the MONTHLY or YEARLY \"RRULE\".\r\n *\r\n * RFC 5545 specifies other components, which can be used along WEEKLY.\r\n * Among them are BYMONTH and BYSETPOS. We don't support those.\r\n */\n const containsUnsupportedByParts = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_WEEKLY);\n const containsInvalidByDayPart = recurrenceRuleValue.getComponent('BYDAY').some(weekday => !SUPPORTED_BY_DAY_WEEKLY.includes(weekday));\n const isUnsupported = containsUnsupportedByParts || containsInvalidByDayPart;\n const byDay = recurrenceRuleValue.getComponent('BYDAY').filter(weekday => SUPPORTED_BY_DAY_WEEKLY.includes(weekday));\n\n // If the BYDAY is empty, add the day that the event occurs in\n // E.g. if the event is on a Wednesday, automatically set BYDAY:WE\n if (byDay.length === 0) {\n byDay.push(getWeekDayFromDate(baseDate.jsDate));\n }\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n byDay,\n isUnsupported\n });\n};\n\n/**\r\n * Maps a monthly calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapMonthlyRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n /**\r\n * We only supports BYMONTHDAY, BYDAY, BYSETPOS in order to expand the monthly rule.\r\n * It supports either BYMONTHDAY or the combination of BYDAY and BYSETPOS. They have to be used exclusively\r\n * and cannot be combined.\r\n *\r\n * We do not support other BY-parts like BYMONTH\r\n *\r\n * For monthly recurrence-rules, BYDAY components are allowed to be preceded by positive or negative integers.\r\n * The Nextcloud-editor supports at most one BYDAY component with an integer.\r\n * If it's presented with such a BYDAY component, it will internally be converted to BYDAY without integer and BYSETPOS.\r\n * e.g.\r\n * BYDAY=3WE => BYDAY=WE,BYSETPOS=3\r\n *\r\n * BYSETPOS is limited to -2, -1, 1, 2, 3, 4, 5\r\n * Other values are not supported\r\n *\r\n * BYDAY is limited to \"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\", \"SU\",\r\n * \"MO,TU,WE,TH,FR,SA,SU\", \"MO,TU,WE,TH,FR\", \"SA,SU\"\r\n *\r\n * BYMONTHDAY is limited to \"1\", \"2\", ..., \"31\"\r\n */\n let isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_MONTHLY);\n let byDay = [];\n let bySetPosition = null;\n let byMonthDay = [];\n\n // This handles the first case, where we have a BYMONTHDAY rule\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTHDAY'])) {\n // verify there is no BYDAY or BYSETPOS at the same time\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY', 'BYSETPOS'])) {\n isUnsupported = true;\n }\n const containsInvalidByMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY').some(monthDay => !SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay.toString()));\n isUnsupported = isUnsupported || containsInvalidByMonthDay;\n byMonthDay = recurrenceRuleValue.getComponent('BYMONTHDAY').filter(monthDay => SUPPORTED_BY_MONTHDAY_MONTHLY.includes(monthDay.toString())).map(monthDay => monthDay.toString());\n\n // This handles cases where we have both BYDAY and BYSETPOS\n } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY']) && containsRecurrenceComponent(recurrenceRuleValue, ['BYSETPOS'])) {\n if (isAllowedByDay(recurrenceRuleValue.getComponent('BYDAY'))) {\n byDay = recurrenceRuleValue.getComponent('BYDAY');\n } else {\n byDay = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];\n isUnsupported = true;\n }\n const setPositionArray = recurrenceRuleValue.getComponent('BYSETPOS');\n if (setPositionArray.length === 1 && isAllowedBySetPos(setPositionArray[0])) {\n bySetPosition = setPositionArray[0];\n } else {\n bySetPosition = 1;\n isUnsupported = true;\n }\n\n // This handles cases where we only have a BYDAY\n } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY'])) {\n const byDayArray = recurrenceRuleValue.getComponent('BYDAY');\n if (byDayArray.length > 1) {\n byMonthDay.push(baseDate.day.toString());\n isUnsupported = true;\n } else {\n const firstElement = byDayArray[0];\n const match = /^(-?\\d)([A-Z]{2})$/.exec(firstElement);\n if (match) {\n const matchedBySetPosition = match[1];\n const matchedByDay = match[2];\n if (isAllowedBySetPos(matchedBySetPosition)) {\n byDay = [matchedByDay];\n bySetPosition = parseInt(matchedBySetPosition, 10);\n } else {\n byDay = [matchedByDay];\n bySetPosition = 1;\n isUnsupported = true;\n }\n } else {\n byMonthDay.push(baseDate.day.toString());\n isUnsupported = true;\n }\n }\n\n // This is a fallback where we just default BYMONTHDAY to the start date of the event\n } else {\n byMonthDay.push(baseDate.day.toString());\n }\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n byDay,\n bySetPosition,\n byMonthDay,\n isUnsupported\n });\n};\n\n/**\r\n * Maps a yearly calendar-js recurrence-rule-value to an recurrence-rule-object\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The calendar-js recurrence rule value\r\n * @param {DateTimeValue} baseDate The base-date used to fill unset values\r\n * @return {object}\r\n */\nconst mapYearlyRuleValueToRecurrenceRuleObject = (recurrenceRuleValue, baseDate) => {\n /**\r\n * We only supports BYMONTH, BYDAY, BYSETPOS in order to expand the yearly rule.\r\n * It supports a combination of them.\r\n *\r\n * We do not support other BY-parts.\r\n *\r\n * For yearly recurrence-rules, BYDAY components are allowed to be preceded by positive or negative integers.\r\n * The Nextcloud-editor supports at most one BYDAY component with an integer.\r\n * If it's presented with such a BYDAY component, it will internally be converted to BYDAY without integer and BYSETPOS.\r\n * e.g.\r\n * BYDAY=3WE => BYDAY=WE,BYSETPOS=3\r\n *\r\n * BYSETPOS is limited to -2, -1, 1, 2, 3, 4, 5\r\n * Other values are not supported\r\n *\r\n * BYDAY is limited to \"MO\", \"TU\", \"WE\", \"TH\", \"FR\", \"SA\", \"SU\",\r\n * \"MO,TU,WE,TH,FR,SA,SU\", \"MO,TU,WE,TH,FR\", \"SA,SU\"\r\n */\n let isUnsupported = containsRecurrenceComponent(recurrenceRuleValue, FORBIDDEN_BY_PARTS_YEARLY);\n let byDay = [];\n let bySetPosition = null;\n let byMonth = [];\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYMONTH'])) {\n const containsInvalidByMonthDay = recurrenceRuleValue.getComponent('BYMONTH').some(month => !SUPPORTED_BY_MONTH_YEARLY.includes(month.toString()));\n isUnsupported = isUnsupported || containsInvalidByMonthDay;\n byMonth = recurrenceRuleValue.getComponent('BYMONTH').filter(monthDay => SUPPORTED_BY_MONTH_YEARLY.includes(monthDay.toString())).map(month => month.toString());\n } else {\n byMonth.push(baseDate.month.toString());\n }\n if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY']) && containsRecurrenceComponent(recurrenceRuleValue, ['BYSETPOS'])) {\n if (isAllowedByDay(recurrenceRuleValue.getComponent('BYDAY'))) {\n byDay = recurrenceRuleValue.getComponent('BYDAY');\n } else {\n byDay = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU'];\n isUnsupported = true;\n }\n const setPositionArray = recurrenceRuleValue.getComponent('BYSETPOS');\n if (setPositionArray.length === 1 && isAllowedBySetPos(setPositionArray[0])) {\n bySetPosition = setPositionArray[0];\n } else {\n bySetPosition = 1;\n isUnsupported = true;\n }\n } else if (containsRecurrenceComponent(recurrenceRuleValue, ['BYDAY'])) {\n const byDayArray = recurrenceRuleValue.getComponent('BYDAY');\n if (byDayArray.length > 1) {\n isUnsupported = true;\n } else {\n const firstElement = byDayArray[0];\n const match = /^(-?\\d)([A-Z]{2})$/.exec(firstElement);\n if (match) {\n const matchedBySetPosition = match[1];\n const matchedByDay = match[2];\n if (isAllowedBySetPos(matchedBySetPosition)) {\n byDay = [matchedByDay];\n bySetPosition = parseInt(matchedBySetPosition, 10);\n } else {\n byDay = [matchedByDay];\n bySetPosition = 1;\n isUnsupported = true;\n }\n } else {\n isUnsupported = true;\n }\n }\n }\n return getDefaultRecurrenceRuleObjectForRecurrenceValue(recurrenceRuleValue, {\n byDay,\n bySetPosition,\n byMonth,\n isUnsupported\n });\n};\n\n/**\r\n * Checks if the given parameter is a supported BYDAY value\r\n *\r\n * @param {string[]} byDay The byDay component to check\r\n * @return {boolean}\r\n */\nconst isAllowedByDay = byDay => {\n return ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU', 'FR,MO,SA,SU,TH,TU,WE', 'FR,MO,TH,TU,WE', 'SA,SU'].includes(byDay.slice().sort().join(','));\n};\n\n/**\r\n * Checks if the given parameter is a supported BYSETPOS value\r\n *\r\n * @param {string} bySetPos The bySetPos component to check\r\n * @return {boolean}\r\n */\nconst isAllowedBySetPos = bySetPos => {\n return ['-2', '-1', '1', '2', '3', '4', '5'].includes(bySetPos.toString());\n};\n\n/**\r\n * Checks if the recurrence-rule contains any of the given components\r\n *\r\n * @param {RecurValue} recurrenceRule The recurrence-rule value to check for the given components\r\n * @param {string[]} components List of components to check for\r\n * @return {boolean}\r\n */\nconst containsRecurrenceComponent = (recurrenceRule, components) => {\n for (const component of components) {\n const componentValue = recurrenceRule.getComponent(component);\n if (componentValue.length > 0) {\n return true;\n }\n }\n return false;\n};\n\n/**\r\n * Returns a full recurrence-rule-object with default values derived from recurrenceRuleValue\r\n * and additional props\r\n *\r\n * @param {RecurValue} recurrenceRuleValue The recurrence-rule value to get default values from\r\n * @param {object} props The properties to provide on top of default one\r\n * @return {object}\r\n */\nconst getDefaultRecurrenceRuleObjectForRecurrenceValue = (recurrenceRuleValue, props) => {\n const isUnsupported = recurrenceRuleValue.count !== null && recurrenceRuleValue.until !== null;\n let isUnsupportedProps = {};\n if (isUnsupported) {\n isUnsupportedProps = {\n isUnsupported\n };\n }\n return getDefaultRecurrenceRuleObject(Object.assign({}, {\n recurrenceRuleValue,\n frequency: recurrenceRuleValue.frequency,\n interval: parseInt(recurrenceRuleValue.interval, 10) || 1,\n count: recurrenceRuleValue.count,\n until: recurrenceRuleValue.until ? getDateFromDateTimeValue(recurrenceRuleValue.until) : null\n }, props, isUnsupportedProps));\n};\nexport { getDefaultRecurrenceRuleObject, mapRecurrenceRuleValueToRecurrenceRuleObject };","/**\r\n * @copyright 2022 Mikhail Sazanov \r\n *\r\n * @author 2022 Mikhail Sazanov \r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport axios from '@nextcloud/axios';\nimport { generateOcsUrl, generateRemoteUrl } from '@nextcloud/router';\nimport { showError, showSuccess } from '@nextcloud/dialogs';\nimport { translate as t } from '@nextcloud/l10n';\nimport { parseXML } from 'webdav';\n\n/**\r\n * Makes a share link for a given file or directory.\r\n *\r\n * @param {string} path The file path from the user's root directory. e.g. `/myfile.txt`\r\n * @return {string} url share link\r\n */\nconst shareFile = async function (path) {\n try {\n const res = await axios.post(generateOcsUrl('apps/files_sharing/api/v1/', 2) + 'shares', {\n shareType: OC.Share.SHARE_TYPE_LINK,\n path\n });\n return res.data.ocs.data;\n } catch (error) {\n var _error$response;\n if (error !== null && error !== void 0 && (_error$response = error.response) !== null && _error$response !== void 0 && (_error$response = _error$response.data) !== null && _error$response !== void 0 && (_error$response = _error$response.ocs) !== null && _error$response !== void 0 && (_error$response = _error$response.meta) !== null && _error$response !== void 0 && _error$response.message) {\n console.error(\"Error while sharing file: \".concat(error.response.data.ocs.meta.message));\n showError(error.response.data.ocs.meta.message);\n throw error;\n } else {\n console.error('Error while sharing file: Unknown error');\n showError(t('calendar', 'Error while sharing file'));\n throw error;\n }\n }\n};\n\n/**\r\n * Share file with a user with permissions\r\n *\r\n * @param path\r\n * @param sharedWith\r\n * @param permissions\r\n * @return {Promise<[{path: string, permissions, scope: string, name: string, backend: string, type: string},{path: string, permissions: *, scope: string, name: string, backend: string, type: string}]>}\r\n */\nconst shareFileWith = async function (path, sharedWith) {\n let permissions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 17;\n try {\n const url = generateOcsUrl('apps/files_sharing/api/v1/', 2);\n const res = await axios.post(\"\".concat(url, \"shares\"), {\n password: null,\n shareType: OC.Share.SHARE_TYPE_USER,\n // WITH USERS,\n permissions,\n // 14 - edit, 17 - view\n path,\n shareWith: sharedWith\n });\n return res.data.ocs.data;\n } catch (error) {\n var _error$response2;\n if (error !== null && error !== void 0 && (_error$response2 = error.response) !== null && _error$response2 !== void 0 && (_error$response2 = _error$response2.data) !== null && _error$response2 !== void 0 && (_error$response2 = _error$response2.ocs) !== null && _error$response2 !== void 0 && (_error$response2 = _error$response2.meta) !== null && _error$response2 !== void 0 && _error$response2.message) {\n console.error(\"Error while sharing file with user: \".concat(error.response.data.ocs.meta.message));\n showError(error.response.data.ocs.meta.message);\n throw error;\n } else {\n console.error('Error while sharing file with user: Unknown error');\n showError(t('calendar', 'Error while sharing file with user'));\n throw error;\n }\n }\n};\nconst createFolder = async function (folderName, userId) {\n const url = generateRemoteUrl(\"dav/files/\".concat(userId, \"/\").concat(folderName));\n try {\n await axios({\n method: 'MKCOL',\n url\n });\n } catch (e) {\n var _e$response;\n if ((e === null || e === void 0 || (_e$response = e.response) === null || _e$response === void 0 ? void 0 : _e$response.status) !== 405) {\n showError(t('calendar', 'Error creating a folder {folder}', {\n folder: folderName\n }));\n // Maybe the actual upload succeeds -> keep going\n return folderName;\n }\n\n // Folder already exists\n if (folderName !== '/') {\n folderName = await findFirstOwnedFolder(folderName, userId);\n }\n }\n return folderName;\n};\nconst findFirstOwnedFolder = async function (path, userId) {\n var _info$multistatus;\n const infoXml = await getFileInfo(path, userId);\n const info = await parseXML(infoXml);\n const mountType = info === null || info === void 0 || (_info$multistatus = info.multistatus) === null || _info$multistatus === void 0 || (_info$multistatus = _info$multistatus.response[0]) === null || _info$multistatus === void 0 || (_info$multistatus = _info$multistatus.propstat) === null || _info$multistatus === void 0 || (_info$multistatus = _info$multistatus.prop) === null || _info$multistatus === void 0 ? void 0 : _info$multistatus['mount-type'];\n if (mountType !== 'shared') {\n return path;\n }\n const hierarchy = path.split('/');\n hierarchy.pop();\n if (hierarchy.length === 1) {\n return '/';\n }\n return findFirstOwnedFolder(hierarchy.join('/'), userId);\n};\nconst uploadLocalAttachment = async function (folder, files, dav, componentAttachments) {\n const attachments = [];\n const promises = [];\n files.forEach(file => {\n // temp fix, until we decide where to save the attachments\n if (componentAttachments.map(attachment => attachment.fileName.split('/').pop()).indexOf(file.name) !== -1) {\n // TODO may be show user confirmation dialog to create a file named Existing_File_(2) ?\n showError(t('calendar', 'Attachment {fileName} already exists!', {\n fileName: file.name\n }));\n } else {\n const url = generateRemoteUrl(\"dav/files/\".concat(dav.userId, \"/\").concat(folder, \"/\").concat(file.name));\n const res = axios.put(url, file).then(resp => {\n const data = {\n fileName: file.name,\n formatType: file.type,\n uri: url,\n value: url,\n path: \"/\".concat(file.name)\n };\n if (resp.status === 204 || resp.status === 201) {\n showSuccess(t('calendar', 'Attachment {fileName} added!', {\n fileName: file.name\n }));\n attachments.push(data);\n }\n }).catch(() => {\n showError(t('calendar', 'An error occurred during uploading file {fileName}', {\n fileName: file.name\n }));\n });\n promises.push(res);\n }\n });\n await Promise.all(promises);\n return attachments;\n};\nconst uploadRemoteFile = async function (folder, fileUrl, fileName, dav) {\n try {\n // Télécharger le fichier distant\n const response = await axios.get(fileUrl, {\n responseType: 'blob'\n });\n\n // Envoyer le fichier récupéré en PUT vers WebDAV\n const url = generateRemoteUrl(\"dav/files/\".concat(dav.userId, \"/\").concat(folder, \"/\").concat(fileName));\n const uploadResponse = await axios.put(url, response.data, {\n headers: {\n 'Content-Type': response.data.type // Utilise le type MIME du fichier\n }\n });\n if (uploadResponse.status === 204 || uploadResponse.status === 201) {\n showSuccess(t('calendar', 'Attachment {fileName} added!', {\n fileName: fileName\n }));\n return {\n fileName: fileName,\n formatType: response.data.type,\n uri: url,\n value: url,\n path: \"/\".concat(fileName)\n };\n }\n } catch (error) {\n showError(t('calendar', 'An error occurred during uploading file {fileName}', {\n fileName: fileName\n }));\n return null;\n }\n};\n// TODO is shared or not @share-types@\nconst getFileInfo = async function (path, userId) {\n const url = generateRemoteUrl(\"dav/files/\".concat(userId, \"/\").concat(path));\n const res = await axios({\n method: 'PROPFIND',\n url,\n data: \"\\n\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\t\\n\\t\\t\\t\\t\\n\\t\\t\\t\"\n }).catch(() => {\n showError(t('calendar', 'An error occurred during getting file information'));\n });\n return res.data;\n};\nexport { getFileInfo, shareFile, shareFileWith, uploadLocalAttachment, createFolder, uploadRemoteFile };","import axios from \"@nextcloud/axios\";\nimport { generateUrl } from \"@nextcloud/router\";\nexport default {\n async fetchAndCommitRoles(commit) {\n try {\n var url = '/apps/gestion/getUserConnectedGroups';\n const ajaxUrl = generateUrl(url);\n axios.get(ajaxUrl).then(response => {\n let roles = JSON.parse(response.data);\n commit(\"setUserRole\", roles);\n }).catch(error => {});\n } catch (error) {}\n }\n};","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport HttpClient from '@nextcloud/axios';\nimport { getLinkToConfig } from '../utils/settings.js';\n\n/**\r\n *\r\n * @param {string} key Config-key to set\r\n * @param {string | number | boolean} value Config-value to set\r\n * @return {Promise}\r\n */\nconst setConfig = async (key, value) => {\n await HttpClient.post(getLinkToConfig(key), {\n value\n });\n};\nexport { setConfig };","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n * @copyright Copyright (c) 2023 Jonas Heinrich\n *\n * @author Georg Ehrke \n * @author Jonas Heinrich \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 .\n *\n */\nimport Vue from 'vue';\nimport getTimezoneManager from '../services/timezoneDataProviderService.js';\nimport { getDateFromDateTimeValue } from '../utils/date.js';\nimport { AttendeeProperty, Property, DateTimeValue, DurationValue, RecurValue, AttachmentProperty, Parameter } from '@nextcloud/calendar-js';\nimport { getBySetPositionAndBySetFromDate, getWeekDayFromDate } from '../utils/recurrence.js';\nimport { copyCalendarObjectInstanceIntoEventComponent, getDefaultEventObject, mapEventComponentToEventObject } from '../models/event.js';\nimport { getAmountAndUnitForTimedEvents, getAmountHoursMinutesAndUnitForAllDayEvents, getTotalSecondsFromAmountAndUnitForTimedEvents, getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents, updateAlarms } from '../utils/alarms.js';\nimport { getClosestCSS3ColorNameForHex, getHexForColorName } from '../utils/color.js';\nimport { mapAlarmComponentToAlarmObject } from '../models/alarm.js';\nimport { getObjectAtRecurrenceId } from '../utils/calendarObject.js';\nimport logger from '../utils/logger.js';\nimport settings from './settings.js';\nimport { getRFCProperties } from '../models/rfcProps.js';\nimport { generateUrl } from '@nextcloud/router';\nimport { updateTalkParticipants } from '../services/talkService.js';\nconst state = {\n isNew: null,\n calendarObject: null,\n calendarObjectInstance: null,\n existingEvent: {\n objectId: null,\n recurrenceId: null\n }\n};\nconst mutations = {\n /**\n * Set a calendar-object-instance that will be opened in the editor (existing event)\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject The calendar-object currently being edited\n * @param {object} data.calendarObjectInstance The calendar-object-instance currently being edited\n * @param {string} data.objectId The objectId of the calendar-object\n * @param {number} data.recurrenceId The recurrence-id of the calendar-object-instance\n */\n setCalendarObjectInstanceForExistingEvent(state, _ref) {\n let {\n calendarObject,\n calendarObjectInstance,\n objectId,\n recurrenceId\n } = _ref;\n state.isNew = false;\n state.calendarObject = calendarObject;\n state.calendarObjectInstance = calendarObjectInstance;\n state.existingEvent.objectId = objectId;\n state.existingEvent.recurrenceId = recurrenceId;\n },\n /**\n * Set a calendar-object-instance that will be opened in the editor (new event)\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject The calendar-object currently being created\n * @param {object} data.calendarObjectInstance The calendar-object-instance currently being crated\n */\n setCalendarObjectInstanceForNewEvent(state, _ref2) {\n let {\n calendarObject,\n calendarObjectInstance\n } = _ref2;\n state.isNew = true;\n state.calendarObject = calendarObject;\n state.calendarObjectInstance = calendarObjectInstance;\n state.existingEvent.objectId = null;\n state.existingEvent.recurrenceId = null;\n },\n /**\n *\n * @param {object} state The Vuex state\n */\n resetCalendarObjectInstanceObjectIdAndRecurrenceId(state) {\n state.isNew = false;\n state.calendarObject = null;\n state.calendarObjectInstance = null;\n state.existingEvent.objectId = null;\n state.existingEvent.recurrenceId = null;\n },\n /**\n * Change the title of the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.title The new Title\n */\n changeTitle(state, _ref3) {\n let {\n calendarObjectInstance,\n title\n } = _ref3;\n calendarObjectInstance.eventComponent.title = title;\n calendarObjectInstance.title = title;\n },\n /**\n * Change the event's start\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {Date} data.startDate New start date to set\n */\n changeStartDate(state, _ref4) {\n let {\n calendarObjectInstance,\n startDate\n } = _ref4;\n calendarObjectInstance.eventComponent.startDate.year = startDate.getFullYear();\n calendarObjectInstance.eventComponent.startDate.month = startDate.getMonth() + 1;\n calendarObjectInstance.eventComponent.startDate.day = startDate.getDate();\n calendarObjectInstance.eventComponent.startDate.hour = startDate.getHours();\n calendarObjectInstance.eventComponent.startDate.minute = startDate.getMinutes();\n calendarObjectInstance.eventComponent.startDate.second = 0;\n const isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n const endDateObj = calendarObjectInstance.eventComponent.endDate.clone();\n const startDateObj = calendarObjectInstance.eventComponent.startDate.clone();\n if (isAllDay) {\n endDateObj.addDuration(DurationValue.fromSeconds(-1 * 60 * 60 * 24));\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(endDateObj.timezoneId);\n calendarObjectInstance.eventComponent.endDate = calendarObjectInstance.eventComponent.startDate.getInTimezone(timezone);\n calendarObjectInstance.endDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.endDate);\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n }\n } else {\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(endDateObj.timezoneId);\n calendarObjectInstance.eventComponent.endDate = calendarObjectInstance.eventComponent.startDate.getInTimezone(timezone);\n calendarObjectInstance.endDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.endDate);\n }\n }\n calendarObjectInstance.startDate = startDate;\n },\n /**\n * Change the timezone of the event's start\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.startTimezone New timezone to set for start\n */\n changeStartTimezone(state, _ref5) {\n let {\n calendarObjectInstance,\n startTimezone\n } = _ref5;\n const timezone = getTimezoneManager().getTimezoneForId(startTimezone);\n calendarObjectInstance.eventComponent.startDate.replaceTimezone(timezone);\n calendarObjectInstance.startTimezoneId = startTimezone;\n\n // Either both are floating or both have a timezone, but it can't be mixed\n if (startTimezone === 'floating' || calendarObjectInstance.endTimezoneId === 'floating') {\n calendarObjectInstance.eventComponent.endDate.replaceTimezone(timezone);\n calendarObjectInstance.endTimezoneId = startTimezone;\n }\n },\n /**\n * Change the event's end\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {Date} data.endDate New end date to set\n */\n changeEndDate(state, _ref6) {\n let {\n calendarObjectInstance,\n endDate\n } = _ref6;\n // If the event is using DURATION, endDate is dynamically generated.\n // In order to alter it, we need to explicitly set DTEND\n const endDateObject = calendarObjectInstance.eventComponent.endDate;\n calendarObjectInstance.eventComponent.endDate = endDateObject;\n calendarObjectInstance.eventComponent.endDate.year = endDate.getFullYear();\n calendarObjectInstance.eventComponent.endDate.month = endDate.getMonth() + 1;\n calendarObjectInstance.eventComponent.endDate.day = endDate.getDate();\n calendarObjectInstance.eventComponent.endDate.hour = endDate.getHours();\n calendarObjectInstance.eventComponent.endDate.minute = endDate.getMinutes();\n calendarObjectInstance.eventComponent.endDate.second = 0;\n const isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n const endDateObj = calendarObjectInstance.eventComponent.endDate.clone();\n const startDateObj = calendarObjectInstance.eventComponent.startDate.clone();\n if (isAllDay) {\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(startDateObj.timezoneId);\n calendarObjectInstance.eventComponent.startDate = calendarObjectInstance.eventComponent.endDate.getInTimezone(timezone);\n calendarObjectInstance.startDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.startDate);\n }\n\n // endDate is inclusive, but DTEND needs to be exclusive, so always add one day\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n } else {\n // Is end before start?\n if (endDateObj.compare(startDateObj) === -1) {\n // Is end more than one day before start?\n endDateObj.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n if (endDateObj.compare(startDateObj) === -1) {\n const timezone = getTimezoneManager().getTimezoneForId(startDateObj.timezoneId);\n calendarObjectInstance.eventComponent.startDate = calendarObjectInstance.eventComponent.endDate.getInTimezone(timezone);\n calendarObjectInstance.startDate = getDateFromDateTimeValue(calendarObjectInstance.eventComponent.startDate);\n } else {\n // add one day to endDate if the endDate is before the startDate which allows to easily create events that reach over or to 0:00\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n endDate = new Date(endDate.getTime() + 24 * 60 * 60 * 1000);\n }\n }\n }\n calendarObjectInstance.endDate = endDate;\n },\n /**\n * Change the timezone of the event's end\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.endTimezone New timezone to set for end\n */\n changeEndTimezone(state, _ref7) {\n let {\n calendarObjectInstance,\n endTimezone\n } = _ref7;\n const timezone = getTimezoneManager().getTimezoneForId(endTimezone);\n calendarObjectInstance.eventComponent.endDate.replaceTimezone(timezone);\n calendarObjectInstance.endTimezoneId = endTimezone;\n\n // Either both are floating or both have a timezone, but it can't be mixed\n if (endTimezone === 'floating' || calendarObjectInstance.startTimezoneId === 'floating') {\n calendarObjectInstance.eventComponent.startDate.replaceTimezone(timezone);\n calendarObjectInstance.startTimezoneId = endTimezone;\n }\n },\n /**\n * Switch from a timed event to allday or vice versa\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n toggleAllDay(state, _ref8) {\n let {\n calendarObjectInstance\n } = _ref8;\n if (!calendarObjectInstance.eventComponent.canModifyAllDay()) {\n return;\n }\n const isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n calendarObjectInstance.eventComponent.startDate.isDate = !isAllDay;\n calendarObjectInstance.eventComponent.endDate.isDate = !isAllDay;\n calendarObjectInstance.isAllDay = calendarObjectInstance.eventComponent.isAllDay();\n\n // isAllDay = old value\n if (isAllDay) {\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(-1 * 60 * 60 * 24));\n } else {\n calendarObjectInstance.eventComponent.endDate.addDuration(DurationValue.fromSeconds(60 * 60 * 24));\n }\n },\n /**\n * Is private\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n toggleIsPrivate(state, _ref9) {\n let {\n calendarObjectInstance,\n isPrivate\n } = _ref9;\n calendarObjectInstance.eventComponent.isPrivate = isPrivate;\n calendarObjectInstance.isPrivate = isPrivate;\n },\n /**\n * Changes the time of a timed event to the default values\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n changeTimeToDefaultForTimedEvents(state, _ref10) {\n let {\n calendarObjectInstance\n } = _ref10;\n const startDate = calendarObjectInstance.eventComponent.startDate;\n const endDate = calendarObjectInstance.eventComponent.endDate;\n if (startDate.hour === 0 && startDate.minute === 0 && endDate.hour === 0 && endDate.minute === 0) {\n startDate.hour = 10;\n endDate.hour = 11;\n calendarObjectInstance.startDate = getDateFromDateTimeValue(startDate);\n calendarObjectInstance.endDate = getDateFromDateTimeValue(endDate);\n }\n },\n /**\n * Change the location of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.location New location to set\n */\n changeLocation(state, _ref11) {\n let {\n calendarObjectInstance,\n location\n } = _ref11;\n // Special case: delete Apple-specific location property to avoid inconsistencies\n calendarObjectInstance.eventComponent.deleteAllProperties('X-APPLE-STRUCTURED-LOCATION');\n calendarObjectInstance.eventComponent.location = location;\n calendarObjectInstance.location = location;\n },\n /**\n * Change the client of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.client New client to set\n */\n\n changeClient(state, _ref12) {\n let {\n calendarObjectInstance,\n client\n } = _ref12;\n calendarObjectInstance.eventComponent.client = client;\n calendarObjectInstance.client = client;\n },\n /**\n * Change the embalmer (Thanato) of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.embalmer New embalmer to set\n */\n\n changeEmbalmer(state, _ref13) {\n let {\n calendarObjectInstance,\n embalmer\n } = _ref13;\n calendarObjectInstance.eventComponent.embalmer = embalmer;\n calendarObjectInstance.embalmer = embalmer;\n },\n /**\n * Change the description of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.description New description to set\n */\n changeDescription(state, _ref14) {\n let {\n calendarObjectInstance,\n description\n } = _ref14;\n // To avoid inconsistencies (bug #3863), remove all parameters (e.g., ALTREP) upon modification\n const descriptionProperty = calendarObjectInstance.eventComponent.getFirstProperty('Description');\n if (descriptionProperty) {\n for (const parameter of descriptionProperty.getParametersIterator()) {\n descriptionProperty.deleteParameter(parameter.name);\n }\n }\n\n // Delete custom description properties\n calendarObjectInstance.eventComponent.deleteAllProperties('X-ALT-DESC');\n calendarObjectInstance.eventComponent.description = description;\n calendarObjectInstance.description = description;\n },\n /**\n * Change the access class of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.accessClass New access class to set\n */\n changeAccessClass(state, _ref15) {\n let {\n calendarObjectInstance,\n accessClass\n } = _ref15;\n calendarObjectInstance.eventComponent.accessClass = accessClass;\n calendarObjectInstance.accessClass = accessClass;\n },\n /**\n * Change the status of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.status New status to set\n */\n changeStatus(state, _ref16) {\n let {\n calendarObjectInstance,\n status\n } = _ref16;\n calendarObjectInstance.eventComponent.status = status;\n calendarObjectInstance.status = status;\n },\n /**\n * Change the time-transparency of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.timeTransparency New time-transparency to set\n */\n changeTimeTransparency(state, _ref17) {\n let {\n calendarObjectInstance,\n timeTransparency\n } = _ref17;\n calendarObjectInstance.eventComponent.timeTransparency = timeTransparency;\n calendarObjectInstance.timeTransparency = timeTransparency;\n },\n /**\n * Change the customized color of an event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string | null} data.customColor New color to set\n */\n changeCustomColor(state, _ref18) {\n let {\n calendarObjectInstance,\n customColor\n } = _ref18;\n if (customColor === null) {\n calendarObjectInstance.eventComponent.deleteAllProperties('COLOR');\n Vue.set(calendarObjectInstance, 'customColor', null);\n return;\n }\n const cssColorName = getClosestCSS3ColorNameForHex(customColor);\n const hexColorOfCssName = getHexForColorName(cssColorName);\n\n // Abort if either is undefined\n if (!cssColorName || !hexColorOfCssName) {\n console.error('Setting custom color failed');\n console.error('customColor: ', customColor);\n console.error('cssColorName: ', cssColorName);\n console.error('hexColorOfCssName: ', hexColorOfCssName);\n return;\n }\n calendarObjectInstance.eventComponent.color = cssColorName;\n Vue.set(calendarObjectInstance, 'customColor', hexColorOfCssName);\n },\n /**\n * Adds an attendee to the event and sets the organizer if not present already\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.commonName Displayname of attendee\n * @param {string} data.uri Email address of attendee\n * @param {string} data.calendarUserType Calendar-user-type of attendee (INDIVIDUAL, GROUP, RESOURCE, ROOM)\n * @param {string} data.participationStatus Participation Status of attendee\n * @param {string} data.role Role of Attendee\n * @param {boolean} data.rsvp Whether or not to request a response from the attendee\n * @param {string=} data.language Preferred language of the attendee\n * @param {string=} data.timezoneId Preferred timezone of the attendee\n * @param {object=} data.organizer Principal of the organizer to be set if not present\n * @param data.member\n */\n addAttendee(state, _ref19) {\n let {\n calendarObjectInstance,\n commonName,\n uri,\n calendarUserType = null,\n participationStatus = null,\n role = null,\n rsvp = null,\n language = null,\n timezoneId = null,\n organizer = null,\n member = null\n } = _ref19;\n const attendee = AttendeeProperty.fromNameAndEMail(commonName, uri);\n if (calendarUserType !== null) {\n attendee.userType = calendarUserType;\n }\n if (participationStatus !== null) {\n attendee.participationStatus = participationStatus;\n }\n if (role !== null) {\n attendee.role = role;\n }\n if (rsvp !== null) {\n attendee.rsvp = rsvp;\n }\n if (language !== null) {\n attendee.language = language;\n }\n if (timezoneId !== null) {\n attendee.updateParameterIfExist('TZID', timezoneId);\n }\n if (member !== null) {\n attendee.updateParameterIfExist('MEMBER', member);\n }\n\n // TODO - use real addAttendeeFrom method\n calendarObjectInstance.eventComponent.addProperty(attendee);\n calendarObjectInstance.attendees.push({\n commonName,\n participationStatus,\n role,\n rsvp,\n uri,\n attendeeProperty: attendee\n });\n if (!calendarObjectInstance.organizer && organizer) {\n this.commit('setOrganizer', {\n calendarObjectInstance,\n commonName: organizer.displayname,\n email: organizer.emailAddress\n });\n }\n },\n /**\n * Removes an attendee from the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.attendee The attendee object to remove\n */\n removeAttendee(state, _ref20) {\n let {\n calendarObjectInstance,\n attendee\n } = _ref20;\n calendarObjectInstance.eventComponent.removeAttendee(attendee.attendeeProperty);\n\n // Also remove members if attendee is a group\n if (attendee.attendeeProperty.userType === 'GROUP') {\n attendee.members.forEach(function (member) {\n calendarObjectInstance.eventComponent.removeAttendee(member.attendeeProperty);\n const index = calendarObjectInstance.attendees.indexOf(member);\n if (index !== -1) {\n calendarObjectInstance.attendees.splice(index, 1);\n }\n });\n }\n const index = calendarObjectInstance.attendees.indexOf(attendee);\n if (index !== -1) {\n calendarObjectInstance.attendees.splice(index, 1);\n }\n },\n /**\n * Changes an attendees' participation status\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.attendee The attendee object\n * @param {string} data.participationStatus New Participation Status of attendee\n */\n changeAttendeesParticipationStatus(state, _ref21) {\n let {\n attendee,\n participationStatus\n } = _ref21;\n attendee.attendeeProperty.participationStatus = participationStatus;\n attendee.participationStatus = participationStatus;\n },\n /**\n * Changes an attendees' role\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.attendee The attendee object\n * @param {string} data.role New role of attendee\n */\n changeAttendeesRole(state, _ref22) {\n let {\n attendee,\n role\n } = _ref22;\n attendee.attendeeProperty.role = role;\n attendee.role = role;\n },\n /**\n * Changes an attendees' RVSP\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.attendee The attendee object\n */\n toggleAttendeeRSVP(state, _ref23) {\n let {\n attendee\n } = _ref23;\n const oldRSVP = attendee.attendeeProperty.rsvp;\n attendee.attendeeProperty.rsvp = !oldRSVP;\n attendee.rsvp = !oldRSVP;\n },\n /**\n * Set the event's organizer\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string=} data.commonName Displayname of organizer\n * @param {string} data.email Email-address of organizer\n */\n setOrganizer(state, _ref24) {\n let {\n calendarObjectInstance,\n commonName = null,\n email\n } = _ref24;\n calendarObjectInstance.eventComponent.setOrganizerFromNameAndEMail(commonName, email);\n Vue.set(calendarObjectInstance, 'organizer', {});\n Vue.set(calendarObjectInstance.organizer, 'commonName', commonName);\n Vue.set(calendarObjectInstance.organizer, 'uri', email);\n Vue.set(calendarObjectInstance.organizer, 'attendeeProperty', calendarObjectInstance.eventComponent.getFirstProperty('ORGANIZER'));\n },\n /**\n * Adds a category to the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.category Category to add\n */\n addCategory(state, _ref25) {\n let {\n calendarObjectInstance,\n category\n } = _ref25;\n calendarObjectInstance.eventComponent.addCategory(category);\n calendarObjectInstance.categories.push(category);\n },\n /**\n * Removes a category from the event\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.category Category to remove\n */\n removeCategory(state, _ref26) {\n let {\n calendarObjectInstance,\n category\n } = _ref26;\n calendarObjectInstance.eventComponent.removeCategory(category);\n const index = calendarObjectInstance.categories.indexOf(category);\n if (index !== -1) {\n calendarObjectInstance.categories.splice(index, 1);\n }\n },\n /**\n * Change the interval of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.interval The new interval to set\n */\n changeRecurrenceInterval(state, _ref27) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n interval\n } = _ref27;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.interval = interval;\n recurrenceRule.interval = interval;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the frequency of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.frequency The new frequency to set\n */\n changeRecurrenceFrequency(state, _ref28) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n } = _ref28;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.frequency = frequency;\n recurrenceRule.frequency = frequency;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the count limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.count The new count to set\n */\n changeRecurrenceCount(state, _ref29) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n count\n } = _ref29;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.count = count;\n recurrenceRule.count = count;\n recurrenceRule.until = null;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {Date} data.until The new until to set\n */\n changeRecurrenceUntil(state, _ref30) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n until\n } = _ref30;\n if (recurrenceRule.recurrenceRuleValue) {\n // RFC 5545, setion 3.3.10: until must be in UTC if the start time is timezone-aware\n if (calendarObjectInstance.startTimezoneId !== 'floating') {\n recurrenceRule.recurrenceRuleValue.until = DateTimeValue.fromJSDate(until, {\n zone: 'utc'\n });\n } else {\n recurrenceRule.recurrenceRuleValue.until = DateTimeValue.fromJSDate(until);\n }\n recurrenceRule.until = until;\n recurrenceRule.count = null;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Changes the recurrence-rule to never end\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n changeRecurrenceToInfinite(state, _ref31) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref31;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setToInfinite();\n recurrenceRule.until = null;\n recurrenceRule.count = null;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n resetRecurrenceByParts(state, _ref32) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref32;\n if (recurrenceRule.recurrenceRuleValue) {\n const parts = ['BYSECOND', 'BYMINUTE', 'BYHOUR', 'BYDAY', 'BYMONTHDAY', 'BYYEARDAY', 'BYWEEKNO', 'BYMONTH', 'BYSETPOS'];\n for (const part of parts) {\n recurrenceRule.recurrenceRuleValue.setComponent(part, []);\n }\n Vue.set(recurrenceRule, 'byDay', []);\n Vue.set(recurrenceRule, 'byMonth', []);\n Vue.set(recurrenceRule, 'byMonthDay', []);\n Vue.set(recurrenceRule, 'bySetPosition', null);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForWeekly(state, _ref33) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref33;\n if (recurrenceRule.recurrenceRuleValue) {\n const byDay = getWeekDayFromDate(calendarObjectInstance.startDate);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', [byDay]);\n recurrenceRule.byDay.push(byDay);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForMonthly(state, _ref34) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref34;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonthDay = calendarObjectInstance.startDate.getDate().toString();\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTHDAY', [byMonthDay]);\n recurrenceRule.byMonthDay.push(byMonthDay);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForMonthlyBySetPosition(state, _ref35) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref35;\n if (recurrenceRule.recurrenceRuleValue) {\n const {\n byDay,\n bySetPosition\n } = getBySetPositionAndBySetFromDate(calendarObjectInstance.startDate);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', [byDay]);\n recurrenceRule.recurrenceRuleValue.setComponent('BYSETPOS', [bySetPosition]);\n recurrenceRule.byDay.push(byDay);\n recurrenceRule.bySetPosition = bySetPosition;\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Reset the By-parts of the recurrence rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n setDefaultRecurrenceByPartsForYearly(state, _ref36) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref36;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonth = calendarObjectInstance.startDate.getMonth() + 1; // Javascript months are zero-based\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTH', [byMonth]);\n recurrenceRule.byMonth.push(byMonth);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byDay The new until to set\n */\n addByDayToRecurrenceRule(state, _ref37) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byDay\n } = _ref37;\n if (recurrenceRule.recurrenceRuleValue) {\n const byDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYDAY');\n const index = byDayList.indexOf(byDay);\n if (index === -1) {\n byDayList.push(byDay);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', byDayList);\n }\n const index2 = recurrenceRule.byDay.indexOf(byDay);\n if (index2 === -1) {\n recurrenceRule.byDay.push(byDay);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byDay The new until to set\n */\n removeByDayFromRecurrenceRule(state, _ref38) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byDay\n } = _ref38;\n if (recurrenceRule.recurrenceRuleValue) {\n const byDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYDAY');\n const index = byDayList.indexOf(byDay);\n if (index !== -1) {\n byDayList.splice(index, 1);\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', byDayList);\n }\n const index2 = recurrenceRule.byDay.indexOf(byDay);\n if (index2 !== -1) {\n recurrenceRule.byDay.splice(index2, 1);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonthDay The new until to set\n */\n addByMonthDayToRecurrenceRule(state, _ref39) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonthDay\n } = _ref39;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonthDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTHDAY');\n const index = byMonthDayList.indexOf(byMonthDay);\n if (index === -1) {\n byMonthDayList.push(byMonthDay);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTHDAY', byMonthDayList);\n }\n const index2 = recurrenceRule.byMonthDay.indexOf(byMonthDay);\n if (index2 === -1) {\n recurrenceRule.byMonthDay.push(byMonthDay);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonthDay The new until to set\n */\n removeByMonthDayFromRecurrenceRule(state, _ref40) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonthDay\n } = _ref40;\n if (recurrenceRule.recurrenceRuleValue) {\n const byMonthDayList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTHDAY');\n const index = byMonthDayList.indexOf(byMonthDay);\n if (index !== -1) {\n byMonthDayList.splice(index, 1);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTHDAY', byMonthDayList);\n }\n const index2 = recurrenceRule.byMonthDay.indexOf(byMonthDay);\n if (index2 !== -1) {\n recurrenceRule.byMonthDay.splice(index2, 1);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonth The new until to set\n */\n addByMonthToRecurrenceRule(state, _ref41) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonth\n } = _ref41;\n if (recurrenceRule.recurrenceRuleValue) {\n console.debug('addByMonthToRecurrenceRule', byMonth);\n const byMonthList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTH');\n const index = byMonthList.indexOf(byMonth);\n if (index === -1) {\n byMonthList.push(byMonth);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTH', byMonthList);\n }\n const index2 = recurrenceRule.byMonth.indexOf(byMonth);\n if (index2 === -1) {\n recurrenceRule.byMonth.push(byMonth);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.byMonth The new until to set\n */\n removeByMonthFromRecurrenceRule(state, _ref42) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byMonth\n } = _ref42;\n if (recurrenceRule.recurrenceRuleValue) {\n console.debug('removeByMonthFromRecurrenceRule', byMonth);\n const byMonthList = recurrenceRule.recurrenceRuleValue.getComponent('BYMONTH');\n const index = byMonthList.indexOf(byMonth);\n if (index !== -1) {\n byMonthList.splice(index, 1);\n recurrenceRule.recurrenceRuleValue.setComponent('BYMONTH', byMonthList);\n }\n const index2 = recurrenceRule.byMonth.indexOf(byMonth);\n if (index2 !== -1) {\n recurrenceRule.byMonth.splice(index2, 1);\n }\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string[]} data.byDay The new until to set\n */\n changeRecurrenceByDay(state, _ref43) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n byDay\n } = _ref43;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setComponent('BYDAY', byDay);\n Vue.set(recurrenceRule, 'byDay', byDay);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Change the until limit of the recurrence-rule\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n * @param {string} data.bySetPosition The new until to set\n */\n changeRecurrenceBySetPosition(state, _ref44) {\n let {\n calendarObjectInstance,\n recurrenceRule,\n bySetPosition\n } = _ref44;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setComponent('BYSETPOS', [bySetPosition]);\n Vue.set(recurrenceRule, 'bySetPosition', bySetPosition);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n unsetRecurrenceBySetPosition(state, _ref45) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref45;\n if (recurrenceRule.recurrenceRuleValue) {\n recurrenceRule.recurrenceRuleValue.setComponent('BYSETPOS', []);\n Vue.set(recurrenceRule, 'bySetPosition', null);\n console.debug(recurrenceRule.recurrenceRuleValue._innerValue.toString());\n }\n },\n /**\n * Remove the recurrence-rule from the calendarObjectInstance\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n removeRecurrenceRuleFromCalendarObjectInstance(state, _ref46) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref46;\n if (recurrenceRule.recurrenceRuleValue) {\n calendarObjectInstance.eventComponent.deleteAllProperties('RRULE');\n Vue.set(calendarObjectInstance, 'recurrenceRule', getDefaultEventObject().recurrenceRule);\n console.debug(calendarObjectInstance);\n console.debug(recurrenceRule);\n }\n },\n /**\n * Add a new recurrence-rule to the calendarObjectInstance\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n */\n addRecurrenceRuleFromCalendarObjectInstance(state, _ref47) {\n let {\n calendarObjectInstance\n } = _ref47;\n const recurrenceValue = RecurValue.fromData({});\n const recurrenceProperty = new Property('RRULE', recurrenceValue);\n calendarObjectInstance.eventComponent.addProperty(recurrenceProperty);\n calendarObjectInstance.recurrenceRule.recurrenceRuleValue = recurrenceValue;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.recurrenceRule The recurrenceRule object to modify\n */\n markRecurrenceRuleAsSupported(state, _ref48) {\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref48;\n recurrenceRule.isUnsupported = false;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.type New type of alarm\n */\n changeAlarmType(state, _ref49) {\n let {\n calendarObjectInstance,\n alarm,\n type\n } = _ref49;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.action = type;\n alarm.type = type;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {number} data.amount New amount of timed event\n */\n changeAlarmAmountTimed(state, _ref50) {\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref50;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountAndUnitForTimedEvents(amount, alarm.relativeUnitTimed, alarm.relativeIsBefore);\n alarm.relativeAmountTimed = amount;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.unit New unit of timed event\n */\n changeAlarmUnitTimed(state, _ref51) {\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref51;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountAndUnitForTimedEvents(alarm.relativeAmountTimed, unit, alarm.relativeIsBefore);\n alarm.relativeUnitTimed = unit;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {number} data.amount New amount of all-day event\n */\n changeAlarmAmountAllDay(state, _ref52) {\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref52;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(amount, alarm.relativeHoursAllDay, alarm.relativeMinutesAllDay, alarm.relativeUnitAllDay);\n alarm.relativeAmountAllDay = amount;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.unit New Unit of all-day event\n */\n changeAlarmUnitAllDay(state, _ref53) {\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref53;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(alarm.relativeAmountAllDay, alarm.relativeHoursAllDay, alarm.relativeMinutesAllDay, unit);\n alarm.relativeUnitAllDay = unit;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {number} data.hours New Hour\n * @param {number} data.minutes New Minutes\n */\n changeAlarmHoursMinutesAllDay(state, _ref54) {\n let {\n calendarObjectInstance,\n alarm,\n hours,\n minutes\n } = _ref54;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.totalSeconds = getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(alarm.relativeAmountAllDay, hours, minutes, alarm.relativeUnitAllDay);\n alarm.relativeHoursAllDay = hours;\n alarm.relativeMinutesAllDay = minutes;\n alarm.relativeTrigger = alarm.alarmComponent.trigger.value.totalSeconds;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {Date} data.date New date object\n */\n changeAlarmAbsoluteDate(state, _ref55) {\n let {\n calendarObjectInstance,\n alarm,\n date\n } = _ref55;\n if (alarm.alarmComponent) {\n alarm.alarmComponent.trigger.value.year = date.getFullYear();\n alarm.alarmComponent.trigger.value.month = date.getMonth() + 1;\n alarm.alarmComponent.trigger.value.day = date.getDate();\n alarm.alarmComponent.trigger.value.hour = date.getHours();\n alarm.alarmComponent.trigger.value.minute = date.getMinutes();\n alarm.alarmComponent.trigger.value.second = 0;\n alarm.absoluteDate = date;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n * @param {string} data.timezoneId New timezoneId\n */\n changeAlarmAbsoluteTimezoneId(state, _ref56) {\n let {\n calendarObjectInstance,\n alarm,\n timezoneId\n } = _ref56;\n if (alarm.alarmComponent) {\n const timezone = getTimezoneManager().getTimezoneForId(timezoneId);\n alarm.alarmComponent.trigger.value.replaceTimezone(timezone);\n alarm.absoluteTimezoneId = timezoneId;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n changeAlarmFromRelativeToAbsolute(state, _ref57) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref57;\n if (alarm.alarmComponent) {\n const triggerDateTime = calendarObjectInstance.eventComponent.startDate.clone();\n // The trigger of an alarm must be DATE-TIME, startDate can be either.\n triggerDateTime.isDate = false;\n triggerDateTime.addDuration(alarm.alarmComponent.trigger.value);\n alarm.alarmComponent.setTriggerFromAbsolute(triggerDateTime);\n alarm.absoluteDate = getDateFromDateTimeValue(alarm.alarmComponent.trigger.value);\n alarm.absoluteTimezoneId = alarm.alarmComponent.trigger.value.timezoneId;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n changeAlarmFromAbsoluteToRelative(state, _ref58) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref58;\n if (alarm.alarmComponent) {\n const duration = alarm.alarmComponent.trigger.value.subtractDateWithTimezone(calendarObjectInstance.eventComponent.startDate);\n alarm.alarmComponent.setTriggerFromRelative(duration);\n alarm.relativeIsBefore = alarm.alarmComponent.trigger.value.isNegative;\n alarm.relativeIsRelatedToStart = true;\n alarm.relativeTrigger = duration.totalSeconds;\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.alarm The alarm object\n */\n resetAlarmRelativeParts(state, _ref59) {\n let {\n alarm\n } = _ref59;\n alarm.relativeIsBefore = null;\n alarm.relativeIsRelatedToStart = null;\n alarm.relativeUnitTimed = null;\n alarm.relativeAmountTimed = null;\n alarm.relativeUnitAllDay = null;\n alarm.relativeAmountAllDay = null;\n alarm.relativeHoursAllDay = null;\n alarm.relativeMinutesAllDay = null;\n alarm.relativeTrigger = null;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.alarm The alarm object\n */\n resetAlarmAbsoluteParts(state, _ref60) {\n let {\n alarm\n } = _ref60;\n alarm.absoluteDate = null;\n alarm.absoluteTimezoneId = null;\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n updateAlarmAllDayParts(state, _ref61) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref61;\n if (alarm.alarmComponent) {\n const totalSeconds = alarm.alarmComponent.trigger.value.totalSeconds;\n const allDayParts = getAmountHoursMinutesAndUnitForAllDayEvents(totalSeconds);\n alarm.relativeUnitAllDay = allDayParts.unit;\n alarm.relativeAmountAllDay = allDayParts.amount;\n alarm.relativeHoursAllDay = allDayParts.hours;\n alarm.relativeMinutesAllDay = allDayParts.minutes;\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n updateAlarmTimedParts(state, _ref62) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref62;\n if (alarm.alarmComponent) {\n const totalSeconds = alarm.alarmComponent.trigger.value.totalSeconds;\n const timedParts = getAmountAndUnitForTimedEvents(totalSeconds);\n alarm.relativeUnitTimed = timedParts.unit;\n alarm.relativeAmountTimed = timedParts.amount;\n console.debug(alarm.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data.type Type of alarm\n * @param {number} data.totalSeconds Total amount of seconds for new alarm\n */\n addAlarmToCalendarObjectInstance(state, _ref63) {\n let {\n calendarObjectInstance,\n type,\n totalSeconds\n } = _ref63;\n if (calendarObjectInstance.eventComponent) {\n const eventComponent = calendarObjectInstance.eventComponent;\n const duration = DurationValue.fromSeconds(totalSeconds);\n const alarmComponent = eventComponent.addRelativeAlarm(type, duration);\n const alarmObject = mapAlarmComponentToAlarmObject(alarmComponent);\n calendarObjectInstance.alarms.push(alarmObject);\n console.debug(alarmObject.alarmComponent.toICALJs().toString());\n }\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.alarm The alarm object\n */\n removeAlarmFromCalendarObjectInstance(state, _ref64) {\n let {\n calendarObjectInstance,\n alarm\n } = _ref64;\n if (alarm.alarmComponent) {\n calendarObjectInstance.eventComponent.removeAlarm(alarm.alarmComponent);\n const index = calendarObjectInstance.alarms.indexOf(alarm);\n if (index !== -1) {\n calendarObjectInstance.alarms.splice(index, 1);\n }\n }\n },\n /**\n * @deprecated\n * @param state\n * @param calendarObjectInstance.calendarObjectInstance\n * @param calendarObjectInstance\n * @param calendarObjectInstance.sharedData\n * @param sharedData\n */\n addAttachmentBySharedData(state, _ref65) {\n let {\n calendarObjectInstance,\n sharedData\n } = _ref65;\n const attachment = AttachmentProperty.fromLink(sharedData.url);\n const fileName = sharedData.fileName;\n\n // hot-fix needed temporary, becase calendar-js has no fileName get-setter\n const parameterFileName = new Parameter('FILENAME', fileName);\n // custom has-preview parameter from dav file\n const xNcHasPreview = new Parameter('X-NC-HAS-PREVIEW', sharedData['has-preview'].toString());\n // custom file id parameter from dav file\n const xNcFileId = new Parameter('X-NC-FILE-ID', sharedData.fileid.toString());\n // custom share-types parameter from dav file\n const xNcSharedTypes = new Parameter('X-NC-SHARED-TYPES', sharedData['share-types']['share-type'] ? sharedData['share-types']['share-type'].join(',') : '');\n attachment.setParameter(parameterFileName);\n attachment.setParameter(xNcFileId);\n attachment.setParameter(xNcHasPreview);\n attachment.setParameter(xNcSharedTypes);\n attachment.isNew = true;\n attachment.shareTypes = sharedData['share-types']['share-type'] ? sharedData['share-types']['share-type'].join(',') : '';\n attachment.fileName = fileName;\n attachment.xNcFileId = sharedData.fileid;\n attachment.xNcHasPreview = sharedData['has-preview'];\n attachment.formatType = sharedData.getcontenttype;\n attachment.uri = sharedData.url ? sharedData.url : generateUrl(\"/f/\".concat(sharedData.fileid));\n calendarObjectInstance.eventComponent.addProperty(attachment);\n calendarObjectInstance.attachments.push(attachment);\n\n // console.log(attachment)\n },\n addAttachmentWithProperty(state, _ref66) {\n var _ref67, _sharedData$shareTyp, _sharedData$shareTyp2, _sharedData$shareTyp3;\n let {\n calendarObjectInstance,\n sharedData\n } = _ref66;\n const attachment = {};\n const fileName = sharedData.fileName;\n attachment.isNew = true;\n attachment.shareTypes = (_ref67 = typeof (sharedData === null || sharedData === void 0 || (_sharedData$shareTyp = sharedData['share-types']) === null || _sharedData$shareTyp === void 0 ? void 0 : _sharedData$shareTyp['share-type']) === 'number' ? sharedData === null || sharedData === void 0 || (_sharedData$shareTyp2 = sharedData['share-types']) === null || _sharedData$shareTyp2 === void 0 || (_sharedData$shareTyp2 = _sharedData$shareTyp2['share-type']) === null || _sharedData$shareTyp2 === void 0 ? void 0 : _sharedData$shareTyp2.toString() : sharedData === null || sharedData === void 0 || (_sharedData$shareTyp3 = sharedData['share-types']) === null || _sharedData$shareTyp3 === void 0 || (_sharedData$shareTyp3 = _sharedData$shareTyp3['share-type']) === null || _sharedData$shareTyp3 === void 0 ? void 0 : _sharedData$shareTyp3.join(',')) !== null && _ref67 !== void 0 ? _ref67 : null;\n attachment.fileName = fileName;\n attachment.xNcFileId = sharedData.fileid;\n attachment.xNcHasPreview = sharedData['has-preview'];\n attachment.formatType = sharedData.getcontenttype;\n attachment.uri = sharedData.url ? sharedData.url : generateUrl(\"/f/\".concat(sharedData.fileid));\n const attachmentProperty = AttachmentProperty.fromLink(attachment.uri, attachment.formatType);\n const parameterFileName = new Parameter('FILENAME', fileName);\n const xNcHasPreview = new Parameter('X-NC-HAS-PREVIEW', attachment.xNcHasPreview.toString());\n const xNcFileId = new Parameter('X-NC-FILE-ID', attachment.xNcFileId.toString());\n // ADD X-NC-SHARED-TYPES only if sharet-type not empty\n if (attachment.shareTypes !== null) {\n const xNcSharedTypes = new Parameter('X-NC-SHARED-TYPES', attachment.shareTypes);\n attachmentProperty.setParameter(xNcSharedTypes);\n }\n attachmentProperty.setParameter(parameterFileName);\n attachmentProperty.setParameter(xNcFileId);\n attachmentProperty.setParameter(xNcHasPreview);\n attachmentProperty.uri = attachment.uri;\n attachment.attachmentProperty = attachmentProperty;\n calendarObjectInstance.eventComponent.addProperty(attachmentProperty);\n calendarObjectInstance.attachments.push(attachment);\n },\n /**\n *\n * @param {object} state The Vuex state\n * @param {object} data The destructuring object\n * @param {object} data.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data.attachment The attachment object\n */\n deleteAttachment(state, _ref68) {\n let {\n calendarObjectInstance,\n attachment\n } = _ref68;\n try {\n const index = calendarObjectInstance.attachments.indexOf(attachment);\n if (index !== -1) {\n calendarObjectInstance.attachments.splice(index, 1);\n }\n calendarObjectInstance.eventComponent.removeAttachment(attachment.attachmentProperty);\n } catch {}\n }\n};\nconst getters = {};\nconst actions = {\n /**\n * Returns the closest existing recurrence-id of a calendar-object\n * close to the given date.\n * This is either the next occurrence in the future or\n * in case there are no more future occurrences the closest\n * occurrence in the past\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {string} data.objectId The objectId of the calendar-object to edit\n * @param {Date} data.closeToDate The date to get a close occurrence to\n * @return {Promise}\n */\n async resolveClosestRecurrenceIdForCalendarObject(_ref69, _ref70) {\n let {\n state,\n dispatch,\n commit\n } = _ref69;\n let {\n objectId,\n closeToDate\n } = _ref70;\n const calendarObject = await dispatch('getEventByObjectId', {\n objectId\n });\n const iterator = calendarObject.calendarComponent.getVObjectIterator();\n const firstVObject = iterator.next().value;\n const d = DateTimeValue.fromJSDate(closeToDate, true);\n return firstVObject.recurrenceManager.getClosestOccurrence(d).getReferenceRecurrenceId().unixTime;\n },\n /**\n * Gets the calendar-object and calendar-object-instance\n * for a given objectId and recurrenceId.\n *\n * If the recurrenceId does not represent a valid instance,\n * an error will be thrown.\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {string} data.objectId The objectId of the calendar-object to edit\n * @param {number} data.recurrenceId The recurrence-id to edit\n * @return {Promise<{calendarObject: object, calendarObjectInstance: object}>}\n */\n async getCalendarObjectInstanceByObjectIdAndRecurrenceId(_ref71, _ref72) {\n let {\n state,\n dispatch,\n commit\n } = _ref71;\n let {\n objectId,\n recurrenceId\n } = _ref72;\n if (state.existingEvent.objectId === objectId && state.existingEvent.recurrenceId === recurrenceId) {\n return Promise.resolve({\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n });\n }\n const recurrenceIdDate = new Date(recurrenceId * 1000);\n const calendarObject = await dispatch('getEventByObjectId', {\n objectId\n });\n const eventComponent = getObjectAtRecurrenceId(calendarObject, recurrenceIdDate);\n if (eventComponent === null) {\n throw new Error('Not a valid recurrence-id');\n }\n const calendarObjectInstance = mapEventComponentToEventObject(eventComponent);\n commit('setCalendarObjectInstanceForExistingEvent', {\n calendarObject,\n calendarObjectInstance,\n objectId,\n recurrenceId\n });\n return {\n calendarObject,\n calendarObjectInstance\n };\n },\n /**\n * Gets the new calendar-object-instance.\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.isAllDay Whether or not the new event is supposed to be all-day\n * @param {number} data.start The start of the new event (unixtime)\n * @param {number} data.end The end of the new event (unixtime)\n * @param {string} data.timezoneId The timezoneId of the new event\n * @return {Promise<{calendarObject: object, calendarObjectInstance: object}>}\n */\n async getCalendarObjectInstanceForNewEvent(_ref73, _ref74) {\n let {\n state,\n dispatch,\n commit\n } = _ref73;\n let {\n isAllDay,\n start,\n end,\n timezoneId\n } = _ref74;\n if (state.isNew === true) {\n return Promise.resolve({\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n });\n }\n const calendarObject = await dispatch('createNewEvent', {\n start,\n end,\n isAllDay,\n timezoneId\n });\n const startDate = new Date(start * 1000);\n const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate);\n const calendarObjectInstance = mapEventComponentToEventObject(eventComponent);\n\n // Add an alarm if the user set a default one in the settings. If\n // not, defaultReminder will not be a number (rather the string \"none\").\n const defaultReminder = parseInt(settings.state.defaultReminder);\n if (!isNaN(defaultReminder)) {\n commit('addAlarmToCalendarObjectInstance', {\n calendarObjectInstance,\n type: 'DISPLAY',\n totalSeconds: defaultReminder\n });\n logger.debug(\"Added defaultReminder (\".concat(defaultReminder, \"s) to newly created event\"));\n }\n\n // Add default status\n const rfcProps = getRFCProperties();\n const status = rfcProps.status.defaultValue;\n commit('changeStatus', {\n calendarObjectInstance,\n status\n });\n commit('setCalendarObjectInstanceForNewEvent', {\n calendarObject,\n calendarObjectInstance\n });\n return {\n calendarObject,\n calendarObjectInstance\n };\n },\n /**\n * Updates the existing calendar-object-instance.\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.isAllDay Whether or not the new event is supposed to be all-day\n * @param {number} data.start The start of the new event (unixtime)\n * @param {number} data.end The end of the new event (unixtime)\n * @param {string} data.timezoneId The timezoneId of the new event\n * @return {Promise<{calendarObject: object, calendarObjectInstance: object}>}\n */\n async updateCalendarObjectInstanceForNewEvent(_ref75, _ref76) {\n let {\n state,\n dispatch,\n commit\n } = _ref75;\n let {\n isAllDay,\n start,\n end,\n timezoneId\n } = _ref76;\n await dispatch('updateTimeOfNewEvent', {\n calendarObjectInstance: state.calendarObjectInstance,\n start,\n end,\n isAllDay,\n timezoneId\n });\n commit('setCalendarObjectInstanceForNewEvent', {\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n });\n return {\n calendarObject: state.calendarObject,\n calendarObjectInstance: state.calendarObjectInstance\n };\n },\n /**\n * Saves changes made to a single calendar-object-instance\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.thisAndAllFuture Whether or not to save changes for all future occurrences or just this one\n * @param {string} data.calendarId The new calendar-id to store it in\n * @return {Promise}\n */\n async saveCalendarObjectInstance(_ref77, _ref78) {\n let {\n state,\n dispatch,\n commit\n } = _ref77;\n let {\n thisAndAllFuture,\n calendarId\n } = _ref78;\n const eventComponent = state.calendarObjectInstance.eventComponent;\n const calendarObject = state.calendarObject;\n updateAlarms(eventComponent);\n updateTalkParticipants(eventComponent);\n let additionalFieldWasUpdated = eventComponent.isPrivate != null || eventComponent.client != null;\n if (eventComponent.isDirty() || additionalFieldWasUpdated) {\n const isForkedItem = eventComponent.primaryItem !== null;\n let original = null;\n let fork = null;\n\n // We check if two things apply:\n // - primaryItem !== null -> Is this a fork or not?\n // - eventComponent.canCreateRecurrenceExceptions() - Can we create a recurrence-exception for this item\n if (isForkedItem && eventComponent.canCreateRecurrenceExceptions()) {\n [original, fork] = eventComponent.createRecurrenceException(thisAndAllFuture);\n }\n await dispatch('updateCalendarObject', {\n calendarObject\n });\n if (original !== null && fork !== null && original.root !== fork.root) {\n await dispatch('createCalendarObjectFromFork', {\n eventComponent: fork,\n calendarId\n });\n }\n }\n if (calendarId !== state.calendarObject.calendarId) {\n await dispatch('moveCalendarObject', {\n calendarObject,\n newCalendarId: calendarId\n });\n }\n },\n /**\n * Duplicate calendar-object-instance\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @return {Promise}\n */\n async duplicateCalendarObjectInstance(_ref79) {\n let {\n state,\n dispatch,\n commit\n } = _ref79;\n const oldCalendarObjectInstance = state.calendarObjectInstance;\n const oldEventComponent = oldCalendarObjectInstance.eventComponent;\n const startDate = oldEventComponent.startDate.getInUTC();\n const endDate = oldEventComponent.endDate.getInUTC();\n const calendarObject = await dispatch('createNewEvent', {\n start: startDate.unixTime,\n end: endDate.unixTime,\n timezoneId: oldEventComponent.startDate.timezoneId,\n isAllDay: oldEventComponent.isAllDay()\n });\n const eventComponent = getObjectAtRecurrenceId(calendarObject, startDate.jsDate);\n copyCalendarObjectInstanceIntoEventComponent(oldCalendarObjectInstance, eventComponent);\n const calendarObjectInstance = mapEventComponentToEventObject(eventComponent);\n await commit('setCalendarObjectInstanceForNewEvent', {\n calendarObject,\n calendarObjectInstance\n });\n },\n /**\n * Deletes a calendar-object-instance\n *\n * @param {object} vuex The vuex destructuring object\n * @param {object} vuex.state The Vuex state\n * @param {Function} vuex.dispatch The Vuex dispatch function\n * @param {Function} vuex.commit The Vuex commit function\n * @param {object} data The destructuring object\n * @param {boolean} data.thisAndAllFuture Whether or not to delete all future occurrences or just this one\n * @return {Promise}\n */\n async deleteCalendarObjectInstance(_ref80, _ref81) {\n let {\n state,\n dispatch,\n commit\n } = _ref80;\n let {\n thisAndAllFuture\n } = _ref81;\n const eventComponent = state.calendarObjectInstance.eventComponent;\n const isRecurrenceSetEmpty = eventComponent.removeThisOccurrence(thisAndAllFuture);\n const calendarObject = state.calendarObject;\n if (isRecurrenceSetEmpty) {\n await dispatch('deleteCalendarObject', {\n calendarObject\n });\n } else {\n await dispatch('updateCalendarObject', {\n calendarObject\n });\n }\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {Date} data2.startDate The new start-date\n */\n changeStartDate(_ref82, _ref83) {\n let {\n commit\n } = _ref82;\n let {\n calendarObjectInstance,\n startDate\n } = _ref83;\n const difference = startDate.getTime() - calendarObjectInstance.startDate.getTime();\n const endDate = new Date(calendarObjectInstance.endDate.getTime() + difference);\n commit('changeStartDate', {\n calendarObjectInstance,\n startDate\n });\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate\n });\n },\n /**\n * Change the timezone of the event's start\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data2.startTimezone New timezone to set for start\n */\n changeStartTimezone(_ref84, _ref85) {\n let {\n commit\n } = _ref84;\n let {\n calendarObjectInstance,\n startTimezone\n } = _ref85;\n commit('changeStartTimezone', {\n calendarObjectInstance,\n startTimezone\n });\n\n // Simulate a change of the start time to trigger the comparison\n // of start and end and trigger an update of end if necessary\n commit('changeStartDate', {\n calendarObjectInstance,\n startDate: calendarObjectInstance.startDate\n });\n },\n /**\n * Change the timezone of the event's end\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {string} data2.endTimezone New timezone to set for end\n */\n changeEndTimezone(_ref86, _ref87) {\n let {\n commit\n } = _ref86;\n let {\n calendarObjectInstance,\n endTimezone\n } = _ref87;\n commit('changeEndTimezone', {\n calendarObjectInstance,\n endTimezone\n });\n\n // Simulate a change of the end time to trigger the comparison\n // of start and end and trigger an update of start if necessary\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate: calendarObjectInstance.endDate\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {Function} data.dispatch The Vuex dispatch function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n * @param {string} data2.frequency The new frequency to set\n */\n changeRecurrenceFrequency(_ref88, _ref89) {\n let {\n commit,\n dispatch\n } = _ref88;\n let {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n } = _ref89;\n console.debug(calendarObjectInstance);\n console.debug(recurrenceRule);\n console.debug(frequency);\n if (recurrenceRule.frequency === 'NONE' && frequency !== 'NONE') {\n // Add a new recurrence-rule\n commit('addRecurrenceRuleFromCalendarObjectInstance', {\n calendarObjectInstance\n });\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceFrequency', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule,\n frequency\n });\n commit('changeRecurrenceInterval', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule,\n interval: 1\n });\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule\n });\n dispatch('setDefaultRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n });\n console.debug(\"changed from none to \".concat(frequency));\n } else if (recurrenceRule.frequency !== 'NONE' && frequency === 'NONE') {\n console.debug('calling removeRecurrenceRuleFromCalendarObjectInstance');\n // Remove the recurrence-rule\n commit('removeRecurrenceRuleFromCalendarObjectInstance', {\n calendarObjectInstance,\n recurrenceRule\n });\n } else {\n // Change frequency of existing recurrence-rule\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceFrequency', {\n calendarObjectInstance,\n recurrenceRule: calendarObjectInstance.recurrenceRule,\n frequency\n });\n dispatch('setDefaultRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n });\n }\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n * @param {string} data2.frequency The new frequency to set\n */\n setDefaultRecurrenceByParts(_ref90, _ref91) {\n let {\n commit\n } = _ref90;\n let {\n calendarObjectInstance,\n recurrenceRule,\n frequency\n } = _ref91;\n switch (frequency) {\n case 'WEEKLY':\n commit('setDefaultRecurrenceByPartsForWeekly', {\n calendarObjectInstance,\n recurrenceRule\n });\n break;\n case 'MONTHLY':\n commit('setDefaultRecurrenceByPartsForMonthly', {\n calendarObjectInstance,\n recurrenceRule\n });\n break;\n case 'YEARLY':\n commit('setDefaultRecurrenceByPartsForYearly', {\n calendarObjectInstance,\n recurrenceRule\n });\n break;\n }\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n setRecurrenceToInfinite(_ref92, _ref93) {\n let {\n commit\n } = _ref92;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref93;\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n changeMonthlyRecurrenceFromByDayToBySetPosition(_ref94, _ref95) {\n let {\n commit\n } = _ref94;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref95;\n console.debug('changeMonthlyRecurrenceFromByDayToBySetPosition');\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('setDefaultRecurrenceByPartsForMonthlyBySetPosition', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n changeMonthlyRecurrenceFromBySetPositionToByDay(_ref96, _ref97) {\n let {\n commit\n } = _ref96;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref97;\n console.debug('changeMonthlyRecurrenceFromBySetPositionToByDay');\n commit('resetRecurrenceByParts', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('setDefaultRecurrenceByPartsForMonthly', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n enableYearlyRecurrenceBySetPosition(_ref98, _ref99) {\n let {\n commit\n } = _ref98;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref99;\n commit('setDefaultRecurrenceByPartsForMonthlyBySetPosition', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n disableYearlyRecurrenceBySetPosition(_ref100, _ref101) {\n let {\n commit\n } = _ref100;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref101;\n commit('changeRecurrenceByDay', {\n calendarObjectInstance,\n recurrenceRule,\n byDay: []\n });\n commit('unsetRecurrenceBySetPosition', {\n calendarObjectInstance,\n recurrenceRule\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n enableRecurrenceLimitByUntil(_ref102, _ref103) {\n let {\n commit\n } = _ref102;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref103;\n let until;\n switch (recurrenceRule.frequency) {\n // Defaults to 7 days\n case 'DAILY':\n until = new Date(calendarObjectInstance.startDate.getTime() + 7 * 24 * 60 * 60 * 1000);\n break;\n\n // Defaults to 4 weeks\n case 'WEEKLY':\n until = new Date(calendarObjectInstance.startDate.getTime() + 4 * 7 * 24 * 60 * 60 * 1000);\n break;\n\n // Defaults to 10 year\n case 'YEARLY':\n until = new Date(calendarObjectInstance.startDate.getFullYear() + 10, calendarObjectInstance.startDate.getMonth(), calendarObjectInstance.startDate.getDate(), 23, 59, 59);\n break;\n\n // Defaults to 12 months\n case 'MONTHLY':\n default:\n until = new Date(calendarObjectInstance.startDate.getFullYear() + 1, calendarObjectInstance.startDate.getMonth(), calendarObjectInstance.startDate.getDate(), 23, 59, 59);\n break;\n }\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceUntil', {\n calendarObjectInstance,\n recurrenceRule,\n until\n });\n },\n /**\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {object} data2 The destructuring object for data\n * @param {object} data2.calendarObjectInstance The calendarObjectInstance object\n * @param {object} data2.recurrenceRule The recurrenceRule object to modify\n */\n enableRecurrenceLimitByCount(_ref104, _ref105) {\n let {\n commit\n } = _ref104;\n let {\n calendarObjectInstance,\n recurrenceRule\n } = _ref105;\n commit('changeRecurrenceToInfinite', {\n calendarObjectInstance,\n recurrenceRule\n });\n commit('changeRecurrenceCount', {\n calendarObjectInstance,\n recurrenceRule,\n count: 2 // Default value is two\n });\n },\n changeAlarmAmountTimed(_ref106, _ref107) {\n let {\n commit\n } = _ref106;\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref107;\n commit('changeAlarmAmountTimed', {\n calendarObjectInstance,\n alarm,\n amount\n });\n commit('updateAlarmAllDayParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmUnitTimed(_ref108, _ref109) {\n let {\n commit\n } = _ref108;\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref109;\n commit('changeAlarmUnitTimed', {\n calendarObjectInstance,\n alarm,\n unit\n });\n commit('updateAlarmAllDayParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmAmountAllDay(_ref110, _ref111) {\n let {\n commit\n } = _ref110;\n let {\n calendarObjectInstance,\n alarm,\n amount\n } = _ref111;\n commit('changeAlarmAmountAllDay', {\n calendarObjectInstance,\n alarm,\n amount\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmUnitAllDay(_ref112, _ref113) {\n let {\n commit\n } = _ref112;\n let {\n calendarObjectInstance,\n alarm,\n unit\n } = _ref113;\n commit('changeAlarmUnitAllDay', {\n calendarObjectInstance,\n alarm,\n unit\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmHoursMinutesAllDay(_ref114, _ref115) {\n let {\n commit\n } = _ref114;\n let {\n calendarObjectInstance,\n alarm,\n hours,\n minutes\n } = _ref115;\n commit('changeAlarmHoursMinutesAllDay', {\n calendarObjectInstance,\n alarm,\n hours,\n minutes\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n },\n changeAlarmFromRelativeToAbsolute(_ref116, _ref117) {\n let {\n commit\n } = _ref116;\n let {\n calendarObjectInstance,\n alarm\n } = _ref117;\n commit('changeAlarmFromRelativeToAbsolute', {\n calendarObjectInstance,\n alarm\n });\n commit('resetAlarmRelativeParts', {\n alarm\n });\n },\n changeAlarmFromAbsoluteToRelative(_ref118, _ref119) {\n let {\n commit\n } = _ref118;\n let {\n calendarObjectInstance,\n alarm\n } = _ref119;\n commit('changeAlarmFromAbsoluteToRelative', {\n calendarObjectInstance,\n alarm\n });\n commit('updateAlarmAllDayParts', {\n calendarObjectInstance,\n alarm\n });\n commit('updateAlarmTimedParts', {\n calendarObjectInstance,\n alarm\n });\n commit('resetAlarmAbsoluteParts', {\n alarm\n });\n },\n toggleAllDay(_ref120, _ref121) {\n let {\n commit,\n getters\n } = _ref120;\n let {\n calendarObjectInstance\n } = _ref121;\n commit('toggleAllDay', {\n calendarObjectInstance\n });\n if (!calendarObjectInstance.isAllDay) {\n if (calendarObjectInstance.startTimezoneId === 'floating') {\n const startTimezone = getters.getResolvedTimezone;\n commit('changeStartTimezone', {\n calendarObjectInstance,\n startTimezone\n });\n }\n commit('changeTimeToDefaultForTimedEvents', {\n calendarObjectInstance\n });\n }\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\n * @copyright Copyright (c) 2019 Georg Ehrke\n *\n * @author Georg Ehrke \n *\n * @author John Molakvoæ \n *\n * @author Thomas Citharel \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 .\n *\n */\nimport Vue from 'vue';\nimport { mapCalendarJsToCalendarObject, setClientValueToIcsAndReturnIcs, setCustomKeyValuesArrayToIcsAndReturnIcs } from '../models/calendarObject.js';\nimport logger from '../utils/logger.js';\nimport { createEvent, getParserManager, getTimezoneManager, DateTimeValue } from '@nextcloud/calendar-js';\nconst state = {\n calendarObjects: {},\n modificationCount: 0\n};\nconst mutations = {\n /**\n * Adds an array of calendar-objects to the store\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object[]} data.calendarObjects Calendar-objects to add\n */\n appendCalendarObjects(state, _ref) {\n let {\n calendarObjects = []\n } = _ref;\n for (const calendarObject of calendarObjects) {\n if (!state.calendarObjects[calendarObject.id]) {\n Vue.set(state.calendarObjects, calendarObject.id, calendarObject);\n }\n }\n },\n /**\n * Adds one calendar-object to the store\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to add\n */\n appendCalendarObject(state, _ref2) {\n let {\n calendarObject\n } = _ref2;\n if (!state.calendarObjects[calendarObject.id]) {\n Vue.set(state.calendarObjects, calendarObject.id, calendarObject);\n }\n },\n /**\n * Updates a calendar-object id\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to update\n */\n updateCalendarObjectId(state, _ref3) {\n let {\n calendarObject\n } = _ref3;\n if (calendarObject.dav === null) {\n calendarObject.id = null;\n } else {\n calendarObject.id = btoa(calendarObject.dav.url);\n }\n },\n /**\n * Updates a calendar-object's calendarId\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {string} data.calendarObjectId Id of calendar-object to update\n * @param {string} data.calendarId New calendarId\n */\n updateCalendarObjectIdCalendarId(state, _ref4) {\n let {\n calendarObjectId,\n calendarId\n } = _ref4;\n state.calendarObjects[calendarObjectId].calendarId = calendarId;\n },\n /**\n * Resets a calendar-object to it's original server state\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to reset\n */\n resetCalendarObjectToDav(state, _ref5) {\n let {\n calendarObject\n } = _ref5;\n calendarObject = state.calendarObjects[calendarObject.id];\n\n // If this object does not exist on the server yet, there is nothing to do\n if (!calendarObject || !calendarObject.existsOnServer) {\n return;\n }\n const parserManager = getParserManager();\n const parser = parserManager.getParserForFileType('text/calendar');\n parser.parse(calendarObject.dav.data);\n const itemIterator = parser.getItemIterator();\n const firstVCalendar = itemIterator.next().value;\n if (firstVCalendar) {\n calendarObject.calendarComponent = firstVCalendar;\n }\n },\n /**\n * Removes a calendar-object from the store\n *\n * @param {object} state The store data\n * @param {object} data The destructuring object\n * @param {object} data.calendarObject Calendar-object to delete\n */\n deleteCalendarObject(state, _ref6) {\n let {\n calendarObject\n } = _ref6;\n Vue.delete(state.calendarObjects, calendarObject.id);\n },\n /**\n * Increments the modification count\n *\n * @param {object} state The store data\n */\n incrementModificationCount(state) {\n state.modificationCount++;\n }\n};\nconst getters = {\n /**\n * Gets a calendar-object based on its id\n *\n * @param {object} state The store data\n * @return {function({String}): CalendarObject}\n */\n getCalendarObjectById: state => id => state.calendarObjects[id]\n};\nconst actions = {\n /**\n * Moves a calendar-object to a different calendar\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {CalendarObject} data.calendarObject Calendar-object to delete\n * @param {string} data.newCalendarId Calendar-Id of calendar to move this calendar-object to\n * @return {Promise}\n */\n async moveCalendarObject(context, _ref7) {\n let {\n calendarObject,\n newCalendarId\n } = _ref7;\n if (!calendarObject.existsOnServer) {\n return;\n }\n const oldCalendarObjectId = calendarObject.id;\n const oldCalendarId = calendarObject.calendarId;\n if (oldCalendarId === newCalendarId) {\n logger.error('Old calendar Id and new calendar Id are the same, nothing to move …');\n return;\n }\n const newCalendar = context.getters.getCalendarById(newCalendarId);\n if (!newCalendar) {\n logger.error('Calendar to move to not found, aborting …');\n return;\n }\n await calendarObject.dav.move(newCalendar.dav);\n // Update calendarId in calendarObject manually as it is not stored in dav\n context.commit('updateCalendarObjectIdCalendarId', {\n calendarObjectId: calendarObject.id,\n calendarId: newCalendarId\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: newCalendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: newCalendarId,\n calendarObjectId: calendarObject.id\n });\n context.commit('deleteCalendarObjectFromCalendar', {\n calendar: {\n id: oldCalendarId\n },\n calendarObjectId: oldCalendarObjectId\n });\n context.commit('removeCalendarObjectIdFromAllTimeRangesOfCalendar', {\n calendarId: oldCalendarId,\n calendarObjectId: oldCalendarObjectId\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Updates a calendar-object\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {CalendarObject} data.calendarObject Calendar-object to delete\n * @return {Promise}\n */\n async updateCalendarObject(context, _ref8) {\n let {\n calendarObject\n } = _ref8;\n let eventComponent = calendarObject.calendarComponent.getFirstComponent('VEVENT');\n if (calendarObject.existsOnServer) {\n let icsValue = calendarObject.calendarComponent.toICS();\n if (eventComponent != null) {\n if (eventComponent.client != null) {\n let newClientKeyValue = \"CLIENT:\" + eventComponent.client;\n icsValue = icsValue.replace(/CLIENT:\\d+/, newClientKeyValue);\n }\n if (eventComponent.isPrivate != null) {\n let isPrivateValue = eventComponent.isPrivate ? \"1\" : \"0\";\n let newIsPrivateKeyValue = \"ISPRIVATE:\" + isPrivateValue;\n let regex = /ISPRIVATE:\\d+/;\n if (regex.test(icsValue)) {\n icsValue = icsValue.replace(regex, newIsPrivateKeyValue);\n } else {\n const customKeyValue = {\n \"ISPRIVATE\": isPrivateValue\n };\n icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue, customKeyValue);\n }\n }\n }\n calendarObject.dav.data = icsValue;\n await calendarObject.dav.update();\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendarObject.calendarId,\n calendarObjectId: calendarObject.id\n });\n context.commit('resetCalendarObjectToDav', {\n calendarObject\n });\n context.commit('incrementModificationCount');\n return;\n // TODO - catch conflicts\n }\n const calendar = context.getters.getCalendarById(calendarObject.calendarId);\n let icsValue = calendarObject.calendarComponent.toICS();\n if (eventComponent != null) {\n const customKeyValue = {\n \"CLIENT\": eventComponent.client,\n \"EMBALMER\": eventComponent.embalmer,\n \"ISPRIVATE\": eventComponent.isPrivate ? \"1\" : \"0\"\n };\n icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue, customKeyValue);\n }\n calendarObject.dav = await calendar.dav.createVObject(icsValue);\n calendarObject.existsOnServer = true;\n context.commit('updateCalendarObjectId', {\n calendarObject\n });\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: calendarObject.calendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendarObject.calendarId,\n calendarObjectId: calendarObject.id\n });\n context.commit('resetCalendarObjectToDav', {\n calendarObject\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Creates a new calendar-object from an recurrence-exception fork\n *\n * @param {object} context The Vuex context\n * @param {object} data destructuring object\n * @param {EventComponent} data.eventComponent EventComponent to store\n * @param {string} data.calendarId The calendar-id to store it in\n * @return {Promise}\n */\n async createCalendarObjectFromFork(context, _ref9) {\n let {\n eventComponent,\n calendarId\n } = _ref9;\n const calendar = context.getters.getCalendarById(calendarId);\n const calendarObject = mapCalendarJsToCalendarObject(eventComponent.root, calendar.id);\n calendarObject.dav = await calendar.dav.createVObject(calendarObject.calendarComponent.toICS());\n calendarObject.existsOnServer = true;\n context.commit('updateCalendarObjectId', {\n calendarObject\n });\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: calendarObject.calendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendar.id,\n calendarObjectId: calendarObject.id\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Deletes a calendar-object\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {CalendarObject} data.calendarObject Calendar-object to delete\n * @return {Promise}\n */\n async deleteCalendarObject(context, _ref10) {\n let {\n calendarObject\n } = _ref10;\n // If this calendar-object was not created on the server yet,\n // no need to send requests to the server\n if (calendarObject.existsOnServer) {\n await calendarObject.dav.delete();\n }\n context.commit('deleteCalendarObject', {\n calendarObject\n });\n context.commit('deleteCalendarObjectFromCalendar', {\n calendar: {\n id: calendarObject.calendarId\n },\n calendarObjectId: calendarObject.id\n });\n context.commit('removeCalendarObjectIdFromAnyTimeRange', {\n calendarObjectId: calendarObject.id\n });\n context.commit('incrementModificationCount');\n },\n /**\n * Creates a new calendar object based on start, end, timezone and isAllDay\n *\n * @param {object} context the store mutations\n * @param {object} data destructuring object\n * @param {number} data.start Timestamp for start of new event\n * @param {number} data.end Timestamp for end of new event\n * @param {string} data.timezoneId asd\n * @param {boolean} data.isAllDay foo\n * @return {Promise}\n */\n createNewEvent(context, _ref11) {\n let {\n start,\n end,\n timezoneId,\n isAllDay\n } = _ref11;\n const timezoneManager = getTimezoneManager();\n const timezone = timezoneManager.getTimezoneForId(timezoneId);\n const startDate = new Date(start * 1000);\n const endDate = new Date(end * 1000);\n const startDateTime = DateTimeValue.fromJSDate(startDate, true).getInTimezone(timezone);\n const endDateTime = DateTimeValue.fromJSDate(endDate, true).getInTimezone(timezone);\n if (isAllDay) {\n startDateTime.isDate = true;\n endDateTime.isDate = true;\n }\n const calendar = createEvent(startDateTime, endDateTime);\n for (const vObject of calendar.getVObjectIterator()) {\n vObject.undirtify();\n }\n const firstCalendar = context.getters.sortedCalendars[0].id;\n return Promise.resolve(mapCalendarJsToCalendarObject(calendar, firstCalendar));\n },\n /**\n * Updates the time of the new calendar object\n *\n * @param {object} data The destructuring object for Vuex\n * @param {Function} data.commit The Vuex commit function\n * @param {Function} data.dispatch The Vuex dispatch function\n * @param {object} data2 destructuring object\n * @param {CalendarObject} data2.calendarObjectInstance Calendar-object to\n * @param {number} data2.start Timestamp for start of new event\n * @param {number} data2.end Timestamp for end of new event\n * @param {string} data2.timezoneId asd\n * @param {boolean} data2.isAllDay foo\n */\n updateTimeOfNewEvent(_ref12, _ref13) {\n let {\n commit,\n dispatch\n } = _ref12;\n let {\n calendarObjectInstance,\n start,\n end,\n timezoneId,\n isAllDay\n } = _ref13;\n const isDirty = calendarObjectInstance.eventComponent.isDirty();\n const startDate = new Date(start * 1000);\n const endDate = new Date(end * 1000);\n if (calendarObjectInstance.isAllDay !== isAllDay) {\n commit('toggleAllDay', {\n calendarObjectInstance\n });\n }\n dispatch('changeStartTimezone', {\n calendarObjectInstance,\n startTimezone: timezoneId\n });\n dispatch('changeEndTimezone', {\n calendarObjectInstance,\n endTimezone: timezoneId\n });\n commit('changeStartDate', {\n calendarObjectInstance,\n startDate\n });\n if (isAllDay) {\n // The full-calendar end date is exclusive, but the end-date\n // that changeEndDate expects is inclusive, so we have to deduct one day.\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate: new Date(endDate.getTime() - 24 * 60 * 60 * 1000)\n });\n } else {\n commit('changeEndDate', {\n calendarObjectInstance,\n endDate\n });\n }\n if (!isDirty) {\n calendarObjectInstance.eventComponent.undirtify();\n }\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @copyright Copyright (c) 2019 John Molakvoæ\r\n *\r\n * @copyright Copyright (c) 2019 Thomas Citharel\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @author Thomas Citharel \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nimport { createCalendar, createSubscription, findAll, findAllDeletedCalendars, findPublicCalendarsByTokens } from '../services/caldavService.js';\nimport { mapCDavObjectToCalendarObject } from '../models/calendarObject.js';\nimport { dateFactory, getUnixTimestampFromDate } from '../utils/date.js';\nimport { getDefaultCalendarObject, mapDavCollectionToCalendar } from '../models/calendar.js';\nimport pLimit from 'p-limit';\nimport { uidToHexColor } from '../utils/color.js';\nimport { translate as t } from '@nextcloud/l10n';\nimport getTimezoneManager from '../services/timezoneDataProviderService.js';\nimport { CalendarComponent, Timezone, TimezoneComponent } from '@nextcloud/calendar-js';\nimport { CALDAV_BIRTHDAY_CALENDAR, IMPORT_STAGE_IMPORTING, IMPORT_STAGE_PROCESSING } from '../models/consts.js';\nimport { showError } from '@nextcloud/dialogs';\nconst state = {\n calendars: [],\n trashBin: undefined,\n scheduleInbox: undefined,\n deletedCalendars: [],\n deletedCalendarObjects: [],\n calendarsById: {},\n initialCalendarsLoaded: false,\n editCalendarModal: undefined,\n widgetView: 'dayGridMonth',\n widgetDate: 'now',\n widgetEventDetailsOpen: false,\n widgetEventDetails: {},\n widgetRef: undefined\n};\nconst mutations = {\n /**\r\n * Adds calendar into state\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to add\r\n */\n addCalendar(state, _ref) {\n let {\n calendar\n } = _ref;\n const object = getDefaultCalendarObject(calendar);\n if (!state.calendars.some(existing => existing.id === object.id)) {\n state.calendars.push(object);\n }\n Vue.set(state.calendarsById, object.id, object);\n },\n addTrashBin(state, _ref2) {\n let {\n trashBin\n } = _ref2;\n state.trashBin = trashBin;\n },\n setWidgetView(state, _ref3) {\n let {\n viewName\n } = _ref3;\n state.widgetView = viewName;\n },\n setWidgetDate(state, _ref4) {\n let {\n widgetDate\n } = _ref4;\n state.widgetDate = widgetDate;\n },\n setWidgetRef(state, _ref5) {\n let {\n widgetRef\n } = _ref5;\n state.widgetRef = widgetRef;\n },\n setSelectedEvent(state, _ref6) {\n let {\n object,\n recurrenceId\n } = _ref6;\n state.widgetEventDetailsOpen = true;\n state.widgetEventDetails = {\n object,\n recurrenceId\n };\n },\n closeWidgetEventDetails(state) {\n state.widgetEventDetailsOpen = false;\n },\n addScheduleInbox(state, _ref7) {\n let {\n scheduleInbox\n } = _ref7;\n state.scheduleInbox = scheduleInbox;\n },\n /**\r\n * Adds deleted calendar into state\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar calendar the calendar to add\r\n */\n addDeletedCalendar(state, _ref8) {\n let {\n calendar\n } = _ref8;\n if (state.deletedCalendars.some(c => c.url === calendar.url)) {\n // This calendar is already known\n return;\n }\n state.deletedCalendars.push(calendar);\n },\n /**\r\n * Removes a deleted calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the deleted calendar to remove\r\n */\n removeDeletedCalendar(state, _ref9) {\n let {\n calendar\n } = _ref9;\n state.deletedCalendars = state.deletedCalendars.filter(c => c !== calendar);\n },\n /**\r\n * Removes a deleted calendar object\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.vobject the deleted calendar object to remove\r\n */\n removeDeletedCalendarObject(state, _ref10) {\n let {\n vobject\n } = _ref10;\n state.deletedCalendarObjects = state.deletedCalendarObjects.filter(vo => vo.id !== vobject.id);\n },\n /**\r\n * Adds a deleted vobject into state\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.vobject the calendar vobject to add\r\n */\n addDeletedCalendarObject(state, _ref11) {\n let {\n vobject\n } = _ref11;\n if (state.deletedCalendarObjects.some(c => c.uri === vobject.uri)) {\n // This vobject is already known\n return;\n }\n state.deletedCalendarObjects.push(vobject);\n },\n /**\r\n * Deletes a calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to delete\r\n */\n deleteCalendar(state, _ref12) {\n let {\n calendar\n } = _ref12;\n state.calendars.splice(state.calendars.indexOf(calendar), 1);\n Vue.delete(state.calendarsById, calendar.id);\n },\n /**\r\n * Toggles a calendar's visibility\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to toggle\r\n */\n toggleCalendarEnabled(state, _ref13) {\n let {\n calendar\n } = _ref13;\n state.calendarsById[calendar.id].enabled = !state.calendarsById[calendar.id].enabled;\n },\n /**\r\n * Renames a calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to rename\r\n * @param {string} data.newName the new name of the calendar\r\n */\n renameCalendar(state, _ref14) {\n let {\n calendar,\n newName\n } = _ref14;\n state.calendarsById[calendar.id].displayName = newName;\n },\n /**\r\n * Changes calendar's color\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to rename\r\n * @param {string} data.newColor the new color of the calendar\r\n */\n changeCalendarColor(state, _ref15) {\n let {\n calendar,\n newColor\n } = _ref15;\n state.calendarsById[calendar.id].color = newColor;\n },\n /**\r\n * Changes calendar's order\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to rename\r\n * @param {string} data.newOrder the new order of the calendar\r\n */\n changeCalendarOrder(state, _ref16) {\n let {\n calendar,\n newOrder\n } = _ref16;\n state.calendarsById[calendar.id].order = newOrder;\n },\n /**\r\n * Adds multiple calendar-objects to calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to append objects to\r\n * @param {string[]} data.calendarObjectIds The calendar object ids to append\r\n */\n appendCalendarObjectsToCalendar(state, _ref17) {\n let {\n calendar,\n calendarObjectIds\n } = _ref17;\n for (const calendarObjectId of calendarObjectIds) {\n if (state.calendarsById[calendar.id].calendarObjects.indexOf(calendarObjectId) === -1) {\n state.calendarsById[calendar.id].calendarObjects.push(calendarObjectId);\n }\n }\n },\n /**\r\n * Adds calendar-object to calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to append objects to\r\n * @param {string} data.calendarObjectId The calendar object id to append\r\n */\n addCalendarObjectToCalendar(state, _ref18) {\n let {\n calendar,\n calendarObjectId\n } = _ref18;\n if (state.calendarsById[calendar.id].calendarObjects.indexOf(calendarObjectId) === -1) {\n state.calendarsById[calendar.id].calendarObjects.push(calendarObjectId);\n }\n },\n /**\r\n * Removes calendar-object from calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to delete objects from\r\n * @param {string} data.calendarObjectId The calendar object ids to delete\r\n */\n deleteCalendarObjectFromCalendar(state, _ref19) {\n let {\n calendar,\n calendarObjectId\n } = _ref19;\n const index = state.calendarsById[calendar.id].calendarObjects.indexOf(calendarObjectId);\n if (index !== -1) {\n state.calendarsById[calendar.id].calendarObjects.slice(index, 1);\n }\n },\n /**\r\n * Adds fetched time-range to calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to append a time-range to\r\n * @param {number} data.fetchedTimeRangeId The time-range-id to append\r\n */\n addFetchedTimeRangeToCalendar(state, _ref20) {\n let {\n calendar,\n fetchedTimeRangeId\n } = _ref20;\n state.calendarsById[calendar.id].fetchedTimeRanges.push(fetchedTimeRangeId);\n },\n /**\r\n * Removes fetched time-range from calendar\r\n *\r\n * @param {object} state the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar The calendar to remove a time-range from\r\n * @param {number} data.fetchedTimeRangeId The time-range-id to remove\r\n */\n deleteFetchedTimeRangeFromCalendar(state, _ref21) {\n let {\n calendar,\n fetchedTimeRangeId\n } = _ref21;\n const index = state.calendarsById[calendar.id].fetchedTimeRanges.indexOf(fetchedTimeRangeId);\n if (index !== -1) {\n state.calendarsById[calendar.id].fetchedTimeRanges.slice(index, 1);\n }\n },\n /**\r\n * Shares calendar with a user or group\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar\r\n * @param {string} data.user the userId\r\n * @param {string} data.displayName the displayName\r\n * @param {string} data.uri the sharing principalScheme uri\r\n * @param {boolean} data.isGroup is this a group?\r\n * @param {boolean} data.isCircle is this a circle?\r\n */\n shareCalendar(state, _ref22) {\n let {\n calendar,\n user,\n displayName,\n uri,\n isGroup,\n isCircle\n } = _ref22;\n const newSharee = {\n displayName,\n id: user,\n writeable: false,\n isGroup,\n isCircle,\n uri\n };\n state.calendarsById[calendar.id].shares.push(newSharee);\n },\n /**\r\n * Removes Sharee from calendar shares list\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar\r\n * @param {string} data.uri the sharee uri\r\n */\n unshareCalendar(state, _ref23) {\n let {\n calendar,\n uri\n } = _ref23;\n calendar = state.calendars.find(search => search.id === calendar.id);\n const shareIndex = calendar.shares.findIndex(sharee => sharee.uri === uri);\n calendar.shares.splice(shareIndex, 1);\n },\n /**\r\n * Toggles sharee's writable permission\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar\r\n * @param {string} data.uri the sharee uri\r\n */\n toggleCalendarShareWritable(state, _ref24) {\n let {\n calendar,\n uri\n } = _ref24;\n calendar = state.calendars.find(search => search.id === calendar.id);\n const sharee = calendar.shares.find(sharee => sharee.uri === uri);\n sharee.writeable = !sharee.writeable;\n },\n /**\r\n * Publishes a calendar calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to publish\r\n * @param {string} data.publishURL published URL of calendar\r\n */\n publishCalendar(state, _ref25) {\n let {\n calendar,\n publishURL\n } = _ref25;\n calendar = state.calendars.find(search => search.id === calendar.id);\n calendar.publishURL = publishURL;\n },\n /**\r\n * Unpublishes a calendar\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to unpublish\r\n */\n unpublishCalendar(state, _ref26) {\n let {\n calendar\n } = _ref26;\n calendar = state.calendars.find(search => search.id === calendar.id);\n calendar.publishURL = null;\n },\n /**\r\n * Marks initial loading of calendars as complete\r\n *\r\n * @param {object} state the store data\r\n */\n initialCalendarsLoaded(state) {\n state.initialCalendarsLoaded = true;\n },\n /**\r\n * Marks a calendar as loading\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to mark as loading\r\n */\n markCalendarAsLoading(state, _ref27) {\n let {\n calendar\n } = _ref27;\n state.calendarsById[calendar.id].loading = true;\n },\n /**\r\n * Marks a calendar as finished loading\r\n *\r\n * @param {object} state the store data\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to mark as finished loading\r\n */\n markCalendarAsNotLoading(state, _ref28) {\n let {\n calendar\n } = _ref28;\n state.calendarsById[calendar.id].loading = false;\n },\n showEditCalendarModal(state, _ref29) {\n let {\n calendarId\n } = _ref29;\n state.editCalendarModal = {\n calendarId\n };\n },\n hideEditCalendarModal(state) {\n state.editCalendarModal = undefined;\n },\n setCalendarDeleteCountdown(state, _ref30) {\n let {\n calendar,\n countdown\n } = _ref30;\n Vue.set(state.calendarsById[calendar.id], 'countdown', countdown);\n },\n setCalendarDeleteHandles(state, _ref31) {\n let {\n calendar,\n deleteTimeout,\n deleteInterval\n } = _ref31;\n Vue.set(state.calendarsById[calendar.id], 'deleteTimeout', deleteTimeout);\n Vue.set(state.calendarsById[calendar.id], 'deleteInterval', deleteInterval);\n }\n};\nconst getters = {\n /**\r\n * List of sorted calendars and subscriptions\r\n *\r\n * @param {object} state the store data\r\n * @param {object} store the store\r\n * @param {object} rootState the rootState\r\n * @return {Array}\r\n */\n sortedCalendarsSubscriptions(state, store, rootState) {\n return state.calendars.filter(calendar => calendar.supportsEvents || rootState.settings.showTasks && calendar.supportsTasks).sort((a, b) => a.order - b.order);\n },\n /**\r\n * List of sorted calendars\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n sortedCalendars(state) {\n return state.calendars.filter(calendar => calendar.supportsEvents).filter(calendar => !calendar.readOnly).sort((a, b) => a.order - b.order);\n },\n /**\r\n * List of sorted calendars owned by the principal\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n ownSortedCalendars(state) {\n return state.calendars.filter(calendar => calendar.supportsEvents).filter(calendar => !calendar.readOnly).filter(calendar => !calendar.isSharedWithMe).sort((a, b) => a.order - b.order);\n },\n widgetView(state) {\n return state.widgetView;\n },\n widgetDate(state) {\n return state.widgetDate;\n },\n widgetEventDetailsOpen(state) {\n return state.widgetEventDetailsOpen;\n },\n widgetRef(state) {\n return state.widgetRef;\n },\n hasTrashBin(state) {\n return state.trashBin !== undefined && state.trashBin.retentionDuration !== 0;\n },\n trashBin(state) {\n return state.trashBin;\n },\n scheduleInbox: state => {\n return state.scheduleInbox;\n },\n /**\r\n * List of deleted sorted calendars\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n sortedDeletedCalendars(state) {\n return state.deletedCalendars.sort((a, b) => a.deletedAt - b.deletedAt);\n },\n /**\r\n * List of deleted calendars objects\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n deletedCalendarObjects(state) {\n const calendarUriMap = {};\n state.calendars.forEach(calendar => {\n const withoutTrail = calendar.url.replace(/\\/$/, '');\n const uri = withoutTrail.slice(withoutTrail.lastIndexOf('/') + 1);\n calendarUriMap[uri] = calendar;\n });\n return state.deletedCalendarObjects.map(obj => ({\n calendar: calendarUriMap[obj.dav._props['{http://nextcloud.com/ns}calendar-uri']],\n ...obj\n }));\n },\n /**\r\n * List of sorted subscriptions\r\n *\r\n * @param {object} state the store data\r\n * @return {Array}\r\n */\n sortedSubscriptions(state) {\n return state.calendars.filter(calendar => calendar.supportsEvents).filter(calendar => calendar.readOnly).sort((a, b) => a.order - b.order);\n },\n /**\r\n * List of enabled calendars and subscriptions\r\n *\r\n * @param {object} state the store data\r\n * @param {object} store the store\r\n * @param {object} rootState the rootState\r\n * @return {Array}\r\n */\n enabledCalendars(state, store, rootState) {\n return state.calendars.filter(calendar => calendar.supportsEvents || rootState.settings.showTasks && calendar.supportsTasks).filter(calendar => calendar.enabled);\n },\n /**\r\n * Gets a calendar by it's Id\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getCalendarById: state => calendarId => state.calendarsById[calendarId],\n /**\r\n * Gets a calendar by its url\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getCalendarByUrl: state => url => state.calendars.find(calendar => calendar.url === url),\n /**\r\n * Gets the contact's birthday calendar or null\r\n *\r\n * @param {object} state the store data\r\n * @return {object | null}\r\n */\n getBirthdayCalendar: state => {\n for (const calendar of state.calendars) {\n const url = calendar.url.slice(0, -1);\n const lastSlash = url.lastIndexOf('/');\n const uri = url.slice(lastSlash + 1);\n if (uri === CALDAV_BIRTHDAY_CALENDAR) {\n return calendar;\n }\n }\n return null;\n },\n /**\r\n * Whether or not a birthday calendar exists\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} getters the vuex getters\r\n * @return {boolean}\r\n */\n hasBirthdayCalendar: (state, getters) => {\n return !!getters.getBirthdayCalendar;\n },\n /**\r\n *\r\n * @param {object} state the store data\r\n * @param {object} getters the store getters\r\n * @return {function({Boolean}, {Boolean}, {Boolean}): {Object}[]}\r\n */\n sortedCalendarFilteredByComponents: (state, getters) => (vevent, vjournal, vtodo) => {\n return getters.sortedCalendars.filter(calendar => {\n if (vevent && !calendar.supportsEvents) {\n return false;\n }\n if (vjournal && !calendar.supportsJournals) {\n return false;\n }\n if (vtodo && !calendar.supportsTasks) {\n return false;\n }\n return true;\n });\n },\n editCalendarModal: state => state.editCalendarModal\n};\nconst actions = {\n /**\r\n * Retrieve and commit calendars and other collections\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} context.state the store state\r\n * @param {object} context.getters the store getters\r\n * @return {Promise} the results\r\n */\n async loadCollections(_ref32) {\n let {\n commit,\n state,\n getters\n } = _ref32;\n const {\n calendars,\n trashBins,\n scheduleInboxes,\n subscriptions\n } = await findAll();\n console.info('calendar home scanned', calendars, trashBins, subscriptions);\n calendars.map(calendar => mapDavCollectionToCalendar(calendar, getters.getCurrentUserPrincipal)).forEach(calendar => {\n commit('addCalendar', {\n calendar\n });\n });\n if (trashBins.length) {\n commit('addTrashBin', {\n trashBin: trashBins[0]\n });\n }\n if (scheduleInboxes.length) {\n commit('addScheduleInbox', {\n scheduleInbox: scheduleInboxes[0]\n });\n }\n commit('initialCalendarsLoaded');\n return {\n calendars: state.calendars,\n trashBin: state.trashBin\n };\n },\n /**\r\n * Retrieve and commit deleted calendars\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @return {Promise} the calendars\r\n */\n async loadDeletedCalendars(_ref33) {\n let {\n commit\n } = _ref33;\n const calendars = await findAllDeletedCalendars();\n calendars.forEach(calendar => commit('addDeletedCalendar', {\n calendar\n }));\n },\n /**\r\n * Retrieve and commit deleted calendar objects\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} context.state the store state\r\n */\n async loadDeletedCalendarObjects(_ref34) {\n let {\n commit,\n state\n } = _ref34;\n const vobjects = await state.trashBin.findDeletedObjects();\n console.info('vobjects loaded', {\n vobjects\n });\n vobjects.forEach(vobject => {\n try {\n const calendarObject = mapCDavObjectToCalendarObject(vobject, undefined);\n commit('addDeletedCalendarObject', {\n vobject: calendarObject\n });\n } catch (error) {\n console.error('could not convert calendar object', vobject, error);\n }\n });\n },\n /**\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} data The data destructuring object\r\n * @param {string[]} data.tokens The tokens to load\r\n * @return {Promise}\r\n */\n async getPublicCalendars(_ref35, _ref36) {\n let {\n commit\n } = _ref35;\n let {\n tokens\n } = _ref36;\n const calendars = await findPublicCalendarsByTokens(tokens);\n const calendarObjects = [];\n for (const davCalendar of calendars) {\n const calendar = mapDavCollectionToCalendar(davCalendar);\n commit('addCalendar', {\n calendar\n });\n calendarObjects.push(calendar);\n }\n commit('initialCalendarsLoaded');\n return calendarObjects;\n },\n /**\r\n * Append a new calendar to array of existing calendars\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.displayName The name of the new calendar\r\n * @param {object} data.color The color of the new calendar\r\n * @param {object} data.order The order of the new calendar\r\n * @param {string[]} data.components The supported components of the calendar\r\n * @param {string=} data.timezone The timezoneId\r\n * @return {Promise}\r\n */\n async appendCalendar(context, _ref37) {\n let {\n displayName,\n color,\n order,\n components = ['VEVENT'],\n timezone = null\n } = _ref37;\n if (timezone === null) {\n timezone = context.getters.getResolvedTimezone;\n }\n let timezoneIcs = null;\n const timezoneObject = getTimezoneManager().getTimezoneForId(timezone);\n if (timezoneObject !== Timezone.utc && timezoneObject !== Timezone.floating) {\n const calendar = CalendarComponent.fromEmpty();\n calendar.addComponent(TimezoneComponent.fromICALJs(timezoneObject.toICALJs()));\n timezoneIcs = calendar.toICS(false);\n }\n const response = await createCalendar(displayName, color, components, order, timezoneIcs);\n const calendar = mapDavCollectionToCalendar(response, context.getters.getCurrentUserPrincipal);\n context.commit('addCalendar', {\n calendar\n });\n },\n /**\r\n * Append a new subscription to array of existing calendars\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {string} data.displayName Name of new subscription\r\n * @param {string} data.color Color of new subscription\r\n * @param {string} data.order Order of new subscription\r\n * @param {string} data.source Source of new subscription\r\n * @return {Promise}\r\n */\n async appendSubscription(context, _ref38) {\n let {\n displayName,\n color,\n order,\n source\n } = _ref38;\n const response = await createSubscription(displayName, color, source, order);\n const calendar = mapDavCollectionToCalendar(response, context.getters.getCurrentUserPrincipal);\n context.commit('addCalendar', {\n calendar\n });\n },\n /**\r\n * Delete a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to delete\r\n * @return {Promise}\r\n */\n async deleteCalendar(context, _ref39) {\n let {\n calendar\n } = _ref39;\n await calendar.dav.delete();\n context.commit('deleteCalendar', {\n calendar\n });\n },\n /**\r\n * Delete a calendar in the trash bin\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to delete\r\n * @return {Promise}\r\n */\n async deleteCalendarPermanently(context, _ref40) {\n let {\n calendar\n } = _ref40;\n await calendar.delete({\n 'X-NC-CalDAV-No-Trashbin': 1\n });\n context.commit('removeDeletedCalendar', {\n calendar\n });\n },\n deleteCalendarAfterTimeout(context, _ref41) {\n let {\n calendar,\n countdown = 7\n } = _ref41;\n context.commit('setCalendarDeleteCountdown', {\n calendar,\n countdown\n });\n const deleteInterval = setInterval(() => {\n countdown--;\n if (countdown < 0) {\n countdown = 0;\n }\n context.commit('setCalendarDeleteCountdown', {\n calendar,\n countdown\n });\n }, 1000);\n const deleteTimeout = setTimeout(async () => {\n try {\n await context.dispatch('deleteCalendar', {\n calendar\n });\n } catch (error) {\n showError(t('calendar', 'An error occurred, unable to delete the calendar.'));\n console.error(error);\n } finally {\n clearInterval(deleteInterval);\n }\n }, 7000);\n context.commit('setCalendarDeleteHandles', {\n calendar,\n deleteInterval,\n deleteTimeout\n });\n },\n cancelCalendarDeletion(context, _ref42) {\n let {\n calendar\n } = _ref42;\n if (calendar.deleteInterval) clearInterval(calendar.deleteInterval);\n if (calendar.deleteTimeout) clearTimeout(calendar.deleteTimeout);\n context.commit('setCalendarDeleteHandles', {\n calendar,\n deleteInterval: undefined,\n deleteTimeout: undefined\n });\n },\n async restoreCalendar(_ref43, _ref44) {\n let {\n commit,\n state\n } = _ref43;\n let {\n calendar\n } = _ref44;\n await state.trashBin.restore(calendar.url);\n commit('removeDeletedCalendar', {\n calendar\n });\n },\n async restoreCalendarObject(_ref45, _ref46) {\n var _component$startDate, _component$endDate;\n let {\n commit,\n state,\n getters\n } = _ref45;\n let {\n vobject\n } = _ref46;\n await state.trashBin.restore(vobject.uri);\n\n // Clean up the data locally\n commit('removeDeletedCalendarObject', {\n vobject\n });\n\n // Delete cached time range that includes the restored event\n const calendarObject = mapCDavObjectToCalendarObject(vobject.dav, undefined);\n const component = calendarObject.calendarComponent.getFirstComponent(vobject.objectType);\n const timeRange = getters.getTimeRangeForCalendarCoveringRange(vobject.calendar.id, (_component$startDate = component.startDate) === null || _component$startDate === void 0 ? void 0 : _component$startDate.unixTime, (_component$endDate = component.endDate) === null || _component$endDate === void 0 ? void 0 : _component$endDate.unixTime);\n if (timeRange) {\n commit('deleteFetchedTimeRangeFromCalendar', {\n calendar: vobject.calendar,\n fetchedTimeRangeId: timeRange.id\n });\n commit('removeTimeRange', {\n timeRangeId: timeRange.id\n });\n }\n\n // Trigger calendar refresh\n commit('incrementModificationCount');\n },\n /**\r\n * Deletes a calendar-object permanently\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {vobject} data.vobject Calendar-object to delete\r\n * @return {Promise}\r\n */\n async deleteCalendarObjectPermanently(context, _ref47) {\n let {\n vobject\n } = _ref47;\n await vobject.dav.delete({\n 'X-NC-CalDAV-No-Trashbin': 1\n });\n context.commit('removeDeletedCalendarObject', {\n vobject\n });\n },\n /**\r\n * Toggle whether a calendar is enabled\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to modify\r\n * @return {Promise}\r\n */\n async toggleCalendarEnabled(context, _ref48) {\n let {\n calendar\n } = _ref48;\n context.commit('markCalendarAsLoading', {\n calendar\n });\n calendar.dav.enabled = !calendar.dav.enabled;\n try {\n await calendar.dav.update();\n context.commit('markCalendarAsNotLoading', {\n calendar\n });\n context.commit('toggleCalendarEnabled', {\n calendar\n });\n } catch (error) {\n context.commit('markCalendarAsNotLoading', {\n calendar\n });\n throw error;\n }\n },\n /**\r\n * Rename a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to modify\r\n * @param {string} data.newName the new name of the calendar\r\n * @return {Promise}\r\n */\n async renameCalendar(context, _ref49) {\n let {\n calendar,\n newName\n } = _ref49;\n calendar.dav.displayname = newName;\n await calendar.dav.update();\n context.commit('renameCalendar', {\n calendar,\n newName\n });\n },\n /**\r\n * Change a calendar's color\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to modify\r\n * @param {string} data.newColor the new color of the calendar\r\n * @return {Promise}\r\n */\n async changeCalendarColor(context, _ref50) {\n let {\n calendar,\n newColor\n } = _ref50;\n calendar.dav.color = newColor;\n await calendar.dav.update();\n context.commit('changeCalendarColor', {\n calendar,\n newColor\n });\n },\n /**\r\n * Share calendar with User or Group\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to share\r\n * @param {string} data.user the userId\r\n * @param {string} data.displayName the displayName\r\n * @param {string} data.uri the sharing principalScheme uri\r\n * @param {boolean} data.isGroup is this a group?\r\n * @param {boolean} data.isCircle is this a circle?\r\n */\n async shareCalendar(context, _ref51) {\n let {\n calendar,\n user,\n displayName,\n uri,\n isGroup,\n isCircle\n } = _ref51;\n // Share calendar with entered group or user\n await calendar.dav.share(uri);\n context.commit('shareCalendar', {\n calendar,\n user,\n displayName,\n uri,\n isGroup,\n isCircle\n });\n },\n /**\r\n * Toggle permissions of calendar Sharees writeable rights\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @param {string} data.uri the sharing principalScheme uri\r\n */\n async toggleCalendarShareWritable(context, _ref52) {\n let {\n calendar,\n uri\n } = _ref52;\n const sharee = calendar.shares.find(sharee => sharee.uri === uri);\n await calendar.dav.share(uri, !sharee.writeable);\n context.commit('toggleCalendarShareWritable', {\n calendar,\n uri\n });\n },\n /**\r\n * Remove sharee from calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @param {string} data.uri the sharing principalScheme uri\r\n */\n async unshareCalendar(context, _ref53) {\n let {\n calendar,\n uri\n } = _ref53;\n await calendar.dav.unshare(uri);\n context.commit('unshareCalendar', {\n calendar,\n uri\n });\n },\n /**\r\n * Publish a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @return {Promise}\r\n */\n async publishCalendar(context, _ref54) {\n let {\n calendar\n } = _ref54;\n await calendar.dav.publish();\n const publishURL = calendar.dav.publishURL;\n context.commit('publishCalendar', {\n calendar,\n publishURL\n });\n },\n /**\r\n * Unpublish a calendar\r\n *\r\n * @param {object} context the store mutations Current context\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to change\r\n * @return {Promise}\r\n */\n async unpublishCalendar(context, _ref55) {\n let {\n calendar\n } = _ref55;\n await calendar.dav.unpublish();\n context.commit('unpublishCalendar', {\n calendar\n });\n },\n /**\r\n * Retrieve the events of the specified calendar\r\n * and commit the results\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {object} data.calendar the calendar to get events from\r\n * @param {Date} data.from the date to start querying events from\r\n * @param {Date} data.to the last date to query events from\r\n * @return {Promise}\r\n */\n async getEventsFromCalendarInTimeRange(context, _ref56) {\n let {\n calendar,\n from,\n to\n } = _ref56;\n context.commit('markCalendarAsLoading', {\n calendar\n });\n const response = await calendar.dav.findByTypeInTimeRange('VEVENT', from, to);\n let responseTodo = [];\n if (context.rootState.settings.showTasks) {\n responseTodo = await calendar.dav.findByTypeInTimeRange('VTODO', from, to);\n }\n context.commit('addTimeRange', {\n calendarId: calendar.id,\n from: getUnixTimestampFromDate(from),\n to: getUnixTimestampFromDate(to),\n lastFetched: getUnixTimestampFromDate(dateFactory()),\n calendarObjectIds: []\n });\n const insertId = context.getters.getLastTimeRangeInsertId;\n context.commit('addFetchedTimeRangeToCalendar', {\n calendar,\n fetchedTimeRangeId: insertId\n });\n const calendarObjects = [];\n const calendarObjectIds = [];\n for (const r of response.concat(responseTodo)) {\n try {\n const calendarObject = mapCDavObjectToCalendarObject(r, calendar.id);\n calendarObjects.push(calendarObject);\n calendarObjectIds.push(calendarObject.id);\n } catch (e) {\n console.error(\"could not convert calendar object of calendar \".concat(calendar.id), e, {\n response: r\n });\n }\n }\n context.commit('appendCalendarObjects', {\n calendarObjects\n });\n context.commit('appendCalendarObjectsToCalendar', {\n calendar,\n calendarObjectIds\n });\n context.commit('appendCalendarObjectIdsToTimeFrame', {\n timeRangeId: insertId,\n calendarObjectIds\n });\n context.commit('markCalendarAsNotLoading', {\n calendar\n });\n return context.rootState.fetchedTimeRanges.lastTimeRangeInsertId;\n },\n /**\r\n * Retrieve one object\r\n *\r\n * @param {object} context the store mutations\r\n * @param {object} data destructuring object\r\n * @param {string} data.objectId Id of the object to fetch\r\n * @return {Promise}\r\n */\n async getEventByObjectId(context, _ref57) {\n let {\n objectId\n } = _ref57;\n // TODO - we should still check if the calendar-object is up to date\n // - Just send head and compare etags\n if (context.getters.getCalendarObjectById(objectId)) {\n return Promise.resolve(context.getters.getCalendarObjectById(objectId));\n }\n\n // This might throw an exception, but we will leave it up to the methods\n // calling this action to properly handle it\n const objectPath = atob(objectId);\n const lastSlashIndex = objectPath.lastIndexOf('/');\n const calendarPath = objectPath.slice(0, lastSlashIndex + 1);\n const objectFileName = objectPath.slice(lastSlashIndex + 1);\n const calendarId = btoa(calendarPath);\n if (!context.state.calendarsById[calendarId]) {\n return Promise.reject(new Error(''));\n }\n const calendar = context.state.calendarsById[calendarId];\n const vObject = await calendar.dav.find(objectFileName);\n const calendarObject = mapCDavObjectToCalendarObject(vObject, calendar.id);\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar: {\n id: calendarId\n },\n calendarObjectId: calendarObject.id\n });\n return calendarObject;\n },\n /**\r\n * Import events into calendar\r\n *\r\n * @param {object} context the store mutations\r\n */\n async importEventsIntoCalendar(context) {\n context.commit('changeStage', IMPORT_STAGE_IMPORTING);\n\n // Create a copy\n const files = context.rootState.importFiles.importFiles.slice();\n let totalCount = 0;\n for (const file of files) {\n totalCount += file.parser.getItemCount();\n const calendarId = context.rootState.importFiles.importCalendarRelation[file.id];\n if (calendarId === 'new') {\n const displayName = file.parser.getName() || t('calendar', 'Imported {filename}', {\n filename: file.name\n });\n const color = file.parser.getColor() || uidToHexColor(displayName);\n const components = [];\n if (file.parser.containsVEvents()) {\n components.push('VEVENT');\n }\n if (file.parser.containsVJournals()) {\n components.push('VJOURNAL');\n }\n if (file.parser.containsVTodos()) {\n components.push('VTODO');\n }\n const response = await createCalendar(displayName, color, components, 0);\n const calendar = mapDavCollectionToCalendar(response, context.getters.getCurrentUserPrincipal);\n context.commit('addCalendar', {\n calendar\n });\n context.commit('setCalendarForFileId', {\n fileId: file.id,\n calendarId: calendar.id\n });\n }\n }\n context.commit('setTotal', totalCount);\n const limit = pLimit(3);\n const requests = [];\n for (const file of files) {\n const calendarId = context.rootState.importFiles.importCalendarRelation[file.id];\n const calendar = context.getters.getCalendarById(calendarId);\n for (const item of file.parser.getItemIterator()) {\n requests.push(limit(async () => {\n const ics = item.toICS();\n let davObject;\n try {\n davObject = await calendar.dav.createVObject(ics);\n } catch (error) {\n context.commit('incrementDenied');\n console.error(error);\n return;\n }\n const calendarObject = mapCDavObjectToCalendarObject(davObject, calendarId);\n context.commit('appendCalendarObject', {\n calendarObject\n });\n context.commit('addCalendarObjectToCalendar', {\n calendar,\n calendarObjectId: calendarObject.id\n });\n context.commit('addCalendarObjectIdToAllTimeRangesOfCalendar', {\n calendarId: calendar.id,\n calendarObjectId: calendarObject.id\n });\n context.commit('incrementAccepted');\n }));\n }\n }\n await Promise.all(requests);\n context.commit('changeStage', IMPORT_STAGE_PROCESSING);\n },\n /**\r\n *\r\n * @param {object} context the store object\r\n * @param {object} context.commit the store mutations\r\n * @param {object} context.state the store state\r\n * @param {object} data The data destructuring object\r\n * @param {object} data.newOrder The object containing String => Number with the new order\r\n * @return {Promise}\r\n */\n async updateCalendarListOrder(_ref58, _ref59) {\n let {\n state,\n commit\n } = _ref58;\n let {\n newOrder\n } = _ref59;\n // keep a record of the original order in case we need to do a rollback\n\n const limit = pLimit(3);\n const requests = [];\n const calendarsToUpdate = [];\n for (const key in newOrder) {\n requests.push(limit(async () => {\n const calendar = state.calendarsById[key];\n\n // Do not update unless necessary\n if (calendar.dav.order === newOrder[key]) {\n return;\n }\n calendar.dav.order = newOrder[key];\n await calendar.dav.update();\n calendarsToUpdate.push({\n calendar,\n newOrder: newOrder[key]\n });\n }));\n }\n await Promise.all(requests);\n for (const {\n calendar,\n newOrder\n } of calendarsToUpdate) {\n console.debug(calendar, newOrder);\n commit('changeCalendarOrder', {\n calendar,\n newOrder\n });\n }\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nconst state = {\n contacts: [],\n contactByEMail: {}\n};\nconst mutations = {\n /**\r\n * Append a single contact to the store\r\n *\r\n * @param {object} state The store data\r\n * @param {object} data The destructuring object\r\n * @param {object} data.contact The contact to append to the store\r\n */\n appendContact(state, _ref) {\n let {\n contact\n } = _ref;\n if (state.contacts.indexOf(contact) === -1) {\n state.contacts.push(contact);\n }\n for (const email of contact.emails) {\n // In the unlikely case that multiple contacts\n // share the same email address, we will just follow\n // first come, first served.\n if (state.contactByEMail[email] === undefined) {\n Vue.set(state.contactByEMail, email, contact);\n }\n }\n },\n /**\r\n * Removes a single contact from the store\r\n *\r\n * @param {object} state The store data\r\n * @param {object} data The destructuring object\r\n * @param {object} data.contact The contact to remove from the store\r\n */\n removeContact(state, _ref2) {\n let {\n contact\n } = _ref2;\n for (const email of contact.emails) {\n if (state.contactByEMail[email] === contact) {\n Vue.delete(state.contactByEMail, email);\n }\n }\n const index = state.contacts.indexOf(contact);\n if (index !== -1) {\n state.contacts.splice(index, 1);\n }\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nconst state = {\n minimumDate: '1970-01-01T00:00:00Z',\n maximumDate: '2037-12-31T23:59:59Z'\n};\nconst mutations = {\n /**\r\n * Initialize restrictions imposed by CalDAV server\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.minimumDate The minimum-date allowed by the CalDAV server\r\n * @param {string} data.maximumDate The maximum-date allowed by the CalDAV server\r\n */\n loadDavRestrictionsFromServer(state, _ref) {\n let {\n minimumDate,\n maximumDate\n } = _ref;\n state.minimumDate = minimumDate;\n state.maximumDate = maximumDate;\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nconst state = {\n lastTimeRangeInsertId: -1,\n fetchedTimeRanges: [],\n fetchedTimeRangesById: {}\n};\nconst mutations = {\n /**\r\n * Adds a fetched time-range to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarId Calendar-id which objects have been fetched\r\n * @param {number} data.from timestamp of start\r\n * @param {number} data.to timestamp of end\r\n * @param {number} data.lastFetched timestamp of last-fetched\r\n * @param {string[]} data.calendarObjectIds array of calendarObjectIds\r\n */\n addTimeRange(state, _ref) {\n let {\n calendarId,\n from,\n to,\n lastFetched,\n calendarObjectIds\n } = _ref;\n const fetchedTimeRange = {\n id: ++state.lastTimeRangeInsertId,\n calendarId,\n from,\n to,\n lastFetched,\n calendarObjectIds\n };\n state.fetchedTimeRanges.push(fetchedTimeRange);\n Vue.set(state.fetchedTimeRangesById, fetchedTimeRange.id, fetchedTimeRange);\n },\n /**\r\n * Removes a fetched time-range from the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId Id of time-range to remove\r\n */\n removeTimeRange(state, _ref2) {\n let {\n timeRangeId\n } = _ref2;\n const obj = state.fetchedTimeRangesById[timeRangeId];\n const index = state.fetchedTimeRanges.indexOf(obj);\n if (index !== -1) {\n state.fetchedTimeRanges.splice(index, 1);\n Vue.delete(state.fetchedTimeRangesById, timeRangeId);\n }\n },\n /**\r\n * Adds a calendar-object-id to an already fetched time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the time-range\r\n * @param {string[]} data.calendarObjectIds The array of ids of the calendar-object to add\r\n */\n appendCalendarObjectIdsToTimeFrame(state, _ref3) {\n let {\n timeRangeId,\n calendarObjectIds\n } = _ref3;\n for (const calendarObjectId of calendarObjectIds) {\n if (state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.indexOf(calendarObjectId) === -1) {\n state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.push(calendarObjectId);\n }\n }\n },\n /**\r\n * Adds a calendar-object-id to an already fetched time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the time-range\r\n * @param {string} data.calendarObjectId The id of the calendar-object to add\r\n */\n appendCalendarObjectIdToTimeRange(state, _ref4) {\n let {\n timeRangeId,\n calendarObjectId\n } = _ref4;\n state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.push(calendarObjectId);\n },\n /**\r\n * Removes a calendar-object-id from an already fetched time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the timerange\r\n * @param {string} data.calendarObjectId The id of the calendar-object to remove\r\n */\n removeCalendarObjectIdFromTimeRange(state, _ref5) {\n let {\n timeRangeId,\n calendarObjectId\n } = _ref5;\n const index = state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.indexOf(calendarObjectId);\n if (index !== -1) {\n state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.splice(index, 1);\n }\n },\n /**\r\n * Removes a calendar-object-id from any time-range it may occur in\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarObjectId The id of the calendar-object to remove\r\n */\n removeCalendarObjectIdFromAnyTimeRange(state, _ref6) {\n let {\n calendarObjectId\n } = _ref6;\n for (const timeRange of state.fetchedTimeRanges) {\n const index = timeRange.calendarObjectIds.indexOf(calendarObjectId);\n if (index !== -1) {\n timeRange.calendarObjectIds.splice(index, 1);\n }\n }\n },\n /**\r\n * Updates the last-fetched timestamp of a time-range\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.timeRangeId The id of the timerange\r\n * @param {number} data.lastFetched Timestamp of last-fetched\r\n */\n updateTimestampOfLastFetched(state, _ref7) {\n let {\n timeRangeId,\n lastFetched\n } = _ref7;\n state.fetchedTimeRangesById[timeRangeId].lastFetched = lastFetched;\n },\n /**\r\n * Adds a calendar-object-id to all time-ranges of a given caloendar\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarObjectId The id of the calendar-object\r\n * @param {string} data.calendarId The id of the calendar\r\n */\n addCalendarObjectIdToAllTimeRangesOfCalendar(state, _ref8) {\n let {\n calendarObjectId,\n calendarId\n } = _ref8;\n for (const timerange of state.fetchedTimeRanges) {\n if (timerange.calendarId !== calendarId) {\n continue;\n }\n if (timerange.calendarObjectIds.indexOf(calendarObjectId) === -1) {\n timerange.calendarObjectIds.push(calendarObjectId);\n }\n }\n },\n /**\r\n * Removes a calendar-object-id to all time-ranges of a given caloendar\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.calendarObjectId The id of the calendar-object\r\n * @param {string} data.calendarId The id of the calendar\r\n */\n removeCalendarObjectIdFromAllTimeRangesOfCalendar(state, _ref9) {\n let {\n calendarObjectId,\n calendarId\n } = _ref9;\n for (const timerange of state.fetchedTimeRanges) {\n if (timerange.calendarId !== calendarId) {\n continue;\n }\n const index = timerange.calendarObjectIds.indexOf(calendarObjectId);\n if (index !== -1) {\n timerange.calendarObjectIds.splice(index, 1);\n }\n }\n },\n /**\r\n * clear FetchedTimeRanges Store\r\n *\r\n * @param {object} state The vuex state\r\n */\n clearFetchedTimeRanges(state) {\n state.lastTimeRangeInsertId = -1;\n state.fetchedTimeRanges = [];\n state.fetchedTimeRangesById = {};\n }\n};\nconst getters = {\n /**\r\n * Get all time-ranges for a calendar\r\n *\r\n * @param {object} state The vuex state\r\n * @return {function({String}): {Object}[]}\r\n */\n getAllTimeRangesForCalendar: state => calendarId => state.fetchedTimeRanges.filter(f => f.calendarId === calendarId),\n /**\r\n * Get time-range covering\r\n *\r\n * @param {object} state The vuex state\r\n * @return {function({Number}, {Number}, {Number}): {Object}|false}\r\n */\n getTimeRangeForCalendarCoveringRange: state => (calendarId, requestedFrom, requestedTo) => {\n return state.fetchedTimeRanges.find(f => {\n return f.calendarId === calendarId && f.from <= requestedFrom && f.to >= requestedTo;\n });\n },\n /**\r\n * Get all time-ranges that have been last fetched before a given time\r\n *\r\n * @param {object} state The vuex state\r\n * @return {function({Number}): {Object}[]}\r\n */\n getAllTimeRangesOlderThan: state => olderThan => state.fetchedTimeRanges.filter(f => f.lastFetched <= olderThan),\n /**\r\n *\r\n * @param {object} state The vuex state\r\n * @return {number}\r\n */\n getLastTimeRangeInsertId: state => state.lastTimeRangeInsertId,\n /**\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} getters The vuex getters\r\n * @return {function({Number}): {CalendarObject}[]}\r\n */\n getCalendarObjectsByTimeRangeId: (state, getters) => timeRangeId => {\n if (!state.fetchedTimeRangesById[timeRangeId]) {\n return [];\n }\n return state.fetchedTimeRangesById[timeRangeId].calendarObjectIds.map(calendarObjectId => {\n return getters.getCalendarObjectById(calendarObjectId);\n });\n }\n};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Team Popcorn \r\n *\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Team Popcorn \r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nconst state = {\n lastFileInsertId: -1,\n importFiles: [],\n importFilesById: {},\n importCalendarRelation: {}\n};\nconst mutations = {\n /**\r\n * Adds a file to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.contents Contents of file\r\n * @param {number} data.lastModified Timestamp of last modification\r\n * @param {string} data.name Name of file\r\n * @param {AbstractParser} data.parser The parser\r\n * @param {number} data.size Size of file\r\n * @param {string} data.type mime-type of file\r\n */\n addFile(state, _ref) {\n let {\n contents,\n lastModified,\n name,\n parser,\n size,\n type\n } = _ref;\n const file = {\n id: ++state.lastFileInsertId,\n contents,\n lastModified,\n name,\n parser,\n size,\n type\n };\n state.importFiles.push(file);\n Vue.set(state.importFilesById, file.id, file);\n },\n /**\r\n * Sets a calendar for the file\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {number} data.fileId Id of file to select calendar for\r\n * @param {string} data.calendarId Id of calendar to import file into\r\n */\n setCalendarForFileId(state, _ref2) {\n let {\n fileId,\n calendarId\n } = _ref2;\n Vue.set(state.importCalendarRelation, fileId, calendarId);\n },\n /**\r\n * Removes all files from state\r\n *\r\n * @param {object} state The vuex state\r\n */\n removeAllFiles(state) {\n Vue.set(state, 'importFiles', []);\n Vue.set(state, 'importFilesById', {});\n Vue.set(state, 'importCalendarRelation', {});\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Team Popcorn \r\n *\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n *\r\n * @author Team Popcorn \r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { IMPORT_STAGE_DEFAULT } from '../models/consts.js';\nconst state = {\n total: 0,\n accepted: 0,\n denied: 0,\n stage: IMPORT_STAGE_DEFAULT\n};\nconst mutations = {\n /**\r\n * Increment the number of calendar-objects accepted\r\n *\r\n * @param {object} state the store data\r\n */\n incrementAccepted(state) {\n state.accepted++;\n },\n /**\r\n * Increment the number of calendar-objects denied\r\n *\r\n * @param {object} state the store data\r\n */\n incrementDenied(state) {\n state.denied++;\n },\n /**\r\n * Set the total number of calendar-objects\r\n *\r\n * @param {object} state the store data\r\n * @param {number} total the total number of calendar-objects to import\r\n */\n setTotal(state, total) {\n state.total = total;\n },\n /**\r\n * Change stage to the indicated one\r\n *\r\n * @param {object} state the store data\r\n * @param {string} stage the name of the stage, see /src/models/consts.js\r\n */\n changeStage(state, stage) {\n state.stage = stage;\n },\n /**\r\n * Reset to the default state\r\n *\r\n * @param {object} state the store data\r\n */\n resetState(state) {\n state.total = 0;\n state.accepted = 0;\n state.denied = 0;\n state.stage = IMPORT_STAGE_DEFAULT;\n }\n};\nconst getters = {};\nconst actions = {};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @author John Molakvoæ \r\n *\r\n * @author Thomas Citharel \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nimport Vuex from 'vuex';\nimport calendarObjectInstance from './calendarObjectInstance.js';\nimport calendarObjects from './calendarObjects.js';\nimport calendars from './calendars.js';\nimport contacts from './contacts.js';\nimport davRestrictions from './davRestrictions.js';\nimport fetchedTimeRanges from './fetchedTimeRanges.js';\nimport importFiles from './importFiles.js';\nimport importState from './importState.js';\nimport principals from './principals.js';\nimport settings from './settings.js';\nimport userRole from './userRole.js';\nVue.use(Vuex);\nexport default new Vuex.Store({\n modules: {\n calendarObjectInstance,\n calendarObjects,\n calendars,\n contacts,\n davRestrictions,\n fetchedTimeRanges,\n importFiles,\n importState,\n principals,\n settings,\n userRole\n }\n // // Throw errors when the state is edited outside of mutations\n // strict: true\n});","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport Vue from 'vue';\nimport { findPrincipalByUrl, getCurrentUserPrincipal } from '../services/caldavService.js';\nimport logger from '../utils/logger.js';\nimport { getDefaultPrincipalObject, mapDavToPrincipal } from '../models/principal.js';\nconst state = {\n principals: [],\n principalsById: {},\n currentUserPrincipal: null\n};\nconst mutations = {\n /**\r\n * Adds a principal to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {object} data.principal The principal to add\r\n */\n addPrincipal(state, _ref) {\n let {\n principal\n } = _ref;\n const object = getDefaultPrincipalObject(principal);\n if (state.principalsById[object.id]) {\n return;\n }\n state.principals.push(object);\n Vue.set(state.principalsById, object.id, object);\n },\n /**\r\n * Adds the current user principal to the state\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data destructuring object\r\n * @param {string} data.principalId principalId of the current-user-principal\r\n */\n setCurrentUserPrincipal(state, _ref2) {\n let {\n principalId\n } = _ref2;\n state.currentUserPrincipal = principalId;\n },\n /**\r\n * Changes the schedule-default-calendar-URL of a principal\r\n *\r\n * @param {object} state The vuex state\r\n * @param {object} data The destructuring object\r\n * @param {object} data.principal The principal to modify\r\n * @param {string} data.scheduleDefaultCalendarUrl The new schedule-default-calendar-URL\r\n */\n changePrincipalScheduleDefaultCalendarUrl(state, _ref3) {\n let {\n principal,\n scheduleDefaultCalendarUrl\n } = _ref3;\n Vue.set(state.principalsById[principal.id], 'scheduleDefaultCalendarUrl', scheduleDefaultCalendarUrl);\n }\n};\nconst getters = {\n /**\r\n * Gets a principal object by its url\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getPrincipalByUrl: state => url => state.principals.find(principal => principal.url === url),\n /**\r\n * Gets a principal object by its id\r\n *\r\n * @param {object} state the store data\r\n * @return {function({String}): {Object}}\r\n */\n getPrincipalById: state => id => state.principalsById[id],\n /**\r\n * Gets the principal object of the current-user-principal\r\n *\r\n * @param {object} state the store data\r\n * @return {{Object}}\r\n */\n getCurrentUserPrincipal: state => state.principalsById[state.currentUserPrincipal],\n /**\r\n * Gets the email-address of the current-user-principal\r\n *\r\n * @param {object} state the store data\r\n * @return {string|undefined}\r\n */\n getCurrentUserPrincipalEmail: state => {\n var _state$principalsById;\n return (_state$principalsById = state.principalsById[state.currentUserPrincipal]) === null || _state$principalsById === void 0 ? void 0 : _state$principalsById.emailAddress;\n }\n};\nconst actions = {\n /**\r\n * Fetches a principal from the DAV server and commits it to the state\r\n *\r\n * @param {object} context The vuex context\r\n * @param {string} url The URL of the principal\r\n * @return {Promise}\r\n */\n async fetchPrincipalByUrl(context, _ref4) {\n let {\n url\n } = _ref4;\n // Don't refetch principals we already have\n if (context.getters.getPrincipalByUrl(url)) {\n return;\n }\n const principal = await findPrincipalByUrl(url);\n if (!principal) {\n // TODO - handle error\n return;\n }\n context.commit('addPrincipal', {\n principal: mapDavToPrincipal(principal)\n });\n },\n /**\r\n * Fetches the current-user-principal\r\n *\r\n * @param {object} context The vuex context\r\n * @return {Promise}\r\n */\n async fetchCurrentUserPrincipal(context) {\n const currentUserPrincipal = getCurrentUserPrincipal();\n if (!currentUserPrincipal) {\n // TODO - handle error\n return;\n }\n const principal = mapDavToPrincipal(currentUserPrincipal);\n context.commit('addPrincipal', {\n principal\n });\n context.commit('setCurrentUserPrincipal', {\n principalId: principal.id\n });\n logger.debug(\"Current user principal is \".concat(principal.url));\n },\n /**\r\n * Change a principal's schedule-default-calendar-URL\r\n *\r\n * @param {object} context The vuex context\r\n * @param {object} data The destructuring object\r\n * @param {object} data.principal The principal to modify\r\n * @param {string} data.scheduleDefaultCalendarUrl The new schedule-default-calendar-URL\r\n * @return {Promise}\r\n */\n async changePrincipalScheduleDefaultCalendarUrl(context, _ref5) {\n let {\n principal,\n scheduleDefaultCalendarUrl\n } = _ref5;\n principal.dav.scheduleDefaultCalendarUrl = scheduleDefaultCalendarUrl;\n await principal.dav.update();\n context.commit('changePrincipalScheduleDefaultCalendarUrl', {\n principal,\n scheduleDefaultCalendarUrl\n });\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","/**\r\n * @copyright Copyright (c) 2020 Georg Ehrke\r\n * @copyright Copyright (c) 2022 Informatyka Boguslawski sp. z o.o. sp.k., http://www.ib.pl/\r\n *\r\n * @author Georg Ehrke \r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { enableBirthdayCalendar } from '../services/caldavService.js';\nimport { mapDavCollectionToCalendar } from '../models/calendar.js';\nimport { detectTimezone } from '../services/timezoneDetectionService.js';\nimport { setConfig as setCalendarJsConfig } from '@nextcloud/calendar-js';\nimport { setConfig } from '../services/settings.js';\nimport { logInfo } from '../utils/logger.js';\nimport getTimezoneManager from '../services/timezoneDataProviderService.js';\nimport * as AttachmentService from '../services/attachmentService.js';\nconst state = {\n // env\n appVersion: null,\n firstRun: null,\n talkEnabled: false,\n disableAppointments: false,\n publicCalendars: null,\n // user-defined calendar settings\n eventLimit: null,\n showTasks: null,\n showWeekends: null,\n showWeekNumbers: null,\n skipPopover: null,\n slotDuration: null,\n defaultReminder: null,\n tasksEnabled: false,\n timezone: 'automatic',\n hideEventExport: false,\n forceEventAlarmType: false,\n canSubscribeLink: true,\n showResources: true,\n // user-defined Nextcloud settings\n momentLocale: 'en',\n attachmentsFolder: '/Calendar',\n attachmentsFolderCreated: false\n};\nconst mutations = {\n /**\r\n * Updates the user's setting for event limit\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleEventLimitEnabled(state) {\n state.eventLimit = !state.eventLimit;\n },\n /**\r\n * Updates the user's setting for visibility of event popover\r\n *\r\n * @param {object} state The Vuex state\r\n */\n togglePopoverEnabled(state) {\n state.skipPopover = !state.skipPopover;\n },\n /**\r\n * Updates the user's setting for visibility of weekends\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleTasksEnabled(state) {\n state.showTasks = !state.showTasks;\n },\n /**\r\n * Updates the user's setting for visibility of weekends\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleWeekendsEnabled(state) {\n state.showWeekends = !state.showWeekends;\n },\n /**\r\n * Updates the user's setting for visibility of week numbers\r\n *\r\n * @param {object} state The Vuex state\r\n */\n toggleWeekNumberEnabled(state) {\n state.showWeekNumbers = !state.showWeekNumbers;\n },\n /**\r\n * Updates the user's preferred slotDuration\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.slotDuration The new slot duration\r\n */\n setSlotDuration(state, _ref) {\n let {\n slotDuration\n } = _ref;\n state.slotDuration = slotDuration;\n },\n /**\r\n * Updates the user's preferred defaultReminder\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.defaultReminder The new default reminder length\r\n */\n setDefaultReminder(state, _ref2) {\n let {\n defaultReminder\n } = _ref2;\n state.defaultReminder = defaultReminder;\n },\n /**\r\n * Updates the user's timezone\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.timezoneId The new timezone\r\n */\n setTimezone(state, _ref3) {\n let {\n timezoneId\n } = _ref3;\n state.timezone = timezoneId;\n },\n /**\r\n * Updates the user's attachments folder\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.attachmentsFolder The new attachments folder\r\n */\n setAttachmentsFolder(state, _ref4) {\n let {\n attachmentsFolder\n } = _ref4;\n state.attachmentsFolder = attachmentsFolder;\n state.attachmentsFolderCreated = false;\n },\n /**\r\n * Update wheter the user's attachments folder has been created\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {boolean} data.attachmentsFolderCreated True if the folder has been created\r\n */\n setAttachmentsFolderCreated(state, _ref5) {\n let {\n attachmentsFolderCreated\n } = _ref5;\n state.attachmentsFolderCreated = attachmentsFolderCreated;\n },\n /**\r\n * Initialize settings\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.appVersion The version of the Nextcloud app\r\n * @param {boolean} data.eventLimit Whether or not to limit number of visible events in grid view\r\n * @param {boolean} data.firstRun Whether or not this is the first run\r\n * @param {boolean} data.showWeekNumbers Whether or not to show week numbers\r\n * @param {boolean} data.showTasks Whether or not to display tasks with a due-date\r\n * @param {boolean} data.showWeekends Whether or not to display weekends\r\n * @param {boolean} data.skipPopover Whether or not to skip the simple event popover\r\n * @param {string} data.slotDuration The duration of one slot in the agendaView\r\n * @param {string} data.defaultReminder The default reminder to set on newly created events\r\n * @param {boolean} data.talkEnabled Whether or not the talk app is enabled\r\n * @param {boolean} data.tasksEnabled Whether ot not the tasks app is enabled\r\n * @param {string} data.timezone The timezone to view the calendar in. Either an Olsen timezone or \"automatic\"\r\n * @param {boolean} data.hideEventExport\r\n * @param {string} data.forceEventAlarmType\r\n * @param {boolean} data.disableAppointments Allow to disable the appointments feature\r\n * @param {boolean} data.canSubscribeLink\r\n * @param {string} data.attachmentsFolder Default user's attachments folder\r\n * @param {boolean} data.showResources Show or hide the resources tab\r\n * @param {string} data.publicCalendars\r\n */\n loadSettingsFromServer(state, _ref6) {\n let {\n appVersion,\n eventLimit,\n firstRun,\n showWeekNumbers,\n showTasks,\n showWeekends,\n skipPopover,\n slotDuration,\n defaultReminder,\n talkEnabled,\n tasksEnabled,\n timezone,\n hideEventExport,\n forceEventAlarmType,\n disableAppointments,\n canSubscribeLink,\n attachmentsFolder,\n showResources,\n publicCalendars\n } = _ref6;\n logInfo(\"\\nInitial settings:\\n\\t- AppVersion: \".concat(appVersion, \"\\n\\t- EventLimit: \").concat(eventLimit, \"\\n\\t- FirstRun: \").concat(firstRun, \"\\n\\t- ShowWeekNumbers: \").concat(showWeekNumbers, \"\\n\\t- ShowTasks: \").concat(showTasks, \"\\n\\t- ShowWeekends: \").concat(showWeekends, \"\\n\\t- SkipPopover: \").concat(skipPopover, \"\\n\\t- SlotDuration: \").concat(slotDuration, \"\\n\\t- DefaultReminder: \").concat(defaultReminder, \"\\n\\t- TalkEnabled: \").concat(talkEnabled, \"\\n\\t- TasksEnabled: \").concat(tasksEnabled, \"\\n\\t- Timezone: \").concat(timezone, \"\\n\\t- HideEventExport: \").concat(hideEventExport, \"\\n\\t- ForceEventAlarmType: \").concat(forceEventAlarmType, \"\\n\\t- disableAppointments: \").concat(disableAppointments, \"\\n\\t- CanSubscribeLink: \").concat(canSubscribeLink, \"\\n\\t- attachmentsFolder: \").concat(attachmentsFolder, \"\\n\\t- ShowResources: \").concat(showResources, \"\\n\\t- PublicCalendars: \").concat(publicCalendars, \"\\n\"));\n state.appVersion = appVersion;\n state.eventLimit = eventLimit;\n state.firstRun = firstRun;\n state.showWeekNumbers = showWeekNumbers;\n state.showTasks = showTasks;\n state.showWeekends = showWeekends;\n state.skipPopover = skipPopover;\n state.slotDuration = slotDuration;\n state.defaultReminder = defaultReminder;\n state.talkEnabled = talkEnabled;\n state.tasksEnabled = tasksEnabled;\n state.timezone = timezone;\n state.hideEventExport = hideEventExport;\n state.forceEventAlarmType = forceEventAlarmType;\n state.disableAppointments = disableAppointments;\n state.canSubscribeLink = canSubscribeLink;\n state.attachmentsFolder = attachmentsFolder;\n state.showResources = showResources;\n state.publicCalendars = publicCalendars;\n },\n /**\r\n * Sets the name of the moment.js locale to be used\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} data The destructuring object\r\n * @param {string} data.locale The moment.js locale to be used\r\n */\n setMomentLocale(state, _ref7) {\n let {\n locale\n } = _ref7;\n logInfo(\"Updated moment locale: \".concat(locale));\n state.momentLocale = locale;\n }\n};\nconst getters = {\n isTalkEnabled: state => state.talkEnabled,\n /**\r\n * Gets the resolved timezone.\r\n * If the timezone is set to automatic, it returns the user's current timezone\r\n * Otherwise, it returns the Olsen timezone stored\r\n *\r\n * @param {object} state The Vuex state\r\n * @return {string}\r\n */\n getResolvedTimezone: state => state.timezone === 'automatic' ? detectTimezone() : state.timezone,\n /**\r\n * Gets the resolved timezone object.\r\n * Falls back to UTC if timezone is invalid.\r\n *\r\n * @param {object} state The Vuex state\r\n * @param {object} getters The vuex getters\r\n * @return {object} The calendar-js timezone object\r\n */\n getResolvedTimezoneObject: (state, getters) => {\n const timezone = getters.getResolvedTimezone;\n let timezoneObject = getTimezoneManager().getTimezoneForId(timezone);\n if (!timezoneObject) {\n timezoneObject = getTimezoneManager().getTimezoneForId('UTC');\n }\n return timezoneObject;\n }\n};\nconst actions = {\n /**\r\n * Updates the user's setting for visibility of birthday calendar\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.getters The Vuex Getters\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {Function} vuex.dispatch The Vuex dispatch Function\r\n * @return {Promise}\r\n */\n async toggleBirthdayCalendarEnabled(_ref8) {\n let {\n getters,\n commit,\n dispatch\n } = _ref8;\n if (getters.hasBirthdayCalendar) {\n const calendar = getters.getBirthdayCalendar;\n await dispatch('deleteCalendar', {\n calendar\n });\n } else {\n const davCalendar = await enableBirthdayCalendar();\n const calendar = mapDavCollectionToCalendar(davCalendar);\n commit('addCalendar', {\n calendar\n });\n }\n },\n /**\r\n * Updates the user's setting for event limit\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @return {Promise}\r\n */\n async toggleEventLimitEnabled(_ref9) {\n let {\n state,\n commit\n } = _ref9;\n const newState = !state.eventLimit;\n const value = newState ? 'yes' : 'no';\n await setConfig('eventLimit', value);\n commit('toggleEventLimitEnabled');\n },\n /**\r\n * Updates the user's setting for visibility of event popover\r\n *\r\n * @param {object} context The Vuex context\r\n * @param {object} context.state The store state\r\n * @param {object} context.commit The store mutations\r\n * @return {Promise}\r\n */\n async togglePopoverEnabled(_ref10) {\n let {\n state,\n commit\n } = _ref10;\n const newState = !state.skipPopover;\n const value = newState ? 'yes' : 'no';\n await setConfig('skipPopover', value);\n commit('togglePopoverEnabled');\n },\n /**\r\n * Updates the user's setting for visibility of weekends\r\n *\r\n * @param {object} context The Vuex context\r\n * @param {object} context.state The store state\r\n * @param {object} context.commit The store mutations\r\n * @return {Promise}\r\n */\n async toggleWeekendsEnabled(_ref11) {\n let {\n state,\n commit\n } = _ref11;\n const newState = !state.showWeekends;\n const value = newState ? 'yes' : 'no';\n await setConfig('showWeekends', value);\n commit('toggleWeekendsEnabled');\n },\n /**\r\n * Updates the user's setting for visibility of tasks\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @return {Promise}\r\n */\n async toggleTasksEnabled(_ref12) {\n let {\n state,\n commit\n } = _ref12;\n const newState = !state.showTasks;\n const value = newState ? 'yes' : 'no';\n await setConfig('showTasks', value);\n commit('toggleTasksEnabled');\n commit('clearFetchedTimeRanges');\n commit('incrementModificationCount');\n },\n /**\r\n * Updates the user's setting for visibility of week numbers\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @return {Promise}\r\n */\n async toggleWeekNumberEnabled(_ref13) {\n let {\n state,\n commit\n } = _ref13;\n const newState = !state.showWeekNumbers;\n const value = newState ? 'yes' : 'no';\n await setConfig('showWeekNr', value);\n commit('toggleWeekNumberEnabled');\n },\n /**\r\n * Updates the view to be used as initial view when opening\r\n * the calendar app again\r\n *\r\n * @param {object} context The Vuex destructuring object\r\n * @param {object} data The destructuring object\r\n * @param {string} data.initialView New view to be used as initial view\r\n * @return {Promise}\r\n */\n async setInitialView(context, _ref14) {\n let {\n initialView\n } = _ref14;\n await setConfig('view', initialView);\n },\n /**\r\n * Updates the user's preferred slotDuration\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.slotDuration The new slot duration\r\n */\n async setSlotDuration(_ref15, _ref16) {\n let {\n state,\n commit\n } = _ref15;\n let {\n slotDuration\n } = _ref16;\n if (state.slotDuration === slotDuration) {\n return;\n }\n await setConfig('slotDuration', slotDuration);\n commit('setSlotDuration', {\n slotDuration\n });\n },\n /**\r\n * Updates the user's preferred defaultReminder\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.defaultReminder The new default reminder\r\n */\n async setDefaultReminder(_ref17, _ref18) {\n let {\n state,\n commit\n } = _ref17;\n let {\n defaultReminder\n } = _ref18;\n if (state.defaultReminder === defaultReminder) {\n return;\n }\n await setConfig('defaultReminder', defaultReminder);\n commit('setDefaultReminder', {\n defaultReminder\n });\n },\n /**\r\n * Updates the user's timezone\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.timezoneId The new timezone\r\n * @return {Promise}\r\n */\n async setTimezone(_ref19, _ref20) {\n let {\n state,\n commit\n } = _ref19;\n let {\n timezoneId\n } = _ref20;\n if (state.timezone === timezoneId) {\n return;\n }\n await setConfig('timezone', timezoneId);\n commit('setTimezone', {\n timezoneId\n });\n },\n /**\r\n * Updates the user's attachments folder\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {object} data The destructuring object\r\n * @param {string} data.attachmentsFolder The new attachments folder\r\n * @return {Promise}\r\n */\n async setAttachmentsFolder(_ref21, _ref22) {\n let {\n state,\n commit\n } = _ref21;\n let {\n attachmentsFolder\n } = _ref22;\n if (state.attachmentsFolder === attachmentsFolder) {\n return;\n }\n await setConfig('attachmentsFolder', attachmentsFolder);\n commit('setAttachmentsFolder', {\n attachmentsFolder\n });\n },\n /**\r\n * Create the user's attachment folder if it doesn't exist and return its path\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n * @param {Function} vuex.commit The Vuex commit Function\r\n * @param {Function} vuex.dispatch The Vuex commit function\r\n * @param {object} vuex.getters The Vuex getters object\r\n * @return {Promise} The path of the user's attachments folder\r\n */\n async createAttachmentsFolder(_ref23) {\n let {\n state,\n commit,\n dispatch,\n getters\n } = _ref23;\n if (state.attachmentsFolderCreated) {\n return state.attachmentsFolder;\n }\n const userId = getters.getCurrentUserPrincipal.dav.userId;\n const path = await AttachmentService.createFolder(state.attachmentsFolder, userId);\n if (path !== state.attachmentsFolder) {\n await dispatch('setAttachmentsFolder', {\n attachmentsFolder: path\n });\n }\n commit('setAttachmentsFolderCreated', {\n attachmentsFolderCreated: true\n });\n return path;\n },\n /**\r\n * Initializes the calendar-js configuration\r\n *\r\n * @param {object} vuex The Vuex destructuring object\r\n * @param {object} vuex.state The Vuex state\r\n */\n initializeCalendarJsConfig(_ref24) {\n let {\n state\n } = _ref24;\n setCalendarJsConfig('PRODID', \"-//IDN nextcloud.com//Calendar app \".concat(state.appVersion, \"//EN\"));\n setCalendarJsConfig('property-list-significant-change', ['SUMMARY', 'LOCATION', 'DESCRIPTION', 'CLIENT']);\n }\n};\nexport default {\n state,\n mutations,\n getters,\n actions\n};","import roleService from \"../services/roleService\";\nconst state = {\n roles: [] // Store the roles here\n};\nconst mutations = {\n setUserRole(state, roles) {\n state.roles = roles;\n }\n};\nconst actions = {\n async fetchUserRoles(_ref) {\n let {\n commit\n } = _ref;\n try {\n // Pass commit to the service\n await roleService.fetchAndCommitRoles(commit);\n } catch (error) {}\n }\n};\nconst getters = {\n isAdmin: state => state.roles.includes(\"admin\"),\n canAccessPreviousEvent: state => state.roles.includes(\"Ligne\") == false && state.roles.includes(\"ligne\") == false\n};\nexport default {\n namespaced: true,\n state,\n mutations,\n actions,\n getters\n};","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n * @author Richard Steinmetz \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\nimport { AttendeeProperty, Property } from '@nextcloud/calendar-js';\nimport { translate as t } from '@nextcloud/l10n';\n\n/**\r\n * Get the factor for a given unit\r\n *\r\n * @param {string} unit The name of the unit to get the factor of\r\n * @return {number}\r\n */\nexport function getFactorForAlarmUnit(unit) {\n switch (unit) {\n case 'seconds':\n return 1;\n case 'minutes':\n return 60;\n case 'hours':\n return 60 * 60;\n case 'days':\n return 24 * 60 * 60;\n case 'weeks':\n return 7 * 24 * 60 * 60;\n default:\n return 1;\n }\n}\n\n/**\r\n * Gets the amount of days / weeks, unit from total seconds\r\n *\r\n * @param {number} totalSeconds Total amount of seconds\r\n * @return {{amount: number, unit: string}}\r\n */\nexport function getAmountAndUnitForTimedEvents(totalSeconds) {\n // Before or after the event is handled somewhere else,\n // so make sure totalSeconds is positive\n totalSeconds = Math.abs(totalSeconds);\n\n // Handle the special case of 0, so we don't show 0 weeks\n if (totalSeconds === 0) {\n return {\n amount: 0,\n unit: 'minutes'\n };\n }\n if (totalSeconds % (7 * 24 * 60 * 60) === 0) {\n return {\n amount: totalSeconds / (7 * 24 * 60 * 60),\n unit: 'weeks'\n };\n }\n if (totalSeconds % (24 * 60 * 60) === 0) {\n return {\n amount: totalSeconds / (24 * 60 * 60),\n unit: 'days'\n };\n }\n if (totalSeconds % (60 * 60) === 0) {\n return {\n amount: totalSeconds / (60 * 60),\n unit: 'hours'\n };\n }\n if (totalSeconds % 60 === 0) {\n return {\n amount: totalSeconds / 60,\n unit: 'minutes'\n };\n }\n return {\n amount: totalSeconds,\n unit: 'seconds'\n };\n}\n\n/**\r\n * Get the total amount of seconds based on amount and unit for timed events\r\n *\r\n * @param {number} amount Amount of unit\r\n * @param {string} unit Minutes/Hours/Days/Weeks\r\n * @param {boolean=} isBefore Whether the reminder is before or after the event\r\n * @return {number}\r\n */\nexport function getTotalSecondsFromAmountAndUnitForTimedEvents(amount, unit) {\n let isBefore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n return amount * getFactorForAlarmUnit(unit) * (isBefore ? -1 : 1);\n}\n\n/**\r\n * Gets the amount of days / weeks, unit, hours and minutes from total seconds\r\n *\r\n * @param {number} totalSeconds Total amount of seconds\r\n * @return {{amount: *, unit: *, hours: *, minutes: *}}\r\n */\nexport function getAmountHoursMinutesAndUnitForAllDayEvents(totalSeconds) {\n const dayFactor = getFactorForAlarmUnit('days');\n const hourFactor = getFactorForAlarmUnit('hours');\n const minuteFactor = getFactorForAlarmUnit('minutes');\n const isNegative = totalSeconds < 0;\n totalSeconds = Math.abs(totalSeconds);\n let dayPart = Math.floor(totalSeconds / dayFactor);\n const hourPart = totalSeconds % dayFactor;\n if (hourPart !== 0) {\n if (isNegative) {\n dayPart++;\n }\n }\n let amount = 0;\n let unit = null;\n if (dayPart === 0) {\n unit = 'days';\n } else if (dayPart % 7 === 0) {\n amount = dayPart / 7;\n unit = 'weeks';\n } else {\n amount = dayPart;\n unit = 'days';\n }\n let hours = Math.floor(hourPart / hourFactor);\n const minutePart = hourPart % hourFactor;\n let minutes = Math.floor(minutePart / minuteFactor);\n if (isNegative) {\n hours = 24 - hours;\n if (minutes !== 0) {\n hours--;\n minutes = 60 - minutes;\n }\n }\n return {\n amount,\n unit,\n hours,\n minutes\n };\n}\n\n/**\r\n * Get the total amount of seconds for all-day events\r\n *\r\n * @param {number} amount amount of unit\r\n * @param {number} hours Time of reminder\r\n * @param {number} minutes Time of reminder\r\n * @param {string} unit days/weeks\r\n * @return {number}\r\n */\nexport function getTotalSecondsFromAmountHourMinutesAndUnitForAllDayEvents(amount, hours, minutes, unit) {\n if (unit === 'weeks') {\n amount *= 7;\n unit = 'days';\n }\n\n // 0 is on the same day of the all-day event => positive\n // 1 ... n before the event is negative\n const isNegative = amount > 0;\n if (isNegative) {\n // If it's negative, we need to subtract one day\n amount--;\n // Convert days to seconds\n amount *= getFactorForAlarmUnit(unit);\n let invertedHours = 24 - hours;\n let invertedMinutes = 0;\n if (minutes !== 0) {\n invertedHours--;\n invertedMinutes = 60 - minutes;\n }\n amount += invertedHours * getFactorForAlarmUnit('hours');\n amount += invertedMinutes * getFactorForAlarmUnit('minutes');\n amount *= -1;\n } else {\n // Convert days to seconds\n amount *= getFactorForAlarmUnit('days');\n amount += hours * getFactorForAlarmUnit('hours');\n amount += minutes * getFactorForAlarmUnit('minutes');\n }\n return amount;\n}\n\n/**\r\n * Propagate data from an event component to all EMAIL alarm components.\r\n * An alarm component must contain a description, summary and all attendees to be notified.\r\n * We don't have a separate UI for maintaining attendees of an alarm, so we just copy them from the event.\r\n *\r\n * https://www.rfc-editor.org/rfc/rfc5545#section-3.6.6\r\n *\r\n * @param {AbstractRecurringComponent} eventComponent\r\n */\nexport function updateAlarms(eventComponent) {\n for (const alarmComponent of eventComponent.getAlarmIterator()) {\n if (alarmComponent.action !== 'EMAIL' && alarmComponent.action !== 'DISPLAY') {\n continue;\n }\n alarmComponent.deleteAllProperties('SUMMARY');\n const summaryProperty = eventComponent.getFirstProperty('SUMMARY');\n if (summaryProperty) {\n alarmComponent.addProperty(summaryProperty.clone());\n } else {\n const defaultSummary = t('calendar', 'Untitled event');\n alarmComponent.addProperty(new Property('SUMMARY', defaultSummary));\n }\n if (!alarmComponent.hasProperty('DESCRIPTION')) {\n const defaultDescription = t('calendar', 'This is an event reminder.');\n alarmComponent.addProperty(new Property('DESCRIPTION', defaultDescription));\n }\n alarmComponent.deleteAllProperties('ATTENDEE');\n for (const attendee of eventComponent.getAttendeeIterator()) {\n if (['RESOURCE', 'ROOM'].includes(attendee.userType)) {\n continue;\n }\n\n // Only copy the email address (value) of the attendee\n alarmComponent.addProperty(new AttendeeProperty('ATTENDEE', attendee.value));\n }\n }\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\n\n/**\r\n * Gets the ByDay and BySetPosition\r\n *\r\n * @param {Date} jsDate The date to get the weekday of\r\n * @return {object}\r\n */\nexport function getBySetPositionAndBySetFromDate(jsDate) {\n const byDay = getWeekDayFromDate(jsDate);\n let bySetPosition = 1;\n let dayOfMonth = jsDate.getDate();\n for (; dayOfMonth > 7; dayOfMonth -= 7) {\n bySetPosition++;\n }\n return {\n byDay,\n bySetPosition\n };\n}\n\n/**\r\n * Gets the string-representation of the weekday of a given date\r\n *\r\n * @param {Date} jsDate The date to get the weekday of\r\n * @return {string}\r\n */\nexport function getWeekDayFromDate(jsDate) {\n switch (jsDate.getDay()) {\n case 0:\n return 'SU';\n case 1:\n return 'MO';\n case 2:\n return 'TU';\n case 3:\n return 'WE';\n case 4:\n return 'TH';\n case 5:\n return 'FR';\n case 6:\n return 'SA';\n default:\n throw TypeError('Invalid date-object given');\n }\n}","/**\r\n * @copyright Copyright (c) 2019 Georg Ehrke\r\n *\r\n * @author Georg Ehrke \r\n *\r\n * @license AGPL-3.0-or-later\r\n *\r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as\r\n * published by the Free Software Foundation, either version 3 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see .\r\n *\r\n */\nimport { linkTo } from '@nextcloud/router';\n\n/**\r\n * Get URL to modify config-key\r\n *\r\n * @param {string} key URL of config-key to modify\r\n * @return {string}\r\n */\nexport function getLinkToConfig(key) {\n return [linkTo('calendar', 'index.php'), 'v1/config', key].join('/');\n}"],"names":[],"sourceRoot":""} diff --git a/calendar/js/calendar-src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254.js b/calendar/js/calendar-src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254.js index 6243fe7..805b8ea 100644 --- a/calendar/js/calendar-src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254.js +++ b/calendar/js/calendar-src_views_Calendar_vue-data_image_svg_xml_3csvg_20xmlns_27http_www_w3_org_2000_svg_27_20heigh-4a4254.js @@ -14454,6 +14454,16 @@ var render = function render() { "add-single-value": _vm.addArticle, "remove-single-value": _vm.removeArticle } + }), _vm._v(" "), _c("PropertyText", { + attrs: { + "is-read-only": _vm.isReadOnly, + "prop-model": _vm.rfcProps.comment, + value: _vm.comment, + "linkify-links": false + }, + on: { + "update:value": _vm.updateComment + } }), _vm._v(" "), _c("InviteesList", { staticClass: "event-popover__invitees", attrs: { @@ -17205,7 +17215,7 @@ __webpack_require__.r(__webpack_exports__); * Returns an object with properties from RFCs including * their displayName, a description, options, etc. * - * @return {{geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}} + * @return {{comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}} */ rfcProps() { return (0,_models_rfcProps_js__WEBPACK_IMPORTED_MODULE_0__.getRFCProperties)(); @@ -17467,6 +17477,17 @@ __webpack_require__.r(__webpack_exports__); location }); }, + /** + * Updates the comments of this event + * + * @param {string} comment New comments + */ + updateComment(comment) { + this.$store.commit('changeComment', { + calendarObjectInstance: this.calendarObjectInstance, + comment + }); + }, /** * Updates the client of the event * diff --git a/calendar/src/mixins/EditorMixin.js b/calendar/src/mixins/EditorMixin.js index 30fc80a..5acf131 100644 --- a/calendar/src/mixins/EditorMixin.js +++ b/calendar/src/mixins/EditorMixin.js @@ -118,6 +118,15 @@ export default { return this.calendarObjectInstance?.embalmer ?? null }, + /** + * Returns the comment or null if the event is still loading + * + * @return {string|null} + */ + comment() { + return this.calendarObjectInstance?.comment ?? null + }, + /** * Returns the isPrivate property @@ -351,7 +360,7 @@ export default { * Returns an object with properties from RFCs including * their displayName, a description, options, etc. * - * @return {{geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}} + * @return {{comment, geo, color, timeTransparency, description, resources, location, client, categories, accessClass, priority, status, locations, articles, clients,embalmer,embalmers}} */ rfcProps() { return getRFCProperties() @@ -623,6 +632,18 @@ export default { }) }, + /** + * Updates the comments of this event + * + * @param {string} comment New comments + */ + updateComment(comment) { + this.$store.commit('changeComment', { + calendarObjectInstance: this.calendarObjectInstance, + comment, + }) + }, + /** * Updates the client of the event * diff --git a/calendar/src/models/event.js b/calendar/src/models/event.js index 0b8af91..65cdd95 100644 --- a/calendar/src/models/event.js +++ b/calendar/src/models/event.js @@ -62,6 +62,8 @@ const getDefaultEventObject = (props = {}) => Object.assign({}, { embalmer : null, //Private isPrivate: false, + //comment of the event + comment : null, // description of the event description: null, // Access class of the event (PUBLIC, PRIVATE, CONFIDENTIAL) @@ -111,6 +113,7 @@ const mapEventComponentToEventObject = (eventComponent) => { location: eventComponent.location, client : "CLIENT", embalmer : "TEST", + comment : "", description: eventComponent.description, accessClass: eventComponent.accessClass, status: eventComponent.status, @@ -208,6 +211,10 @@ const mapEventComponentToEventObject = (eventComponent) => { eventObject.embalmer = eventComponent.getFirstPropertyFirstValue('EMBALMER'); } + if(eventComponent.hasProperty('COMMENT')){ + eventObject.comment = eventComponent.getFirstPropertyFirstValue('COMMENT'); + } + return eventObject; } @@ -223,6 +230,7 @@ const copyCalendarObjectInstanceIntoEventComponent = (eventObject, eventComponen eventComponent.client = eventObject.client eventComponent.embalmer = eventObject.embalmer eventComponent.isPrivate = eventObject.isPrivate + eventComponent.comment = eventObject.comment eventComponent.description = eventObject.description eventComponent.accessClass = eventObject.accessClass eventComponent.status = eventObject.status diff --git a/calendar/src/models/rfcProps.js b/calendar/src/models/rfcProps.js index 8a87f08..1253cf0 100644 --- a/calendar/src/models/rfcProps.js +++ b/calendar/src/models/rfcProps.js @@ -169,6 +169,15 @@ const getRFCProperties = () => { tagPlaceholder: t('calendar', 'Choisir les soins'), options: [], }, + comment: { + readableName: t('calendar', 'Comment'), + icon: 'TextBoxOutline', + info: t('calendar', 'Commentaires.'), + placeholder: t('calendar', 'Commentaires'), + tagPlaceholder: t('calendar', 'Commentaires'), + options: [], + defaultNumberOfRows: 4 + }, } } diff --git a/calendar/src/store/calendarObjectInstance.js b/calendar/src/store/calendarObjectInstance.js index 367cc30..3ff3fd7 100644 --- a/calendar/src/store/calendarObjectInstance.js +++ b/calendar/src/store/calendarObjectInstance.js @@ -336,6 +336,19 @@ const mutations = { calendarObjectInstance.location = location }, + /** + * Change the comment of an event + * + * @param {object} state The Vuex state + * @param {object} data The destructuring object + * @param {object} data.calendarObjectInstance The calendarObjectInstance object + * @param {string} data.comment New comment to set + */ + changeComment(state, { calendarObjectInstance, comment }) { + calendarObjectInstance.eventComponent.comment = comment + calendarObjectInstance.comment = comment + }, + /** * Change the client of an event * @@ -1703,8 +1716,9 @@ const actions = { updateAlarms(eventComponent) updateTalkParticipants(eventComponent) let additionalFieldWasUpdated = + eventComponent.client != null || eventComponent.isPrivate != null || - eventComponent.client != null; + eventComponent.comment != null ; if (eventComponent.isDirty() || additionalFieldWasUpdated) { const isForkedItem = eventComponent.primaryItem !== null let original = null diff --git a/calendar/src/store/calendarObjects.js b/calendar/src/store/calendarObjects.js index 5b40c13..4073771 100644 --- a/calendar/src/store/calendarObjects.js +++ b/calendar/src/store/calendarObjects.js @@ -230,7 +230,33 @@ const actions = { if(eventComponent != null){ if(eventComponent.client != null){ let newClientKeyValue = "CLIENT:"+eventComponent.client; - icsValue = icsValue.replace(/CLIENT:\d+/, newClientKeyValue); + let regexEmptyClient = /CLIENT:(?!\d)(?=\s*[\r\n])/g; + if (regexEmptyClient.test(icsValue)) { + icsValue = icsValue.replace(regexEmptyClient, newClientKeyValue); + } + let regex = /CLIENT:\d+/; + if(regex.test(icsValue)){ + icsValue = icsValue.replace(regex, newClientKeyValue); + } + else{ + const customKeyValue = { + "CLIENT": eventComponent.client + }; + icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue); + } + } + if(eventComponent.comment != null){ + let newCommentKeyValue = "COMMENT:"+eventComponent.comment; + let regex = /^COMMENT:.*$/m; + if(regex.test(icsValue)){ + icsValue = icsValue.replace(regex, newCommentKeyValue); + } + else{ + const customKeyValue = { + "COMMENT": eventComponent.comment + }; + icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue); + } } if(eventComponent.isPrivate != null){ @@ -266,7 +292,9 @@ const actions = { const customKeyValue = { "CLIENT": eventComponent.client, "EMBALMER": eventComponent.embalmer , - "ISPRIVATE": eventComponent.isPrivate ? "1" : "0",}; + "ISPRIVATE": eventComponent.isPrivate ? "1" : "0", + "COMMENT": eventComponent.comment + }; icsValue = setCustomKeyValuesArrayToIcsAndReturnIcs(icsValue,customKeyValue); } calendarObject.dav = await calendar.dav.createVObject(icsValue); diff --git a/calendar/src/views/EditSidebar.vue b/calendar/src/views/EditSidebar.vue index 4f1c7f9..eee5242 100644 --- a/calendar/src/views/EditSidebar.vue +++ b/calendar/src/views/EditSidebar.vue @@ -135,6 +135,13 @@ @add-single-value="addArticle" @remove-single-value="removeArticle" /> + + + + l->t('New'), $locationId, $this->l->t('Mention'), - $this->l->t('Comment'), + $devisComment, $last, $devisNumber, $devisFullNumber @@ -2933,6 +2933,7 @@ class Bdd { } $sql = "SELECT devis.id, + devis.date, devis.id_thanato, devis.id_defunt as defunt_id, devis.num, @@ -3031,6 +3032,23 @@ class Bdd { } } + public function updateDevisComment($devisId,$requestedComment,$currentComment = null){ + $commentIsUpdated = $currentComment != $requestedComment; + if($commentIsUpdated){ + $sql= "UPDATE ".$this->tableprefix."devis as devis + SET devis.comment = ? + WHERE devis.id = ?"; + $this->execSQLNoData($sql,[$requestedComment,$devisId]); + } + } + + public function updateDevisDate($devisId,$requestedDate){ + $sql= "UPDATE ".$this->tableprefix."devis as devis + SET devis.date = ? + WHERE devis.id = ?"; + $this->execSQLNoData($sql,[$requestedDate,$devisId]); + } + public function deleteDevisProduit($devisProductId){ $sql = "DELETE FROM ".$this->tableprefix."produit_devis WHERE id = ?;"; $this->execSQLNoData($sql, array($devisProductId)); diff --git a/gestion/lib/Listener/CalendarObjectUpdatedListener.php b/gestion/lib/Listener/CalendarObjectUpdatedListener.php index a00efa4..6685a15 100644 --- a/gestion/lib/Listener/CalendarObjectUpdatedListener.php +++ b/gestion/lib/Listener/CalendarObjectUpdatedListener.php @@ -30,6 +30,7 @@ use OCA\DAV\Events\CalendarObjectUpdatedEvent; use OCA\Gestion\Service\GestionService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; +use OCP\IRequest; use Psr\Log\LoggerInterface; class CalendarObjectUpdatedListener implements IEventListener { @@ -40,19 +41,25 @@ class CalendarObjectUpdatedListener implements IEventListener { /** @var GestionService */ private $gestionService; + /** @var IRequest */ + private $request; + public function __construct( + IRequest $request, LoggerInterface $logger,GestionService $gestionService) { $this->logger = $logger; $this->gestionService = $gestionService; + $this->request = $request; } public function handle(Event $event): void { if (!($event instanceof CalendarObjectUpdatedEvent)) { return; } + $cookie = $this->request->getHeader("Cookie"); $calendarData = $event->getObjectData(); $vCalendarString = $calendarData["calendardata"]; - $this->gestionService->HandleUpdatedCalendarObject($vCalendarString); + $this->gestionService->HandleUpdatedCalendarObject($vCalendarString,$cookie); } } diff --git a/gestion/lib/Service/GestionService.php b/gestion/lib/Service/GestionService.php index 1f2f88d..6ba01f8 100644 --- a/gestion/lib/Service/GestionService.php +++ b/gestion/lib/Service/GestionService.php @@ -197,6 +197,13 @@ class GestionService { $isPrivateValue = VCalendarHelpers::GetValueFromKeyInVCalendarString(VCalendarPropertyConstant::PROPERTY_IS_LEAVE, $vCalendarString); return $isPrivateValue === "1" ? true : false; } + private function GetDevisCommentFromVCalendarString(string $vCalendarString){ + $commentValue = VCalendarHelpers::GetValueFromKeyInVCalendarString("COMMENT", $vCalendarString); + if($commentValue == ""){ + $commentValue = "Commentaire"; + } + return $commentValue; + } public function HandleCreatedCalendarObject(string $vCalendarString ,$cookie){ try{ @@ -227,8 +234,9 @@ class GestionService { } $defuntId = $this->gestionBdd->insertDefuntByNameAndReturnId($calendarSummary); $calendarStartDate = $this->GetCalendarDateFromVCalendarString($vCalendarString); - $devisDate = $calendarStartDate->format('Y-m-d'); - $devisId = $this->gestionBdd->insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$calendarUuid,$devisDate,$userName); + $devisComment = $this->GetDevisCommentFromVCalendarString($vCalendarString); + $devisDate = $calendarStartDate->format(format: 'Y-m-d'); + $devisId = $this->gestionBdd->insertDevisFromVCalendarAndReturnId($thanatoId,$clientId,$locationId,$defuntId,$devisComment,$calendarUuid,$devisDate,$userName); $articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString); if(!empty($articlesValue)){ $articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue); @@ -355,7 +363,10 @@ class GestionService { $requestedClientId = $this->GetClientIdFromVCalendarString($vCalendarString); $requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString); $requestedArticleReferences = $this->GetArticlesNameFromVCalendarString($vCalendarString); + $requestedDevisComment = $this->GetDevisCommentFromVCalendarString($vCalendarString); $requestedArticleIds = $this->gestionBdd->getArticleIdsByArticleReferences($requestedArticleReferences); + $requestedDevisDate = $this->GetCalendarDateFromVCalendarString($vCalendarString); + $requestedDevisDate = $requestedDevisDate->format('Y-m-d'); $articleDevis = $this->gestionBdd->getProduitDevisByDevisId($devis['id']); $articleDevisIds = []; foreach($articleDevis as $currentArticleDevis){ @@ -368,6 +379,8 @@ class GestionService { $devis['defunt_nom'] == $requestedDefuntName && $devis['client_id'] == $requestedClientId && $devis['lieu_id'] == $requestLocationId && + $devis['comment'] == $requestedDevisComment && + $devis['date'] == $requestedDevisDate && $requestedArticleIds == $articleDevisIds; } @@ -382,6 +395,13 @@ class GestionService { $requestLocationId = $this->GetLocationIdFromVCalendarString($vCalendarString); $this->gestionBdd->updateDevisLieu($devis['id'],$requestLocationId,$devis['lieu_id']); + $requestedDevisComment = $this->GetDevisCommentFromVCalendarString($vCalendarString); + $this->gestionBdd->updateDevisComment($devis['id'],$requestedDevisComment,$devis['comment']); + + $requestedDevisDate = $this->GetCalendarDateFromVCalendarString($vCalendarString); + $requestedDevisDate = $requestedDevisDate->format('Y-m-d'); + $this->gestionBdd->updateDevisDate($devis['id'],$requestedDevisDate); + $articlesValue = $this->GetArticlesNameFromVCalendarString($vCalendarString); if(!empty($articlesValue)){ $articleIds = $this->gestionBdd->getArticleIdsByArticleReferences($articlesValue); @@ -394,17 +414,18 @@ class GestionService { $calendarUuid = $this->GetCalendarUuidFromVCalendarString($vCalendarString); $devis = $this->gestionBdd->getDevisByCalendarUuid($calendarUuid); if($devis != null){ - $this->gestionBdd->updateDevisMention($devis['id'],DevisMentionConstant::NEW); $isDevisAlreadyUpdated = $this->CheckIfDevisIsAlreadyUpdated($devis,$vCalendarString); if($isDevisAlreadyUpdated){ return true; } + $devisIsAlreadyFactured = $devis['mentions'] == DevisMentionConstant::FACTURED || $devis['mentions'] == DevisMentionConstant::FACTURED_FORMATTED; $this->UpdateDevisDataByVCalendarString($devis,$vCalendarString); $userName = $this->GetThanatoNameFromVCalendarString($vCalendarString); - $devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devis['id'],$userName); - $this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid); - $this->devisPdfService->generateDevisPdfByDevisId($devis['id'],$this->userConnectedUuid); - + if($devisIsAlreadyFactured == false){ + $devisTalkMessage = $this->gestionBdd->getDevisTalkRoomMessage($devis['id'],$userName); + $this->talkService->sendDevisTalkNotifications($devisTalkMessage,$userName,$this->userConnectedUuid); + $this->devisPdfService->generateDevisPdfByDevisId($devis['id'],$this->userConnectedUuid); + } if (VCalendarHelpers::hasAttachment($vCalendarString)) { $thanato = $this->gestionBdd->getThanatoByThanatoId($devis['id_thanato']);