diff --git a/__manifest__.py b/__manifest__.py index c5cbd7a..e46a494 100755 --- a/__manifest__.py +++ b/__manifest__.py @@ -28,9 +28,13 @@ 'views/dss_texts.xml', 'views/dss_systems.xml', 'views/dss_screendesign.xml', - 'views/dss_trigger_actions.xml', 'views/dss_eventdays.xml', + 'views/dss_trigger_actions.xml', 'views/dss_triggertypes.xml', + 'views/dss_trigger_groups.xml', + 'views/dss_maintains.xml', + 'views/dss_provisionstypen.xml', + 'views/dss_provision.xml', 'views/mainsystem_view.xml', 'views/menu.xml', 'views/company_view.xml', diff --git a/getimg.sh b/getimg.sh index 3b6cb2e..076f3e7 100755 --- a/getimg.sh +++ b/getimg.sh @@ -1 +1 @@ -curl https://upload.diebesorger.com/f.php?h=1DWnJR2Q&d=1 \ No newline at end of file +https://apps.odoo.com/apps/modules/16.0/master_search \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py index 6e17e15..23c3689 100755 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,4 +1,5 @@ from . import dss_settings +from . import dss_trigger from . import dss_contract from . import dss_projects from . import dss_geraetetypen @@ -7,8 +8,12 @@ from . import dss_software from . import dss_systems from . import dss_eventdays from . import dss_advertisefields -from . import dss_ads +from . import dss_trigger +from . import dss_triggervalues from . import dss +from . import dss_maintains +from . import dss_provisionstypen +from . import dss_provision from . import company diff --git a/models/company.py b/models/company.py index 8e52005..4b77965 100755 --- a/models/company.py +++ b/models/company.py @@ -24,6 +24,9 @@ class ResCompany(models.Model): dssprojekte = fields.Many2many('dss.main', readonly=1 ) dsspartner_name = fields.Char('Kundenname', default=False) dsspartner_vorname = fields.Char('KundenVorname', default=False) + dssinternpartner = fields.Boolean('Mitarbeiter', default=False) + dssinternpartner_grafik = fields.Boolean('Grafiker', default=False) + dssinternpartner_technik = fields.Boolean('Techniker', default=False) # dss_uuid = fields.Char('uuid') dss_uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') diff --git a/models/dss.py b/models/dss.py index f78bfc3..c2c306c 100755 --- a/models/dss.py +++ b/models/dss.py @@ -9,6 +9,7 @@ import logging import base64 import subprocess import tempfile + import easywebdav import os import os.path @@ -365,24 +366,124 @@ class dssscreendesign(models.Model): outlist = {'uuid' : 2222} return outlist -class dsstriggertypes(models.Model): - _name = "dss.triggertypes" - _description = "DigitalSignage Trigger Typen" - _inherit = ['mail.thread','mail.activity.mixin'] - _rec_name = "triggername" - uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') - date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) - date_lastedit = fields.Date('Änderungsdatum') - user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) - user_lastedit = fields.Char('Änderungsuser') +class dsscontractads(models.Model): - triggername = fields.Char('Triggername',track_visibility='onchange',tracking=True) - triggertyp = fields.Selection([('FIELD_A','Feldänderung allgemein'),('FIELD_S','Feldänderung spezifisch'),('FIELD_K','Feldwert berechnet'),('MANUAL','Menuell ausgelösst')],'Triggertyp',track_visibility='onchange',tracking=True) - trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',track_visibility='onchange',tracking=True) - trigger_field = fields.Many2one('ir.model.fields', help='Feldname in der Tabelle',track_visibility='onchange',tracking=True) - trigger_operator = fields.Selection([('NGLEICH','Feld gleich dem Wert'),('GGLEICH','Feld größer/gleich dem Wert'),('KGLEICH','Feld kleiner/gleich dem Wert'),('UGLEICH','Feld ungleich dem Wert'),('ENTHAELT','Feld enthällt dem Wert')],'Feldwertoperator',track_visibility='onchange',tracking=True) - trigger_value = fields.Char('Feldwert für Trigger',track_visibility='onchange',tracking=True) - trigger_Aktionen = fields.Many2many('dss.triggeractions',string='Aktionen bei auslösen des Triggers',track_visibility='onchange',tracking=True) + def _default_work_state(self): + ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).id + _logger.debug(ds) + return ds + + def _default_work_state_color(self): + ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).color + _logger.info(ds) + return ds + + def _default_todo_state(self): + ds = self.env['dss.todostate'].search([('statusnr', '=', '0')], limit=1).id + if not ds: ds = 1 + _logger.debug(ds) + # ds = + return ds + + @api.model + def create(self, vals): + result = super().create(vals) + resstr = result.uuid + _logger.info(resstr) + for n_record in result: + resstr = n_record.uuid + _logger.info(resstr) + n_record.date_create = date.today() + n_record.user_create = self.env.user.name + allads = n_record.contract.ads + _logger.info(allads) + if allads != False: + for ad in allads: + ad.ad_is_lastpos = False + n_record.ad_is_lastpos = True + contract = n_record.contract + contract.ads_last_ad = n_record + return result + + # @api.depends('need_media') + # def _getmedialist(self): + # mlist = [] + # mlist = self.env['dss.mediarelations'].search([('ad','=',self.id)]) + # if mlist != False: + # _logger.info('AD Need_Medias A_'+str(self)+' - Computed Medias '+str(mlist)) + # self.need_media = mlist.ids + # else: + # self.need_media = False + + _name = "dss.ads" + _description = "DigitalSignage Werbekampagnen Phasen" + _inherit = ['mail.thread', 'mail.activity.mixin'] + # _inherit = ['mail.activity.mixin'] + # 'mail.thread','mail.activity.mixin' + _rec_name = "adname" + # _inherit = ['mail.thread', 'mail.activity.mixin'] + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, + string='UUID') + aduuid = fields.Char(related='uuid') + + date_create = fields.Date('Erstellungsdatum', default=lambda self: self._default_create_date()) + date_lastedit = fields.Date('Änderungsdatum') + user_create = fields.Char('Erstellungsuser', default=lambda self: self._default_create_user()) + user_lastedit = fields.Char('Änderungsuser') + # uuid = fields.Char('UUID', required=True, translate=True) + adname = fields.Char('Kampagnenname', required=True, tracking=True) + adtype = fields.Selection( + [('MAIN', 'Ersteinrichtung'), ('KCHN', 'Änderung durch Kunde'), ('LCHN', 'Änderung durch Logumedia'), + ('SONS', 'Sonstige Änderung')], tracking=True) + adpos = fields.Integer('Reihenfolge', default=lambda self: self._default_adpos(), + tracking=True) + ad_is_lastpos = fields.Boolean('Letzte Aktion', tracking=True) + + start_date = fields.Date('gew. Ausstrahl.Begin', tracking=True) + end_date = fields.Date('gew. Ausstrahl.Ende', tracking=True) + + contract = fields.Many2one('dss.contracts', store=True, tracking=True) + contract_id = fields.Char(related='contract.contract_id') + contract_name = fields.Char(related='contract.contract_name') + contract_need_media = fields.Many2many(related='contract.need_media', tracking=True) + + project = fields.Many2one('dss.projects', string='Project', store=True, tracking=True) + project_id = fields.Integer(related='project.projectid', string='Project ID') + + parent_ad = fields.Many2one('dss.ads', string='UrsprungsWerbung', store=True) + parent_ad_uuid = fields.Char(related='parent_ad.uuid') + description = fields.Text('Beschreibung') + amount = fields.Float('Extrakosten', tracking=True) + order = fields.Integer('Reihenfolge', tracking=True) + + # need_media = fields.Many2many('dss.mediarelations','ad',string='Medien') + need_media = fields.One2many('dss.mediarelations', 'ad', string='Medien') + + work_state = fields.Many2one('dss.workstate', default=_default_work_state, tracking=True) + work_state_color = fields.Char(related='work_state.color') + work_state_text = fields.Char(related='work_state.statusname') + work_state_info = fields.Char('Zusatzinfo') + + ad_state = fields.Many2one('dss.adstate', tracking=True) + ad_state_color = fields.Char(related='ad_state.color') + ad_state_text = fields.Char(related='ad_state.statusname') + ad_state_func = fields.Selection(related='ad_state.func') + + todo_state = fields.Many2one('dss.todostate', default=_default_todo_state, + tracking=True) + todo_state_color = fields.Char(related='todo_state.color') + todo_state_text = fields.Char(related='todo_state.statusname') + todo_state_info = fields.Char('Zusatzinfo', tracking=True) + todo_state_until = fields.Date('Abarbeiten bis', tracking=True) + + cloud_add_directory = fields.Char('Cloud KundenKampagnen Ordner', tracking=True) + + date_zuarbeit = fields.Date(string='Zuarbeit Datum', help='Zuarbeit gesendet am', tracking=True) + date_korrekturabzug = fields.Date(string='K.Abzug Datum', help='Korrekturabzug gesendet am') + date_korrekturfreigabe = fields.Date(string='K.Freigabe Datum', help='Korrekturfreigabe erhalten am', + tracking=True) + date_korrekturfreigabe_frist = fields.Date(string='K.Freigabe bis Datum', help='Korrekturfreigabe sollte bis .... erfolgen') + freigabe_durch_ablauf = fields.Boolean(string='Zeitablauf',help='Freigabe wurde durch Zeitablauf erreicht ?', tracking=True) @api.model def _default_uuid(self): @@ -394,29 +495,320 @@ class dsstriggertypes(models.Model): def _default_create_user(self): return str(self.env.user.name) -class dsstriggertypes(models.Model): - _name = "dss.triggeractions" - _description = "DigitalSignage Trigger Aktionen" - _inherit = ['mail.thread','mail.activity.mixin'] - _rec_name = "triggeractionname" - uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') - date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) + def _default_adpos(self): + pos = self.env['dss.ads'].search_count([('contract_id', '=', self.contract.id)]) + 1 + return str(pos) + + @api.onchange('ad_state') + def _onchange_ad_state(self): + for record in self: + if record.ad_is_lastpos == True: + contract = record.contract + contract.ads_last_state = record.ad_state + # mtyp = self.env['dss.adstructures'].search([("uuid","=",str(record.mediastructure.uuid))]) + # buildmediarelations(self) + self.date_lastedit = str(date.today()) + + # self.mediastructure = mtyp + + def pyaction_view_ad_details(self): + action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( + 'DigitalSignage.action_dss_ads_view') + # action['display_name'] = self.ad_name + # action['domain'] = '[["projectid","=","4"]]' + # context = action['context'].replace('', str(self.id)) + # context = ast.literal_eval(context) + # context.update({ + # 'create': self.active, + # 'active_test': self.active + # }) + # action['context'] = context + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '', + 'res_id': self.id, + 'display_name': ' ' + self.adname, + 'domain': '' + } + + return action + + def pydoviewallads(self): + action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( + 'DigitalSignage.act_dss_ads_view_full') + action['display_name'] = self.contract_name + # action['domain'] = '[["projectid","=","4"]]' + # context = action['context'].replace('', str(self.id)) + # context = ast.literal_eval(context) + # context.update({ + # 'create': self.active, + # 'active_test': self.active + # }) + # action['context'] = context + # return { + # 'type': 'ir.actions.act_window', + # 'view_type':'form', + # 'view_mode':'form,tree', + # 'res_model':'dss.ads', + # 'target':'current', + # 'context':'', + # 'res_id':kampagne.id, + # 'display_name' : 'Werbekampagne '+kampagne.adname, + # 'domain':'[("contract","=","context[active_id]")]' + # } + # return action + return { + 'type': 'ir.actions.act_window', + 'view_type': 'kanban', + 'view_mode': 'kanban', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '{"group_by":["parent_ad"]}', + # 'res_id':self.parent_ad, + 'display_name': 'Übersicht für ' + self.adname, + 'domain': [("contract", "=", self.contract.id)] + } + + def pydonewad(self): + for n_record in self: + resstr = n_record.uuid + _logger.info(resstr) + allads = n_record.contract.ads + _logger.info(allads) + abort = False + if allads != False: + for ad in allads: + if ad.ad_state.func != 'FIN': + abort = True + if abort == False: + defadstate = self.env['dss.adstate'].search([('func', '=', 'STD')], limit=1).id + if not defadstate: + defadstate = 1 + if self.ad_state.func == 'STD': + parent_id = self.id + else: + parent_id = self.parent_ad.id + newkampagne = self.env['dss.ads'].create({'contract': self.contract.id, 'project': self.project.id, + 'adname': 'AD_' + self.contract.contract_auto_name + ' ' + str( + date.today()), 'parent_ad': parent_id, 'adtype': 'KCHN', + 'ad_state': defadstate}) + _logger.info('C_' + str(self.id) + ' Kampagne erzeugt : ' + str(newkampagne)) + _logger.info('Prüfe Medien : C_' + str(self.id) + 'K_' + str(newkampagne.id)) + + mediaids = [] + for feld in self.contract.werbe_feld_selected: + for media in feld.mediastructure.medias: + if not media: + _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( + newkampagne.id) + ' Kein Medium in MedienStructur von F_' + str(feld.id) + 'M_' + str( + media.id)) + else: + newmedia = self.env['dss.mediarelations'].create( + {'field': feld.id, 'contract': self.contract.id, 'project': self.project.id, + 'field_uuid': feld.uuid, 'ad': newkampagne.id, 'relname': media.medianame, + 'mediatype': media.id}) + _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( + newkampagne.id) + ' setze Vertrag für Medium : ' + str(newmedia.contract) + '/' + str( + newmedia.ad)) + mediaids.append(newmedia.id) + newkampagne.write({'need_media': [(6, 0, mediaids)]}) + _logger.info('Click auf Werbekampagne : C_' + str(self.contract.id) + 'A_' + str( + newkampagne.id) + ' setze Media ') + + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '', + 'res_id': newkampagne.id, + 'display_name': 'Änderung zur Werbekampagne ' + newkampagne.parent_ad.adname, + 'domain': '[("id","=","context[newkampagne.id]")]' + } + else: + raise ValidationError( + _("Kann neue Aktualisierung erst anlegen wenn alle vorherigen Schritte beendet wurden !")) + + def setStandardText(self, tid): + text = self.env['dss.texts'].search([('text_id', '=', tid)], limit=1) + if text: + self.write({'description': text.description}) + + +class dsscontractads(models.Model): + + def _default_work_state(self): + ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).id + _logger.debug(ds) + return ds + + def _default_work_state_color(self): + ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).color + _logger.info(ds) + return ds + + def _default_todo_state(self): + ds = self.env['dss.todostate'].search([('statusnr', '=', '0')], limit=1).id + if not ds: ds = 1 + _logger.debug(ds) + # ds = + return ds + + @api.model + def create(self, vals): + result = super().create(vals) + resstr = result.uuid + _logger.info(resstr) + for n_record in result: + resstr = n_record.uuid + _logger.info(resstr) + n_record.date_create = date.today() + n_record.user_create = self.env.user.name + allads = n_record.contract.ads + _logger.info(allads) + if allads != False: + for ad in allads: + ad.ad_is_lastpos = False + n_record.ad_is_lastpos = True + contract = n_record.contract + contract.ads_last_ad = n_record + return result + + # @api.depends('need_media') + # def _getmedialist(self): + # mlist = [] + # mlist = self.env['dss.mediarelations'].search([('ad','=',self.id)]) + # if mlist != False: + # _logger.info('AD Need_Medias A_'+str(self)+' - Computed Medias '+str(mlist)) + # self.need_media = mlist.ids + # else: + # self.need_media = False + + _name = "dss.ads" + _description = "DigitalSignage Werbekampagnen" + _inherit = ['mail.thread', 'mail.activity.mixin','dss.triggermodel'] + # _inherit = ['mail.activity.mixin'] + # 'mail.thread','mail.activity.mixin' + _rec_name = "adname" + # _inherit = ['mail.thread', 'mail.activity.mixin'] + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, + string='UUID') + aduuid = fields.Char(related='uuid') + + date_create = fields.Date('Erstellungsdatum', default=lambda self: self._default_create_date()) date_lastedit = fields.Date('Änderungsdatum') - user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) + user_create = fields.Char('Erstellungsuser', default=lambda self: self._default_create_user()) user_lastedit = fields.Char('Änderungsuser') + # uuid = fields.Char('UUID', required=True, translate=True) + adname = fields.Char('Kampagnenname', required=True, tracking=True) + adtype = fields.Selection( + [('MAIN', 'Ersteinrichtung'), ('KCHN', 'Änderung durch Kunde'), ('LCHN', 'Änderung durch Logumedia'), + ('SONS', 'Sonstige Änderung'),('PREA', 'Vorausplanung')], tracking=True) + adpos = fields.Integer('Reihenfolge', default=lambda self: self._default_adpos(), + tracking=True) + ad_is_lastpos = fields.Boolean('Letzte Aktion', tracking=True) - triggeractionname = fields.Char('Triggeraktionname',track_visibility='onchange',tracking=True) - triggeractiontyp = fields.Selection([('EMAIL','EMail senden'),('ACTIV','Aufgabe erzeugen'),('DSEDIT','Datensatz ändern'),('TUYA','Tuya Aktion auslössen')],'Aktionstyp',track_visibility='onchange',tracking=True) - email_getfrom = fields.Selection([('FIX','Email fest hinterlegt'),('DATA','Email in Feld hinterlegt')],'Emailadresse von',track_visibility='onchange',tracking=True) - email_fix_email_sender = fields.Many2one('res.partner','Absender',help='Email Sender Adresse der Aktion',track_visibility='onchange',tracking=True) - email_fix_email = fields.Many2one('res.partner','Empfänger',help='Email Emüfänger Adresse für Benachrichtigung/Triggeraktion',track_visibility='onchange',tracking=True) - email_data_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist diese Aktion gültig ?',track_visibility='onchange',tracking=True) - email_data_field = fields.Many2one('ir.model.fields', help='Feldname in der Tabelle',track_visibility='onchange',tracking=True) - email_template = fields.Many2one('mail.template','Emailvorlage',track_visibility='onchange',tracking=True) + contract = fields.Many2one('dss.contracts', store=True, tracking=True) + contract_id = fields.Char(related='contract.contract_id') + contract_name = fields.Char(related='contract.contract_name') + contract_need_media = fields.Many2many(related='contract.need_media', tracking=True) - field = fields.Char('Feldname',help='Feldname in o.g. Tebelle.',track_visibility='onchange',tracking=True) - type_s = fields.Char('Feldwertoperator',track_visibility='onchange',tracking=True) - value_s = fields.Char('Feldwert für Trigger',track_visibility='onchange',tracking=True) + project = fields.Many2one('dss.projects', string='Project', store=True, tracking=True) + project_id = fields.Integer(related='project.projectid', string='Project ID') + + parent_ad = fields.Many2one('dss.ads', string='UrsprungsWerbung', store=True) + parent_ad_uuid = fields.Char(related='parent_ad.uuid') + description = fields.Text('Beschreibung') + amount = fields.Float('Extrakosten', tracking=True) + order = fields.Integer('Reihenfolge', tracking=True) + + # need_media = fields.Many2many('dss.mediarelations','ad',string='Medien') + need_media = fields.One2many('dss.mediarelations', 'ad', string='Medien') + + work_state = fields.Many2one('dss.workstate', default=_default_work_state, tracking=True) + work_state_color = fields.Char(related='work_state.color') + work_state_text = fields.Char(related='work_state.statusname') + work_state_info = fields.Char('Zusatzinfo') + + ad_state = fields.Many2one('dss.adstate', tracking=True) + ad_state_color = fields.Char(related='ad_state.color') + ad_state_text = fields.Char(related='ad_state.statusname') + ad_state_func = fields.Selection(related='ad_state.func') + + todo_state = fields.Many2one('dss.todostate', default=_default_todo_state, + tracking=True) + todo_state_color = fields.Char(related='todo_state.color') + todo_state_text = fields.Char(related='todo_state.statusname') + todo_state_info = fields.Char('Zusatzinfo', tracking=True) + todo_state_until = fields.Date('Abarbeiten bis', tracking=True) + + cloud_add_directory = fields.Char('Cloud KundenKampagnen Ordner', tracking=True) + + date_zuarbeit = fields.Date(string='Zuarbeit Datum', help='Zuarbeit gesendet am', + tracking=True) + date_korrekturabzug = fields.Date(string='K.Abzug Datum', help='Korrekturabzug gesendet am', + tracking=True) + date_korrekturfreigabe = fields.Date(string='K.Freigabe Datum', help='Korrekturfreigabe erhalten am', + tracking=True) + date_korrekturfreigabe_ablauf = fields.Date(string='K.Freigabe Ablaufdatum', help='Korrekturfreigabe muss bis xxxx erfolgen.. sonst Autofreigabe', + tracking=True) + date_korrekturfreigabe_ablauf_compute = fields.Char(compute='_date_korrekturfreigabe_ablauf_compute') + date_korrekturfreigabe_ablauf_compute_int = fields.Integer(compute='_date_korrekturfreigabe_ablauf_compute_int') + korrekturfreigabe_ablauf_erfolgt = fields.Boolean(string='K.Freigabe durch Ablauf', help='Korrekturfreigabe erfolgte durch Zeitablauf ?', + tracking=True) + date_start_planed = fields.Date(string='geplantes Startdatum', tracking=True) + date_start_planed_calendar_event=fields.Integer('gepl. Start - Kal.ID',tracking=True) + date_start_real = fields.Date(string='wirkliches Startdatum', tracking=True) + + date_remove_planed = fields.Date(string='geplantes Enddatum', tracking=True) + date_remove_real = fields.Date(string='wirkliches Enddatum', tracking=True) + + @api.depends('date_korrekturfreigabe_ablauf') + def _date_korrekturfreigabe_ablauf_compute(self): + self.date_korrekturfreigabe_ablauf_compute = '' + if not self: + return '' + pass + else: + for record in self: + if not record: + return '' + pass + else: + if not record.date_korrekturfreigabe_ablauf: + return '' + pass + else: + datedif = record.date_korrekturfreigabe_ablauf-date.today() + record.date_korrekturfreigabe_ablauf_compute='Noch '+str(datedif.days)+' Tage bis Autoablauf' + + @api.depends('date_korrekturfreigabe_ablauf') + def _date_korrekturfreigabe_ablauf_compute_int(self): + for record in self: + if record: + if record.date_korrekturfreigabe_ablauf: + datedif = record.date_korrekturfreigabe_ablauf-date.today() + record.date_korrekturfreigabe_ablauf_compute_int = datedif.days + + def _check_date_korrekturfreigabe_ablauf(self): + for record in self: + if record: + if record.date_korrekturfreigabe_ablauf: + datedif = record.date_korrekturfreigabe_ablauf-date.today() + _logger.info('Contract Autokorrektur Running C_' + str(record.contract)+' / '+str(datedif)) + if (datedif.days<=0) & ( not record.date_korrekturfreigabe): + _logger.info('Contract Autokorrektur Running C_' + str(record.contract)+' A_'+str(record)+' Set Values') + record.date_korrekturfreigabe = date.today() + record.korrekturfreigabe_ablauf_erfolgt = True + body = 'Für die Werbekampagne '+str(record.adname)+' im Vertrag '+str(record.contract.contract_auto_name)+' des Projektes '+str(record.project.projektname)+' wurde der Korekturabzug automatisch durch Zeitablauf bestätigt !' + record.message_post(body=body) + self.env['mail.message'].create({'message_type': 'comment','subtype_id': self.env.ref('mail.mt_comment').id, + 'model': 'mail.channel','res_id': self.env.ref('mail.channel_all_employees').id,'body': body,}) @api.model def _default_uuid(self): @@ -428,26 +820,249 @@ class dsstriggertypes(models.Model): def _default_create_user(self): return str(self.env.user.name) -class dsstriggertypes(models.Model): - _name = "dss.triggergroups" - _description = "DigitalSignage Trigger Gruppen" - _inherit = ['mail.thread','mail.activity.mixin'] - _rec_name = "triggergroupname" -# _inherit = ['mail.thread', 'mail.activity.mixin'] - uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') - date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) - date_lastedit = fields.Date('Änderungsdatum') - user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) - user_lastedit = fields.Char('Änderungsuser') + def _default_adpos(self): + pos = self.env['dss.ads'].search_count([('contract_id', '=', self.contract.id)]) + 1 + return str(pos) - triggergroupname = fields.Char('Trigger Gruppenname',track_visibility='onchange',tracking=True) + @api.onchange('ad_state') + def _onchange_ad_state(self): + for record in self: + if record.ad_is_lastpos == True: + contract = record.contract + contract.ads_last_state = record.ad_state + # mtyp = self.env['dss.adstructures'].search([("uuid","=",str(record.mediastructure.uuid))]) + # buildmediarelations(self) + self.date_lastedit = str(date.today()) - @api.model - def _default_uuid(self): - return str(uuid.uuid4()) + # self.mediastructure = mtyp - def _default_create_date(self): - return str(date.today()) + @api.onchange('date_korrekturabzug') + def _date_korrekturabzug_change(self): + for record in self: + autodays=0 + if record.date_korrekturabzug: + autodays=self.env['dss.settings'].search([],limit=1).freigabe_auto_time + record.date_korrekturfreigabe_ablauf = record.date_korrekturabzug + relativedelta(days=autodays) - def _default_create_user(self): - return str(self.env.user.name) + def pyaction_view_ad_details(self): + action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( + 'DigitalSignage.action_dss_ads_view') + # action['display_name'] = self.ad_name + # action['domain'] = '[["projectid","=","4"]]' + # context = action['context'].replace('', str(self.id)) + # context = ast.literal_eval(context) + # context.update({ + # 'create': self.active, + # 'active_test': self.active + # }) + # action['context'] = context + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '', + 'res_id': self.id, + 'display_name': ' ' + self.adname, + 'domain': '' + } + + return action + + def pydoviewallads(self): + action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( + 'DigitalSignage.act_dss_ads_view_full') + action['display_name'] = self.contract_name + # action['domain'] = '[["projectid","=","4"]]' + # context = action['context'].replace('', str(self.id)) + # context = ast.literal_eval(context) + # context.update({ + # 'create': self.active, + # 'active_test': self.active + # }) + # action['context'] = context + # return { + # 'type': 'ir.actions.act_window', + # 'view_type':'form', + # 'view_mode':'form,tree', + # 'res_model':'dss.ads', + # 'target':'current', + # 'context':'', + # 'res_id':kampagne.id, + # 'display_name' : 'Werbekampagne '+kampagne.adname, + # 'domain':'[("contract","=","context[active_id]")]' + # } + # return action + return { + 'type': 'ir.actions.act_window', + 'view_type': 'kanban', + 'view_mode': 'kanban', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '{"group_by":["parent_ad"]}', + # 'res_id':self.parent_ad, + 'display_name': 'Übersicht für ' + self.adname, + 'domain': [("contract", "=", self.contract.id)] + } + + def pydonewpread(self): + defadstate = self.env['dss.adstate'].search([('func', '=', 'STD')], limit=1).id + if not defadstate: + defadstate = 1 + if self.ad_state.func == 'STD': + parent_id = self.id + else: + parent_id = self.parent_ad.id + newkampagne = self.env['dss.ads'].create({'contract': self.contract.id, 'project': self.project.id, + 'adname': 'PRE_' + self.contract.contract_auto_name + ' ' + str( + date.today()), 'parent_ad': parent_id, 'adtype': 'PREA', + 'ad_state': defadstate}) + _logger.info('C_' + str(self.id) + ' Kampagne erzeugt : ' + str(newkampagne)) + _logger.info('Erzeugte PreWerbekampagne - Prüfe Medien : C_' + str(self.id) + 'K_' + str(newkampagne.id)) + + mediaids = [] + for feld in self.contract.werbe_feld_selected: + for media in feld.mediastructure.medias: + if not media: + _logger.info('Erzeugte PreWerbekampagne - Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( + newkampagne.id) + ' Kein Medium in MedienStructur von F_' + str(feld.id) + 'M_' + str( + media.id)) + else: + newmedia = self.env['dss.mediarelations'].create( + {'field': feld.id, 'contract': self.contract.id, 'project': self.project.id, + 'field_uuid': feld.uuid, 'ad': newkampagne.id, 'relname': media.medianame, + 'mediatype': media.id}) + _logger.info('Erzeugte PreWerbekampagne - Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( + newkampagne.id) + ' setze Vertrag für Medium : ' + str(newmedia.contract) + '/' + str( + newmedia.ad)) + mediaids.append(newmedia.id) + newkampagne.write({'need_media': [(6, 0, mediaids)]}) + _logger.info('Erzeugte PreWerbekampagne : C_' + str(self.contract.id) + 'A_' + str( + newkampagne.id) + ' setze Media ') + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '', + 'res_id': newkampagne.id, + 'display_name': 'Änderung zur Werbekampagne ' + newkampagne.parent_ad.adname, + 'domain': '[("id","=","context[newkampagne.id]")]' + } + + def pydonewad(self): + for n_record in self: + resstr = n_record.uuid + _logger.info(resstr) + allads = n_record.contract.ads + _logger.info(allads) + abort = False + if allads != False: + for ad in allads: + if ad.ad_state.func != 'FIN': + if ad.adtype !='PREA': + abort = True + if abort == False: + defadstate = self.env['dss.adstate'].search([('func', '=', 'STD')], limit=1).id + if not defadstate: + defadstate = 1 + if self.ad_state.func == 'STD': + parent_id = self.id + else: + parent_id = self.parent_ad.id + newkampagne = self.env['dss.ads'].create({'contract': self.contract.id, 'project': self.project.id, + 'adname': 'AD_' + self.contract.contract_auto_name + ' ' + str( + date.today()), 'parent_ad': parent_id, 'adtype': 'KCHN', + 'ad_state': defadstate}) + _logger.info('C_' + str(self.id) + ' Kampagne erzeugt : ' + str(newkampagne)) + _logger.info('Prüfe Medien : C_' + str(self.id) + 'K_' + str(newkampagne.id)) + + mediaids = [] + for feld in self.contract.werbe_feld_selected: + for media in feld.mediastructure.medias: + if not media: + _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( + newkampagne.id) + ' Kein Medium in MedienStructur von F_' + str(feld.id) + 'M_' + str( + media.id)) + else: + newmedia = self.env['dss.mediarelations'].create( + {'field': feld.id, 'contract': self.contract.id, 'project': self.project.id, + 'field_uuid': feld.uuid, 'ad': newkampagne.id, 'relname': media.medianame, + 'mediatype': media.id}) + _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( + newkampagne.id) + ' setze Vertrag für Medium : ' + str(newmedia.contract) + '/' + str( + newmedia.ad)) + mediaids.append(newmedia.id) + newkampagne.write({'need_media': [(6, 0, mediaids)]}) + _logger.info('Click auf Werbekampagne : C_' + str(self.contract.id) + 'A_' + str( + newkampagne.id) + ' setze Media ') + + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '', + 'res_id': newkampagne.id, + 'display_name': 'Änderung zur Werbekampagne ' + newkampagne.parent_ad.adname, + 'domain': '[("id","=","context[newkampagne.id]")]' + } + else: + raise ValidationError( + _("Kann neue Aktualisierung erst anlegen wenn alle vorherigen Schritte beendet wurden !")) + def pydoprecopyad(selfself): + for n_record in self: + resstr = n_record.uuid + _logger.info(resstr) + allads = n_record.contract.ads + _logger.info(allads) + abort = False + if allads != False: + for ad in allads: + if ad.ad_state.func != 'FIN': + if ad.adtype != 'PREA': + abort = True + if abort == False: + + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form,tree', + 'res_model': 'dss.ads', + 'target': 'current', + 'context': '', + 'res_id': newkampagne.id, + 'display_name': 'Änderung zur Werbekampagne ' + newkampagne.parent_ad.adname, + 'domain': '[("id","=","context[newkampagne.id]")]' + } + + else: + raise ValidationError( + _("Kann neue Aktualisierung erst anlegen wenn alle vorherigen Schritte beendet wurden !")) + + def setStandardText(self, tid): + text = self.env['dss.texts'].search([('text_id', '=', tid)], limit=1) + if text: + self.write({'description': text.description}) + + def pyaddstartdate(self): + self.env['calendar.event'].search([('id','=',self.date_start_planed_calendar_event)]).unlink() + event = { + 'start': self.date_start_planed.strftime('%Y-%m-%d %H:%M:%S'), + 'stop': self.date_start_planed.strftime('%Y-%m-%d %H:%M:%S'), + 'duration': 24, + 'allday': True, + 'partner_ids': (4,self.env['dss.settings'].search([],limit=1).contact_runtime_user.partner_id.id), + 'name': 'Geplanter Start '+self.contract.contract_auto_name, + 'description': 'Geplanter Start '+self.contract.contract_auto_name+' im Projekt '+self.project.projektname, + 'user_id': self.env['dss.settings'].search([],limit=1).contact_runtime_user.id + } + _logger.debug('linking new Startevent ' + str(event) + ' ' + str(self.uuid)) + self.date_start_planed_calendar_event=self.env['calendar.event'].create(event).id + return "" + + def pyaddenddate(self): + return 1 diff --git a/models/dss_ads.py b/models/dss_ads.py deleted file mode 100644 index ec4c81e..0000000 --- a/models/dss_ads.py +++ /dev/null @@ -1,576 +0,0 @@ -import ast -import datetime -import json -import re -import uuid -import logging -import base64 -import subprocess -import tempfile -import easywebdav -import os -import os.path - - -from odoo import api, fields, models, _ -from odoo import tools -from odoo.exceptions import ValidationError -from datetime import date -from datetime import datetime -from dateutil.relativedelta import relativedelta -from pyffmpeg import FFmpeg -from tuya_iot import TuyaOpenAPI, TUYA_LOGGER -from tuya_connector import TuyaOpenAPI, TUYA_LOGGER -import sys - -TUYA_LOGGER.setLevel(logging.DEBUG) -_logger = logging.getLogger(__name__) - - -class dsscontractads(models.Model): - - def _default_work_state(self): - ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).id - _logger.debug(ds) - return ds - - def _default_work_state_color(self): - ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).color - _logger.info(ds) - return ds - - def _default_todo_state(self): - ds = self.env['dss.todostate'].search([('statusnr', '=', '0')], limit=1).id - if not ds: ds = 1 - _logger.debug(ds) - # ds = - return ds - - @api.model - def create(self, vals): - result = super().create(vals) - resstr = result.uuid - _logger.info(resstr) - for n_record in result: - resstr = n_record.uuid - _logger.info(resstr) - n_record.date_create = date.today() - n_record.user_create = self.env.user.name - allads = n_record.contract.ads - _logger.info(allads) - if allads != False: - for ad in allads: - ad.ad_is_lastpos = False - n_record.ad_is_lastpos = True - contract = n_record.contract - contract.ads_last_ad = n_record - return result - - # @api.depends('need_media') - # def _getmedialist(self): - # mlist = [] - # mlist = self.env['dss.mediarelations'].search([('ad','=',self.id)]) - # if mlist != False: - # _logger.info('AD Need_Medias A_'+str(self)+' - Computed Medias '+str(mlist)) - # self.need_media = mlist.ids - # else: - # self.need_media = False - - _name = "dss.ads" - _description = "DigitalSignage Werbekampagnen Phasen" - _inherit = ['mail.thread', 'mail.activity.mixin'] - # _inherit = ['mail.activity.mixin'] - # 'mail.thread','mail.activity.mixin' - _rec_name = "adname" - # _inherit = ['mail.thread', 'mail.activity.mixin'] - uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, - string='UUID') - aduuid = fields.Char(related='uuid') - - date_create = fields.Date('Erstellungsdatum', default=lambda self: self._default_create_date()) - date_lastedit = fields.Date('Änderungsdatum') - user_create = fields.Char('Erstellungsuser', default=lambda self: self._default_create_user()) - user_lastedit = fields.Char('Änderungsuser') - # uuid = fields.Char('UUID', required=True, translate=True) - adname = fields.Char('Kampagnenname', required=True, tracking=True) - adtype = fields.Selection( - [('MAIN', 'Ersteinrichtung'), ('KCHN', 'Änderung durch Kunde'), ('LCHN', 'Änderung durch Logumedia'), - ('SONS', 'Sonstige Änderung')], tracking=True) - adpos = fields.Integer('Reihenfolge', default=lambda self: self._default_adpos(), - tracking=True) - ad_is_lastpos = fields.Boolean('Letzte Aktion', tracking=True) - - start_date = fields.Date('gew. Ausstrahl.Begin', tracking=True) - end_date = fields.Date('gew. Ausstrahl.Ende', tracking=True) - - contract = fields.Many2one('dss.contracts', store=True, tracking=True) - contract_id = fields.Char(related='contract.contract_id') - contract_name = fields.Char(related='contract.contract_name') - contract_need_media = fields.Many2many(related='contract.need_media', tracking=True) - - project = fields.Many2one('dss.projects', string='Project', store=True, tracking=True) - project_id = fields.Integer(related='project.projectid', string='Project ID') - - parent_ad = fields.Many2one('dss.ads', string='UrsprungsWerbung', store=True) - parent_ad_uuid = fields.Char(related='parent_ad.uuid') - description = fields.Text('Beschreibung') - amount = fields.Float('Extrakosten', tracking=True) - order = fields.Integer('Reihenfolge', tracking=True) - - # need_media = fields.Many2many('dss.mediarelations','ad',string='Medien') - need_media = fields.One2many('dss.mediarelations', 'ad', string='Medien') - - work_state = fields.Many2one('dss.workstate', default=_default_work_state, tracking=True) - work_state_color = fields.Char(related='work_state.color') - work_state_text = fields.Char(related='work_state.statusname') - work_state_info = fields.Char('Zusatzinfo') - - ad_state = fields.Many2one('dss.adstate', tracking=True) - ad_state_color = fields.Char(related='ad_state.color') - ad_state_text = fields.Char(related='ad_state.statusname') - ad_state_func = fields.Selection(related='ad_state.func') - - todo_state = fields.Many2one('dss.todostate', default=_default_todo_state, - tracking=True) - todo_state_color = fields.Char(related='todo_state.color') - todo_state_text = fields.Char(related='todo_state.statusname') - todo_state_info = fields.Char('Zusatzinfo', tracking=True) - todo_state_until = fields.Date('Abarbeiten bis', tracking=True) - - cloud_add_directory = fields.Char('Cloud KundenKampagnen Ordner', tracking=True) - - date_zuarbeit = fields.Date(string='Zuarbeit Datum', help='Zuarbeit gesendet am', tracking=True) - date_korrekturabzug = fields.Date(string='K.Abzug Datum', help='Korrekturabzug gesendet am') - date_korrekturfreigabe = fields.Date(string='K.Freigabe Datum', help='Korrekturfreigabe erhalten am', - tracking=True) - date_korrekturfreigabe_frist = fields.Date(string='K.Freigabe bis Datum', help='Korrekturfreigabe sollte bis .... erfolgen') - freigabe_durch_ablauf = fields.Boolean(string='Zeitablauf',help='Freigabe wurde durch Zeitablauf erreicht ?', tracking=True) - - @api.model - def _default_uuid(self): - return str(uuid.uuid4()) - - def _default_create_date(self): - return str(date.today()) - - def _default_create_user(self): - return str(self.env.user.name) - - def _default_adpos(self): - pos = self.env['dss.ads'].search_count([('contract_id', '=', self.contract.id)]) + 1 - return str(pos) - - @api.onchange('ad_state') - def _onchange_ad_state(self): - for record in self: - if record.ad_is_lastpos == True: - contract = record.contract - contract.ads_last_state = record.ad_state - # mtyp = self.env['dss.adstructures'].search([("uuid","=",str(record.mediastructure.uuid))]) - # buildmediarelations(self) - self.date_lastedit = str(date.today()) - - # self.mediastructure = mtyp - - def pyaction_view_ad_details(self): - action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( - 'DigitalSignage.action_dss_ads_view') - # action['display_name'] = self.ad_name - # action['domain'] = '[["projectid","=","4"]]' - # context = action['context'].replace('', str(self.id)) - # context = ast.literal_eval(context) - # context.update({ - # 'create': self.active, - # 'active_test': self.active - # }) - # action['context'] = context - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form,tree', - 'res_model': 'dss.ads', - 'target': 'current', - 'context': '', - 'res_id': self.id, - 'display_name': ' ' + self.adname, - 'domain': '' - } - - return action - - def pydoviewallads(self): - action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( - 'DigitalSignage.act_dss_ads_view_full') - action['display_name'] = self.contract_name - # action['domain'] = '[["projectid","=","4"]]' - # context = action['context'].replace('', str(self.id)) - # context = ast.literal_eval(context) - # context.update({ - # 'create': self.active, - # 'active_test': self.active - # }) - # action['context'] = context - # return { - # 'type': 'ir.actions.act_window', - # 'view_type':'form', - # 'view_mode':'form,tree', - # 'res_model':'dss.ads', - # 'target':'current', - # 'context':'', - # 'res_id':kampagne.id, - # 'display_name' : 'Werbekampagne '+kampagne.adname, - # 'domain':'[("contract","=","context[active_id]")]' - # } - # return action - return { - 'type': 'ir.actions.act_window', - 'view_type': 'kanban', - 'view_mode': 'kanban', - 'res_model': 'dss.ads', - 'target': 'current', - 'context': '{"group_by":["parent_ad"]}', - # 'res_id':self.parent_ad, - 'display_name': 'Übersicht für ' + self.adname, - 'domain': [("contract", "=", self.contract.id)] - } - - def pydonewad(self): - for n_record in self: - resstr = n_record.uuid - _logger.info(resstr) - allads = n_record.contract.ads - _logger.info(allads) - abort = False - if allads != False: - for ad in allads: - if ad.ad_state.func != 'FIN': - abort = True - if abort == False: - defadstate = self.env['dss.adstate'].search([('func', '=', 'STD')], limit=1).id - if not defadstate: - defadstate = 1 - if self.ad_state.func == 'STD': - parent_id = self.id - else: - parent_id = self.parent_ad.id - newkampagne = self.env['dss.ads'].create({'contract': self.contract.id, 'project': self.project.id, - 'adname': 'AD_' + self.contract.contract_auto_name + ' ' + str( - date.today()), 'parent_ad': parent_id, 'adtype': 'KCHN', - 'ad_state': defadstate}) - _logger.info('C_' + str(self.id) + ' Kampagne erzeugt : ' + str(newkampagne)) - _logger.info('Prüfe Medien : C_' + str(self.id) + 'K_' + str(newkampagne.id)) - - mediaids = [] - for feld in self.contract.werbe_feld_selected: - for media in feld.mediastructure.medias: - if not media: - _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( - newkampagne.id) + ' Kein Medium in MedienStructur von F_' + str(feld.id) + 'M_' + str( - media.id)) - else: - newmedia = self.env['dss.mediarelations'].create( - {'field': feld.id, 'contract': self.contract.id, 'project': self.project.id, - 'field_uuid': feld.uuid, 'ad': newkampagne.id, 'relname': media.medianame, - 'mediatype': media.id}) - _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( - newkampagne.id) + ' setze Vertrag für Medium : ' + str(newmedia.contract) + '/' + str( - newmedia.ad)) - mediaids.append(newmedia.id) - newkampagne.write({'need_media': [(6, 0, mediaids)]}) - _logger.info('Click auf Werbekampagne : C_' + str(self.contract.id) + 'A_' + str( - newkampagne.id) + ' setze Media ') - - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form,tree', - 'res_model': 'dss.ads', - 'target': 'current', - 'context': '', - 'res_id': newkampagne.id, - 'display_name': 'Änderung zur Werbekampagne ' + newkampagne.parent_ad.adname, - 'domain': '[("id","=","context[newkampagne.id]")]' - } - else: - raise ValidationError( - _("Kann neue Aktualisierung erst anlegen wenn alle vorherigen Schritte beendet wurden !")) - - def setStandardText(self, tid): - text = self.env['dss.texts'].search([('text_id', '=', tid)], limit=1) - if text: - self.write({'description': text.description}) - - -class dsscontractads(models.Model): - - def _default_work_state(self): - ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).id - _logger.debug(ds) - return ds - - def _default_work_state_color(self): - ds = self.env['dss.workstate'].search([('statusname', '=', 'Neu')], limit=1).color - _logger.info(ds) - return ds - - def _default_todo_state(self): - ds = self.env['dss.todostate'].search([('statusnr', '=', '0')], limit=1).id - if not ds: ds = 1 - _logger.debug(ds) - # ds = - return ds - - @api.model - def create(self, vals): - result = super().create(vals) - resstr = result.uuid - _logger.info(resstr) - for n_record in result: - resstr = n_record.uuid - _logger.info(resstr) - n_record.date_create = date.today() - n_record.user_create = self.env.user.name - allads = n_record.contract.ads - _logger.info(allads) - if allads != False: - for ad in allads: - ad.ad_is_lastpos = False - n_record.ad_is_lastpos = True - contract = n_record.contract - contract.ads_last_ad = n_record - return result - - # @api.depends('need_media') - # def _getmedialist(self): - # mlist = [] - # mlist = self.env['dss.mediarelations'].search([('ad','=',self.id)]) - # if mlist != False: - # _logger.info('AD Need_Medias A_'+str(self)+' - Computed Medias '+str(mlist)) - # self.need_media = mlist.ids - # else: - # self.need_media = False - - _name = "dss.ads" - _description = "DigitalSignage Werbekampagnen Phasen" - _inherit = ['mail.thread', 'mail.activity.mixin'] - # _inherit = ['mail.activity.mixin'] - # 'mail.thread','mail.activity.mixin' - _rec_name = "adname" - # _inherit = ['mail.thread', 'mail.activity.mixin'] - uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, - string='UUID') - aduuid = fields.Char(related='uuid') - - date_create = fields.Date('Erstellungsdatum', default=lambda self: self._default_create_date()) - date_lastedit = fields.Date('Änderungsdatum') - user_create = fields.Char('Erstellungsuser', default=lambda self: self._default_create_user()) - user_lastedit = fields.Char('Änderungsuser') - # uuid = fields.Char('UUID', required=True, translate=True) - adname = fields.Char('Kampagnenname', required=True, tracking=True) - adtype = fields.Selection( - [('MAIN', 'Ersteinrichtung'), ('KCHN', 'Änderung durch Kunde'), ('LCHN', 'Änderung durch Logumedia'), - ('SONS', 'Sonstige Änderung')], tracking=True) - adpos = fields.Integer('Reihenfolge', default=lambda self: self._default_adpos(), - tracking=True) - ad_is_lastpos = fields.Boolean('Letzte Aktion', tracking=True) - - start_date = fields.Date('gew. Ausstrahl.Begin', tracking=True) - end_date = fields.Date('gew. Ausstrahl.Ende', tracking=True) - - contract = fields.Many2one('dss.contracts', store=True, tracking=True) - contract_id = fields.Char(related='contract.contract_id') - contract_name = fields.Char(related='contract.contract_name') - contract_need_media = fields.Many2many(related='contract.need_media', tracking=True) - - project = fields.Many2one('dss.projects', string='Project', store=True, tracking=True) - project_id = fields.Integer(related='project.projectid', string='Project ID') - - parent_ad = fields.Many2one('dss.ads', string='UrsprungsWerbung', store=True) - parent_ad_uuid = fields.Char(related='parent_ad.uuid') - description = fields.Text('Beschreibung') - amount = fields.Float('Extrakosten', tracking=True) - order = fields.Integer('Reihenfolge', tracking=True) - - # need_media = fields.Many2many('dss.mediarelations','ad',string='Medien') - need_media = fields.One2many('dss.mediarelations', 'ad', string='Medien') - - work_state = fields.Many2one('dss.workstate', default=_default_work_state, tracking=True) - work_state_color = fields.Char(related='work_state.color') - work_state_text = fields.Char(related='work_state.statusname') - work_state_info = fields.Char('Zusatzinfo') - - ad_state = fields.Many2one('dss.adstate', tracking=True) - ad_state_color = fields.Char(related='ad_state.color') - ad_state_text = fields.Char(related='ad_state.statusname') - ad_state_func = fields.Selection(related='ad_state.func') - - todo_state = fields.Many2one('dss.todostate', default=_default_todo_state, - tracking=True) - todo_state_color = fields.Char(related='todo_state.color') - todo_state_text = fields.Char(related='todo_state.statusname') - todo_state_info = fields.Char('Zusatzinfo', tracking=True) - todo_state_until = fields.Date('Abarbeiten bis', tracking=True) - - cloud_add_directory = fields.Char('Cloud KundenKampagnen Ordner', tracking=True) - - date_zuarbeit = fields.Date(string='Zuarbeit Datum', help='Zuarbeit gesendet am', - tracking=True) - date_korrekturabzug = fields.Date(string='K.Abzug Datum', help='Korrekturabzug gesendet am', - track_visibility='onchange', tracking=True) - date_korrekturfreigabe = fields.Date(string='K.Freigabe Datum', help='Korrekturfreigabe erhalten am', - track_visibility='onchange', tracking=True) - - @api.model - def _default_uuid(self): - return str(uuid.uuid4()) - - def _default_create_date(self): - return str(date.today()) - - def _default_create_user(self): - return str(self.env.user.name) - - def _default_adpos(self): - pos = self.env['dss.ads'].search_count([('contract_id', '=', self.contract.id)]) + 1 - return str(pos) - - @api.onchange('ad_state') - def _onchange_ad_state(self): - for record in self: - if record.ad_is_lastpos == True: - contract = record.contract - contract.ads_last_state = record.ad_state - # mtyp = self.env['dss.adstructures'].search([("uuid","=",str(record.mediastructure.uuid))]) - # buildmediarelations(self) - self.date_lastedit = str(date.today()) - - # self.mediastructure = mtyp - - def pyaction_view_ad_details(self): - action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( - 'DigitalSignage.action_dss_ads_view') - # action['display_name'] = self.ad_name - # action['domain'] = '[["projectid","=","4"]]' - # context = action['context'].replace('', str(self.id)) - # context = ast.literal_eval(context) - # context.update({ - # 'create': self.active, - # 'active_test': self.active - # }) - # action['context'] = context - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form,tree', - 'res_model': 'dss.ads', - 'target': 'current', - 'context': '', - 'res_id': self.id, - 'display_name': ' ' + self.adname, - 'domain': '' - } - - return action - - def pydoviewallads(self): - action = self.env['ir.actions.act_window'].with_context({'default_adid': self.id})._for_xml_id( - 'DigitalSignage.act_dss_ads_view_full') - action['display_name'] = self.contract_name - # action['domain'] = '[["projectid","=","4"]]' - # context = action['context'].replace('', str(self.id)) - # context = ast.literal_eval(context) - # context.update({ - # 'create': self.active, - # 'active_test': self.active - # }) - # action['context'] = context - # return { - # 'type': 'ir.actions.act_window', - # 'view_type':'form', - # 'view_mode':'form,tree', - # 'res_model':'dss.ads', - # 'target':'current', - # 'context':'', - # 'res_id':kampagne.id, - # 'display_name' : 'Werbekampagne '+kampagne.adname, - # 'domain':'[("contract","=","context[active_id]")]' - # } - # return action - return { - 'type': 'ir.actions.act_window', - 'view_type': 'kanban', - 'view_mode': 'kanban', - 'res_model': 'dss.ads', - 'target': 'current', - 'context': '{"group_by":["parent_ad"]}', - # 'res_id':self.parent_ad, - 'display_name': 'Übersicht für ' + self.adname, - 'domain': [("contract", "=", self.contract.id)] - } - - def pydonewad(self): - for n_record in self: - resstr = n_record.uuid - _logger.info(resstr) - allads = n_record.contract.ads - _logger.info(allads) - abort = False - if allads != False: - for ad in allads: - if ad.ad_state.func != 'FIN': - abort = True - if abort == False: - defadstate = self.env['dss.adstate'].search([('func', '=', 'STD')], limit=1).id - if not defadstate: - defadstate = 1 - if self.ad_state.func == 'STD': - parent_id = self.id - else: - parent_id = self.parent_ad.id - newkampagne = self.env['dss.ads'].create({'contract': self.contract.id, 'project': self.project.id, - 'adname': 'AD_' + self.contract.contract_auto_name + ' ' + str( - date.today()), 'parent_ad': parent_id, 'adtype': 'KCHN', - 'ad_state': defadstate}) - _logger.info('C_' + str(self.id) + ' Kampagne erzeugt : ' + str(newkampagne)) - _logger.info('Prüfe Medien : C_' + str(self.id) + 'K_' + str(newkampagne.id)) - - mediaids = [] - for feld in self.contract.werbe_feld_selected: - for media in feld.mediastructure.medias: - if not media: - _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( - newkampagne.id) + ' Kein Medium in MedienStructur von F_' + str(feld.id) + 'M_' + str( - media.id)) - else: - newmedia = self.env['dss.mediarelations'].create( - {'field': feld.id, 'contract': self.contract.id, 'project': self.project.id, - 'field_uuid': feld.uuid, 'ad': newkampagne.id, 'relname': media.medianame, - 'mediatype': media.id}) - _logger.info('Prüfe Medien : C_' + str(self.contract.id) + 'K_' + str( - newkampagne.id) + ' setze Vertrag für Medium : ' + str(newmedia.contract) + '/' + str( - newmedia.ad)) - mediaids.append(newmedia.id) - newkampagne.write({'need_media': [(6, 0, mediaids)]}) - _logger.info('Click auf Werbekampagne : C_' + str(self.contract.id) + 'A_' + str( - newkampagne.id) + ' setze Media ') - - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form,tree', - 'res_model': 'dss.ads', - 'target': 'current', - 'context': '', - 'res_id': newkampagne.id, - 'display_name': 'Änderung zur Werbekampagne ' + newkampagne.parent_ad.adname, - 'domain': '[("id","=","context[newkampagne.id]")]' - } - else: - raise ValidationError( - _("Kann neue Aktualisierung erst anlegen wenn alle vorherigen Schritte beendet wurden !")) - - def setStandardText(self, tid): - text = self.env['dss.texts'].search([('text_id', '=', tid)], limit=1) - if text: - self.write({'description': text.description}) - diff --git a/models/dss_advertisefields.py b/models/dss_advertisefields.py old mode 100644 new mode 100755 diff --git a/models/dss_contract.py b/models/dss_contract.py old mode 100644 new mode 100755 index 4fe7b94..7915a8d --- a/models/dss_contract.py +++ b/models/dss_contract.py @@ -64,7 +64,7 @@ class dsscontracts(models.Model): _name = "dss.contracts" _description = "DigitalSignage Vertraege" _rec_name = "contract_auto_name" - _inherit = ['mail.thread','mail.activity.mixin'] + _inherit = ['mail.thread','mail.activity.mixin','dss.triggermodel'] uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') cruuid = fields.Char(related='uuid') contract_id = fields.Char("Kundennummer",store=True,tracking=True) @@ -74,6 +74,18 @@ class dsscontracts(models.Model): contract_state_order = fields.Integer(related='contract_state.order',store=True) contract_auto_id = fields.Char("Kundennummer",tracking=True,help="Wird berechnet aus Projektnummer + Kunden ID") contract_auto_name = fields.Char('Vertragskennug',tracking=True,help="Wird berechnet aus Kundennummer + Vertragskennung") + contract_payment_done = fields.Boolean('Zahlungeingang erfolgt',tracking=True) + contract_payment_done_date = fields.Date('Zahlungeingang Datum',tracking=True) + + remark = fields.Html('Bemerkung',tracking=True) + + contract_writer = fields.Many2one('res.partner', tracking=True) + vertragssumme = fields.Float('Vertragssumme :', tracking=True) + provisionstyp = fields.Many2one('dss.provisionstypen', tracking=True) + provisionsteilcalc = fields.Float('Berechnete Provision :',computed='_compute_prov') + provisions = fields.Many2many('dss.provision',tracking=True) + provisionspayedpercent = fields.Float('Ausgezahlte Provision % :',computed='_compute_provisionspayedpercent') + grafiker = fields.Many2one('res.partner', placeholder="wenn vom Projekt abweichend", domain="['&',('dssinternpartner','=',True),('dssinternpartner_grafik','=',True)]", tracking=True, string="abw. Grafiker",help="Grafiker nur wenn abweichend vom Projektgrafiker") contract_remark = fields.Html('Vertragshinweise',tracking=True) @@ -81,6 +93,8 @@ class dsscontracts(models.Model): project_id = fields.Integer(related='project.projectid', string='Project ID') projectIid = fields.Integer('Project IID',tracking=True) project_ad_structure = fields.Many2one(related='project.grundsystem_default_adstructure', string='Aufbau') + project_grundsystem_typ = fields.Char(related='project.grundsystem_typ', tracking=True) + project_grafiker = fields.Many2one(related="project.project_grafiker",tracking=True) client = fields.Many2one('res.partner',string="Kunde (wenn angelegt)",domain="['&',('dsspartner','=',True),('dsspartner_werbung','=',True)]",tracking=True,help="Nur zu Benutzen wenn Kunden als Kontakt angelegt wurde") client_id = fields.Char(string="KundenID (2Stellen)",help="Nur der 2 stellige letzte Teil der Kundennummer",tracking=True) @@ -133,6 +147,8 @@ class dsscontracts(models.Model): contract_date = fields.Date('Vertragsdatum',tracking=True) start_date = fields.Date('Start/Auslief.datum',tracking=True) + contract_cancel_mon = fields.Integer('Kündigungsfrist Monaten',tracking=True) + contract_cancel_date = fields.Date('Kündigungsfrist Errechnet', tracking=True) contract_auto_extend = fields.Boolean('autom. V.Verlängerung',tracking=True) contract_auto_extend_time = fields.Char('Verl. Monate',tracking=True) @@ -159,13 +175,12 @@ class dsscontracts(models.Model): ads_last_work_state = fields.Many2one(related='ads_last_ad.work_state', string="Arbeitschritt letzt Kamp",help="Arbeitsstatus des letzten Werbekampagnen Eintrags",store=True,readonly=False,group_expand='_expand_ads_last_work_state') ads_last_work_state_color = fields.Char(related='ads_last_ad.work_state_color') ads_last_work_state_text = fields.Char(related='ads_last_ad.work_state_text',store=True,readonly=False) - ads_last_work_state_info = fields.Char(related='ads_last_ad.work_state_info') + ads_last_work_state_info = fields.Char(related='ads_last_ad.work_state_info',store=True,readonly=False) ads_last_todo_state = fields.Many2one(related='ads_last_ad.todo_state',string="Aufgabe letzt Kamp", help="Aufgabenstatus des letzten Werbekampagnen Eintrags",store=True,readonly=False,group_expand='_expand_ads_last_todo_state') ads_last_todo_state_until = fields.Date(related='ads_last_ad.todo_state_until') ads_last_todo_state_color = fields.Char(related='ads_last_ad.todo_state_color') ads_last_todo_state_text = fields.Char(related='ads_last_ad.todo_state_text',store=True,readonly=False) - vnnox_zugang_erstellt = fields.Boolean('Vnnox Zugang ?',tracking=True) vnnox_zugang_username = fields.Char('Vnnox Username',tracking=True) vnnox_zugang_password = fields.Char('Vnnox Passwort',tracking=True) @@ -174,7 +189,7 @@ class dsscontracts(models.Model): xibo_zugang_erstellt = fields.Boolean('Xibo Zugang ?',tracking=True) xibo_zugang_username = fields.Char('Xibo Username',tracking=True) xibo_zugang_password = fields.Char('Xibo Passwort',tracking=True) - vnnox_zugang_gesendet = fields.Boolean('Xibo Zugang gesendet?',tracking=True) + xibo_zugang_gesendet = fields.Boolean('Xibo Zugang gesendet?',tracking=True) lmw_zugang_erstellt = fields.Boolean('LMW Zugang ?',tracking=True) lmw_zugang_username = fields.Char('LMW Username',tracking=True) @@ -204,6 +219,34 @@ class dsscontracts(models.Model): cloudlink = fields.Char('Cloud Verzeichnis',help='Verzeichnis für den Kunde innerhalb des Projekt Ordners') + @api.depends('vertragssumme') + def _compute_prov(self): + _logger.info('contract Provision Berechnung : C_' + str(self.id)); + if self.provisionstyp.provisionbase == 'VSUM': + if not self.provisionstyp.provisioncalc: + prozent=self.provisionstyp.provisionprozent + basis=self.vertragssumme + value = (basis/100)*prozent + self.provisionsteilcalc = value + + def _compute_provisionspayedpercent(self): + addval = 0 + for prov in self.provisions: + _logger.info('contract Provision Payed_part : C_' + str(self.id)+' / '+str(prov.provisionprozent)); + addval = addval + prov.provisionprozent + _logger.info('Contract Provision payed : C_' + str(self.id)+' V '+str(addval)); + self.provisionspayedpercent = addval + + @api.onchange('provisionstyp') + def _onchange_provtype(self): + self._compute_prov() + self._compute_provisionspayedpercent() + + @api.onchange('vertragssumme') + def _onchange_vsumme(self): + self._compute_prov() + self._compute_provisionspayedpercent() + @api.model def _expand_ads_last_work_state(self,states,domain,order): if dss_settings.dssSettings._get_settingvalue(self,'show_expand_contract_group_ad_work_state'): @@ -248,12 +291,8 @@ class dsscontracts(models.Model): if resstr is None : resstr = 'nicht ermittelbar' _logger.info('Contract_client_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name)); - if not self.contract_auto_name: - self.contract_auto_name = resstr - if not self.contract_auto_id: - self.contract_auto_id = cidstr - if self.contract_auto_id == "": - self.contract_auto_id = cidstr + self.contract_auto_name = resstr + self.contract_auto_id = cidstr @api.onchange('project_id') def _onchange_project_id(self): @@ -263,16 +302,12 @@ class dsscontracts(models.Model): else: cname = record.contract_name resstr = "%s%s %s" % (record.project_id,record.client_id,cname) - cidstr = "%s%s" % (record.project_id,record.client_id) + cidstr: String = "%s%s" % (record.project_id,record.client_id) if resstr is None : resstr = 'nicht ermittelbar' _logger.info('project_id_change : C_' + str(self.id) + ' - '+str(cidstr)+' vs. '+str(self.contract_auto_id)+'/'+str(resstr)+' vs '+str(self.contract_auto_name)); - if not self.contract_auto_name: - self.contract_auto_name = resstr - if not self.contract_auto_id: - self.contract_auto_id = cidstr - if self.contract_auto_id == "": - self.contract_auto_id = cidstr + self.contract_auto_name = resstr + self.contract_auto_id = cidstr @api.onchange('contract_name') def _onchange_contract_name(self): @@ -319,6 +354,66 @@ class dsscontracts(models.Model): # contract=super().create(vals) # return contract + def action_info_click_ls(self): + view=self.env.ref("DigitalSignage.dss_contracts_infofeld_form") + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form' , + 'view_id': view.id, + 'res_model': 'dss.contracts' , + 'target': 'new' , + 'display_name' : 'Text ändern', + 'views':[(view.id,'form')], + 'res_id': self.id , + } + + def action_state_click_ls(self): + view=self.env.ref("DigitalSignage.dss_contracts_viewstate_ls_form") + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form' , + 'view_id': view.id, + 'res_model': 'dss.contracts' , + 'target': 'new' , + 'display_name' : 'Status ändern', + 'views':[(view.id,'form')], + 'res_id': self.id , + } + + def action_state_click_lws(self): + view=self.env.ref("DigitalSignage.dss_contracts_viewstate_lws_form") + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form' , + 'view_id': view.id, + 'res_model': 'dss.contracts' , + 'target': 'new' , + 'display_name' : 'Status ändern', + 'views':[(view.id,'form')], + 'res_id': self.id , + } + + def action_state_click_lds(self): + view=self.env.ref("DigitalSignage.dss_contracts_viewstate_lds_form") + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form' , + 'view_id': view.id, + 'res_model': 'dss.contracts' , + 'target': 'new' , + 'display_name' : 'Status ändern', + 'views':[(view.id,'form')], + 'res_id': self.id , + } + +# return { + #'effect':{ +# 'fadeout':'slow', +# 'message':'Status Geklickt', +# 'type':'rainbow_man', +# } +# } + '' @api.model def _default_uuid(self): @@ -387,7 +482,7 @@ class dsscontracts(models.Model): return "" def pyaction_dss_contract_addcalendar_rf_runtime(self): - self.runtime_calendar_event.unlink() + self.env['calendar.event'].search([('id', '=', self.runtime_calendar_event)]).unlink() event = { 'start': self.runtime_finish.strftime('%Y-%m-%d %H:%M:%S'), 'stop': self.runtime_finish.strftime('%Y-%m-%d %H:%M:%S'), @@ -416,9 +511,9 @@ class dsscontracts(models.Model): else: addyears = 0 addmonths = bmonths - (addyears*12) - enddatum = startdatum + relativedelta(months=addmonths,years=addyears) + enddatum = startdatum + relativedelta(months=addmonths,years=addyears,days=-1) elif self.runtimesystem == "T": - enddatum = startdatum + relativedelta(days=self.runtime_t) + enddatum = startdatum + relativedelta(days=self.runtime_t-1) enddatum = enddatum + relativedelta(days=self.runtime_t) elif self.runtimesystem == "E": enddatum = startdatum @@ -433,6 +528,67 @@ class dsscontracts(models.Model): self.runtime_finish = enddatum + if not self.contract_cancel_mon: + cancelmonths = 0 + else: + cancelmonths = self.contract_cancel_mon + + self.contract_cancel_date = enddatum - relativedelta(months=cancelmonths) + + def pyaction_dss_contract_calc_runtime_end(self): + if self.start_date: + startdatum= self.start_date + else: + startdatum= self.contract_date + if startdatum : + if self.runtimesystem == "M": + bmonths = 0 + bmonths = self.runtime_m+self.runtime_bonus_m + if bmonths > 12: + addyears=bmonths//12 + else: + addyears = 0 + addmonths = bmonths - (addyears*12) + enddatum = startdatum + relativedelta(months=addmonths,years=addyears,days=-1) + elif self.runtimesystem == "T": + enddatum = startdatum + relativedelta(days=self.runtime_t-1) + enddatum = enddatum + relativedelta(days=self.runtime_t) + elif self.runtimesystem == "E": + enddatum = startdatum + if self.runtime_events: + mydate = startdatum + for event in self.runtime_events: + if mydate.strftime('%Y-%m-%d') < event.eventenddate.strftime('%Y-%m-%d'): + mydate = event.eventenddate + enddatum = mydate + elif self.runtimesystem == "S": + enddatum = self.runtime_finish + + if not self.contract_cancel_mon: + cancelmonths = 0 + else: + cancelmonths = self.contract_cancel_mon + + self.contract_cancel_date = enddatum - relativedelta(months=cancelmonths) + + def pyopen_provadd_form_view(self): + _logger.info('Open Add Provision') + view=self.env.ref("DigitalSignage.dss_provision_add_form") + self._compute_prov() + provision=self.env['dss.provision'].create({'contract':self.id,'provisiongesamt':self.provisionsteilcalc,'paydate':date.today()}) + _logger.info('Open Add Provision '+str(view)+' P_'+str(provision)) +# self.provisions=[(4,[provision.id])] + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form' , + 'view_type': 'form' , + 'view_id': view.id, + 'res_model': 'dss.provision' , + 'target': 'new' , + 'display_name' : 'Neu Provision einfügen', + 'views':[(view.id,'form')], + 'res_id':provision.id, + } def tokampagne(self): _logger.info('Click auf Werbekampagne : C_'+str(self.id)+' - prüfe Letzte Aktuelle Kampagne') @@ -458,7 +614,7 @@ class dsscontracts(models.Model): resstr = 'nicht ermittelbar' _logger.debug(resstr) self.contract_auto_name = resstr - _logger.info('Click auf Werbekampagne : C_' + str(self.id) + 'A_' + str(ds.id) + ' - Contract_autoname gesetzt '+ str(resstr)+'/'+str(cidstr)) + _logger.info('Click auf Werbekampagne : C_' + str(self.id) + 'A_' + str(ds.id) + ' - Contract_autoname gesetzt '+ str(resstr)) # prüfen ob LetzteKampagne medien hat _logger.info('Click auf Werbekampagne : C_'+str(self.id)+'A_'+str(ds.id)+' - Suche evtl Medien der Kampagne ') medias = self.env['dss.mediarelations'].search(['&',('contract','=',self.id),('ad','=',ds.id)]) @@ -696,3 +852,33 @@ class dsscontracts(models.Model): for record in self: self.tokampagne() + + def trigger_action_init(self): + _logger.info('Contract Cron Running - Start '+str(self)+' start searching') + jobcontracts = self.env['dss.contracts'].search([('run_trigger', '=', True)]) + _logger.info('Contract Cron Running - Start '+str(self)+' Found '+str(len(jobcontracts))+' Trigger') + for record in jobcontracts: + if not record: + _logger.info('Contract Cron Running No Contracts Delivered - searching') + else: + _logger.info('Contract Cron Running C_' + str(record.id) + ' Check Trigger') + if record.run_trigger: + _logger.info('Contract Cron Running C_' + str(record.id) + ' Prüfe Triggergruppe TG_' + str(record.triggergroup.id)) + triggergroup = record.triggergroup + if not triggergroup: + _logger.info('Contract Cron Running C_' + str(record.id) + ' Triggergruppe TG_' + str(record.triggergroup.id)+' not found') + pass + else: + for trigger in triggergroup.triggers: + if not trigger: + pass + else: + _logger.info('Contract Cron Running C_' + str(record) + ' in Triggergruppe TG_' + str(record.triggergroup)+' Prüfe Trigger T_'+str(trigger)) + if trigger._check_trigger(): + _logger.info('Contract Cron Trigger T_' + str(trigger)+' executed ') + + + _logger.info('Contract Cron Running - Finished') + + + diff --git a/models/dss_dialog.py b/models/dss_dialog.py old mode 100644 new mode 100755 diff --git a/models/dss_eventdays.py b/models/dss_eventdays.py old mode 100644 new mode 100755 diff --git a/models/dss_geraetetypen.py b/models/dss_geraetetypen.py old mode 100644 new mode 100755 diff --git a/models/dss_maintains.py b/models/dss_maintains.py new file mode 100755 index 0000000..b272c8c --- /dev/null +++ b/models/dss_maintains.py @@ -0,0 +1,62 @@ + +import ast +import datetime +import json +import re +import uuid +import logging +import base64 +import subprocess +import tempfile +import easywebdav +import os +import os.path + + +from odoo import api, fields, models, _ +from odoo import tools +from odoo.exceptions import ValidationError +from datetime import date +from datetime import datetime +from dateutil.relativedelta import relativedelta +from pyffmpeg import FFmpeg +from tuya_iot import TuyaOpenAPI, TUYA_LOGGER +from tuya_connector import TuyaOpenAPI, TUYA_LOGGER +import sys + +TUYA_LOGGER.setLevel(logging.DEBUG) +_logger = logging.getLogger(__name__) + + +class dssmaintaintasks(models.Model): + _name = "dss.maintaintask" + _description = "DigitalSignage Wartungsarbeiten" + _inherit = ['mail.thread','mail.activity.mixin'] + _rec_name = "maintainname" + maintainname = fields.Char('Einsatzbezeichnung', required=True) + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + + date_create = fields.Date('Erstellungsdatum', default=lambda self: self._default_create_date()) + date_lastedit = fields.Date('Änderungsdatum') + user_create = fields.Char('Erstellungsuser', default=lambda self: self._default_create_user()) + user_lastedit = fields.Char('Änderungsuser') + + maintaintyp = fields.Selection([('AUF','Aufbau/Installation'),('REP','Reparatur'), ('CLE','Reinigung'), ('INS','Inspektion'), ('ABB','Demontage'), ('SON','Sonstiges')],tracking=True) + project = fields.Many2one('dss.projects', required=True, tracking=True) + maintain_tag = fields.Date('Einsatztag', required=True, tracking=True) + maintain_time_h = fields.Integer('Einsatzzeit Volle Stunden', required=True, tracking=True) + maintain_time_m = fields.Integer('Einsatzzeit Rest Minuten', required=True, tracking=True) +# maintain_people = fields.Many2many('res.partner','Einsatzbeteiligte', domain="['&',('dssinternpartner','=',True),('dssinternpartner_grafik','=',True)]", tracking=True,required=True) + maintain_reason = fields.Char('Einsatzgrund', required=True) + maintain_text = fields.Html('Einsatzablauf', required=True) + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) + + def _default_create_date(self): + return str(date.today()) + + def _default_create_user(self): + return str(self.env.user.name) + diff --git a/models/dss_projects.py b/models/dss_projects.py old mode 100644 new mode 100755 index 43adde6..8f59245 --- a/models/dss_projects.py +++ b/models/dss_projects.py @@ -7,6 +7,8 @@ import logging import base64 import subprocess import tempfile +#from symbol import return_stmt + import easywebdav import os import os.path @@ -47,6 +49,7 @@ class dssprojects(models.Model): description = fields.Text('Beschreibung',tracking=True) systemname = fields.Many2one('dss.systems',tracking=True) grundsystemname = fields.Many2one('dss.systemtypen',tracking=True) + grundsystem_typ = fields.Char(related='grundsystemname.kennung',tracking=True) grundsystemicon = fields.Image(related='grundsystemname.icon',tracking=True) grundsystem_default_adstructure = fields.Many2one(related='grundsystemname.default_adstructure',tracking=True) grundsystemicon5050 = fields.Image(related='grundsystemname.icon_5050') @@ -68,14 +71,22 @@ class dssprojects(models.Model): vertragsschreiber = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]",tracking=True) standortpartner = fields.Many2one('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_standort','=',True)]",tracking=True) vertriebspartner = fields.Many2many('res.partner',domain="['&',('dsspartner','=',True),('dsspartner_vertrieb','=',True)]",tracking=True) + project_grafiker = fields.Many2one('res.partner',domain="['&',('dssinternpartner','=',True),('dssinternpartner_grafik','=',True)]",tracking=True) zeiten_on = fields.Datetime('veraltet',tracking=True) zeiten_off = fields.Datetime('veraltet',tracking=True) zeitenf_on = fields.Float('Einschaltzeit',tracking=True) zeitenf_off = fields.Float('Ausschaltzeit',tracking=True) errichtet_am = fields.Date('Errichtungstag',tracking=True) - standort_inout = fields.Selection([('indoor','im Gebäude'), ('outdoor','Aussenbereich'), ('semiindoor','Überdachter Aussenbereich'),('Divers','Andere Art')],tracking=True); + standort_inout = fields.Selection([('indoor','im Gebäude'), ('outdoor','Aussenbereich'), ('semiindoor','Überdachter Aussenbereich'),('Divers','Andere Art')],tracking=True) + + date_start_compute = fields.Date('Kalender Start intern',compute='_compute_calendar_start') cloudlink = fields.Char('Cloud Verzeichnis',help='Verzeichnis für das Project innerhalb des Cloud Struktur') + maintains = fields.Many2many('dss.maintaintask',string="Einsätze am Projekt") + + @api.model + def _compute_calendar_start(self): + self.date_start_compute=date.today() @api.model def _default_uuid(self): @@ -102,7 +113,7 @@ class dssprojects(models.Model): # context = "{ # 'create': self.active, # 'active_test': self.active -# } +# }7 # action['context'] = context # action['domain'] = domain # return action diff --git a/models/dss_provision.py b/models/dss_provision.py new file mode 100644 index 0000000..a6f09f1 --- /dev/null +++ b/models/dss_provision.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -* + +import ast +import datetime +import json +import re +import uuid +import logging +import base64 +import subprocess +import tempfile +import easywebdav +import os +import os.path + + +from odoo import api, fields, models, _ +from odoo import tools +from . import dss_settings +from odoo.exceptions import ValidationError +from datetime import date +from datetime import datetime +from dateutil.relativedelta import relativedelta +from pyffmpeg import FFmpeg +from tuya_iot import TuyaOpenAPI, TUYA_LOGGER +from tuya_connector import TuyaOpenAPI, TUYA_LOGGER +import sys + +TUYA_LOGGER.setLevel(logging.DEBUG) +_logger = logging.getLogger(__name__) + +class dssprovision(models.Model): + + _name = "dss.provision" + _description = "DigitalSignage Provisionen" + _rec_name = "provisionname" + _inherit = ['mail.thread','mail.activity.mixin','dss.triggermodel'] + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) + user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) + provisionname = fields.Char('Kurzbezeichnung der Provision',tracking=True) + contract = fields.Many2one('dss.contracts' , string='Vertrag', store=True,tracking=True) + project = fields.Many2one(related='contract.project' , string='Project', store=True,tracking=True) + client = fields.Many2one(related='contract.client',string="Kunde (wenn angelegt)") + contract_writer = fields.Many2one(related='contract.contract_writer',string="Vertragsschreiber", store=True) + provisionbase = fields.Selection([('VZAHL','Volle Zahlung'),('TZAHL','Teil Betrag FIX'),('PZAHL','Teil Betrag Prozent')], tracking=True, store=True) + provisiongesamt = fields.Float('Gesamtsumme Provision', tracking=True) + provisionprozent = fields.Float('Ausgezahlte Prozent',tracking=True) + provisionteil = fields.Float('Auszahlungs-Summe', tracking=True) + + paydate = fields.Date('Zahlungsdatum', tracking=True) + + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) + + def _default_create_date(self): + return str(date.today()) + + def _default_create_user(self): + return str(self.env.user.name) + + + @api.onchange('provisionbase') + def _onchange_provisionbase(self): + if self.provisionbase == "PZAHL": + _logger.info('Calc Provisionpart : ' + str(self.provisionbase) + ' \% ' + str(self.provisionprozent)); + try: + self.provisionteil = self.provisiongesamt/100*self.provisionprozent + except: + self.provisionteil = 0 + elif self.provisionbase == "VZAHL": + _logger.info('Calc Provisionpart : ' + str(self.provisionbase) + ' \V ' + str(self.provisiongesamt)); + self.provisionteil = self.provisiongesamt + self.provisionprozent = 100 + else: + _logger.info('Calc Provisionpart : ' + str(self.provisionbase) + ' \T ' + str(self.provisionteil)); + self.provisionteil = self.provisionteil + + @api.onchange('provisionprozent') + def _onchange_provisionprozent(self): + self._onchange_provisionbase() + + def pyadd_entry_tocontract(self): + self._onchange_provisionbase() + self.contract.provisions=[(4,self.id)] + self.contract._compute_provisionspayedpercent() + + def pycancel_entry(self): + self.unlink() diff --git a/models/dss_provisionstypen.py b/models/dss_provisionstypen.py new file mode 100644 index 0000000..43e0fcf --- /dev/null +++ b/models/dss_provisionstypen.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -* + +import ast +import datetime +import json +import re +import uuid +import logging +import base64 +import subprocess +import tempfile +import easywebdav +import os +import os.path + + +from odoo import api, fields, models, _ +from odoo import tools +from . import dss_settings +from odoo.exceptions import ValidationError +from datetime import date +from datetime import datetime +from dateutil.relativedelta import relativedelta +from pyffmpeg import FFmpeg +from tuya_iot import TuyaOpenAPI, TUYA_LOGGER +from tuya_connector import TuyaOpenAPI, TUYA_LOGGER +import sys + +TUYA_LOGGER.setLevel(logging.DEBUG) +_logger = logging.getLogger(__name__) + +class dssprovisionstypen(models.Model): + + _name = "dss.provisionstypen" + _description = "DigitalSignage Provisionen" + _rec_name = "provisionstyp" + _inherit = ['mail.thread','mail.activity.mixin','dss.triggermodel'] + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + provisionbase = fields.Selection([('VSUM','Vertragssumme'),('FSUM','Fester Betrag')], tracking=True) + provisionstyp = fields.Char('Kurzbezeichnung der Provisions Art',tracking=True) + provisionprozent = fields.Float('Prozent der Basis',tracking=True) + provisioncalc = fields.Char('Berechnung',help="Beispiel : =%10(B-F(300)) ist 10% der (Basissumme - 300€) oder =%5(B)-F(200) ist 5% der Basissumme und dann minus 200€ )",tracking=True) + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) + diff --git a/models/dss_settings.py b/models/dss_settings.py old mode 100644 new mode 100755 index fa7ddff..57a1a98 --- a/models/dss_settings.py +++ b/models/dss_settings.py @@ -48,6 +48,8 @@ class dssSettings(models.Model): show_expand_contract_group_ad_state = fields.Boolean('Jeden Kampagnen-Status anzeigen ?',help='im Groupierungsmodus der Verträge nach Kampagnenstatus alle (auch unbenutzte) Statusspalten anzeigen ?',tracking=True) show_expand_contract_group_ad_work_state = fields.Boolean('Jeden Kampagnen-Arbeitsstatus anzeigen ?',help='im Groupierungsmodus der Verträge nach Kampagnen-Arbeitsstatus alle (auch unbenutzte) Statusspalten anzeigen ?',tracking=True) show_expand_contract_group_ad_todo_state = fields.Boolean('Jeden Kampagnen-Aufgabenschritt anzeigen ?',help='im Groupierungsmodus der Verträge nach Kampagnen-Aufgabenschritt alle (auch unbenutzte) Aufgabenspalten anzeigen ?',tracking=True) + freigabe_auto_time = fields.Integer('Auto Freigabetage',help='Automatische Freigabe nach x Tagen',tracking=True) + def _get_settingvalue(self,valuename): settings = (self.env['dss.settings'].search([],limit=1)) wert = settings._origin.read([valuename])[0][valuename] diff --git a/models/dss_software.py b/models/dss_software.py old mode 100644 new mode 100755 diff --git a/models/dss_systems.py b/models/dss_systems.py old mode 100644 new mode 100755 index 33a037a..aafbfc2 --- a/models/dss_systems.py +++ b/models/dss_systems.py @@ -42,7 +42,7 @@ class dsssystems(models.Model): standort = fields.Char('Hauptstandort des Systems',tracking=True) - farbe = fields.Integer('Grundfarbe') + farbe = fields.Char('Grundfarbe') has_heizung = fields.Boolean('Mit Heizsystem') has_klima = fields.Boolean('Mit Klimasystem') diff --git a/models/dss_systemtypen.py b/models/dss_systemtypen.py old mode 100644 new mode 100755 index 35952ca..637cf3b --- a/models/dss_systemtypen.py +++ b/models/dss_systemtypen.py @@ -40,8 +40,13 @@ class dsssystemtypen(models.Model): farbe = fields.Char('Grundfarbe') icon = fields.Image() icon_5050 = fields.Image("Icon 50",compute='_compute_icon_5050') - default_adstructure = fields.Many2one('dss.adstructures',String='Standard-Werbeaufbau') - default_cloud_path = fields.Char('Standard Cloud Path') + default_adstructure = fields.Many2one('dss.adstructures',String='Standard-Werbeaufbau', tracking=True) + default_cloud_path = fields.Char('Standard Cloud Path', tracking=True) + email_template_welcome = fields.Many2one('mail.template',string='Mailvorlage für Willkommen', tracking=True) + email_template_zuarbeit = fields.Many2one('mail.template',string='Mailvorlage für Zuarbeiterrinnerung', tracking=True) + email_template_abzug = fields.Many2one('mail.template',string='Mailvorlage für Korrekturabzug', tracking=True) + email_template_start = fields.Many2one('mail.template',string='Mailvorlage für Auslieferung', tracking=True) + @api.model def _default_uuid(self): return str(uuid.uuid4()) diff --git a/models/dss_trigger.py b/models/dss_trigger.py new file mode 100644 index 0000000..e05a996 --- /dev/null +++ b/models/dss_trigger.py @@ -0,0 +1,135 @@ +import uuid +import logging + +from odoo import api, fields, models, _ +from odoo import tools +from odoo.exceptions import ValidationError +import sys + +_logger = logging.getLogger(__name__) + +class dsstriggergroups(models.Model): + _name = "dss.triggergroups" + _description = "DigitalSignage Trigger Gruppen" + _inherit = ['mail.thread','mail.activity.mixin'] + _rec_name = "triggergroupname" +# _inherit = ['mail.thread', 'mail.activity.mixin'] + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) + date_lastedit = fields.Date('Änderungsdatum') + user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) + user_lastedit = fields.Char('Änderungsuser') + + triggergroupname = fields.Char('Trigger Gruppenname',tracking=True) + trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',track_visibility='onchange',tracking=True) + triggers = fields.Many2many('dss.triggertypes',string='Enthaltene Trigger',tracking=True) + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) + + def _default_create_date(self): + return str(date.today()) + + def _default_create_user(self): + return str(self.env.user.name) + + +class dsstriggertypes(models.Model): + _name = "dss.triggertypes" + _description = "DigitalSignage Trigger Typen" + _inherit = ['mail.thread','mail.activity.mixin'] + _rec_name = "triggername" + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) + date_lastedit = fields.Date('Änderungsdatum') + user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) + user_lastedit = fields.Char('Änderungsuser') + + triggername = fields.Char('Triggername',tracking=True) + trigger_active = fields.Boolean('Trigger Aktiv ?',tracking=True) + triggertyp = fields.Selection([('FIELD_A','Feldänderung allgemein'),('FIELD_S','Feldänderung spezifisch'),('FIELD_K','Feldwert berechnet'),('MANUAL','Menuell ausgelösst')],'Triggertyp',tracking=True) + trigger_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist dieser Tigger gültig ?',tracking=True) + trigger_field = fields.Many2one('ir.model.fields', help='Feldname in der Tabelle',tracking=True) + trigger_operator = fields.Selection([('NGLEICH','Feld gleich dem Wert'),('GGLEICH','Feld größer/gleich dem Wert'),('KGLEICH','Feld kleiner/gleich dem Wert'),('UGLEICH','Feld ungleich dem Wert'),('ENTHAELT','Feld enthällt dem Wert')],'Feldwertoperator',tracking=True) + trigger_init_trigger = fields.Boolean('Ausl. bei 1. Änderung ?',help='Soll der Trigger bereits beim setzen des 1. Wertes auslösen?',tracking=True) + trigger_value = fields.Char('Feldwert für Trigger',tracking=True) + trigger_old_value = fields.Char('Letzter-Feldwert für Trigger',tracking=True) + trigger_aktionen = fields.Many2many('ir.actions.server',string='Aktionen bei auslösen des Triggers',tracking=True) + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) + + def _default_create_date(self): + return str(date.today()) + + def _default_create_user(self): + return str(self.env.user.name) + + def _check_trigger(self): + for record in self: + _logger.info('Trigger Check TR_' + str(record)+' Begin') + if record.trigger_active: + _logger.info('Trigger Check TR_' + str(record) + ' Check Field F_'+str(record.trigger_field.name)+' of model M_'+str(record.trigger_table.model)+' Feld-Typ :'+str(record.trigger_field.ttype)) + if record.trigger_field.ttype in ['char','text','html']: + val = self.env[record.trigger_table.model]._origin.read([record.trigger_field.name]) + elif record.trigger_field.ttype in ['selection']: + val = self.env[record.trigger_table.model]._origin.read([record.trigger_field.name])[0] + elif record.trigger_field.ttype in ['one2many']: + val = self.env[record.trigger_table.model]._origin.read([record.trigger_field.name]).ids + elif record.trigger_field.ttype in ['many2one']: + val = self.env[record.trigger_table.model]._origin.read([record.trigger_field.name]) + else: + val = False + record.trigger_old_value = str(val) + _logger.info('Trigger Check TR_' + str(record)+' oldValue '+str(val)) + _logger.info('Trigger Check TR_' + str(record)+' Ende') + return "" + +class dsstriggeractions(models.Model): + _name = "dss.triggeractions" + _description = "DigitalSignage Trigger Aktionen" + _inherit = ['mail.thread','mail.activity.mixin'] + _rec_name = "triggeractionname" + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + date_create = fields.Date('Erstellungsdatum',default=lambda self: self._default_create_date()) + date_lastedit = fields.Date('Änderungsdatum') + user_create = fields.Char('Erstellungsuser',default=lambda self: self._default_create_user()) + user_lastedit = fields.Char('Änderungsuser') + + triggeractionname = fields.Char('Triggeraktionname',track_visibility='onchange',tracking=True) + triggeractiontyp = fields.Selection([('EMAIL','EMail senden'),('ACTIV','Aufgabe erzeugen'),('DSEDIT','Datensatz ändern'),('TUYA','Tuya Aktion auslössen')],'Aktionstyp',tracking=True) + email_getfrom = fields.Selection([('FIX','Email fest hinterlegt'),('DATA','Email in Feld hinterlegt')],'Emailadresse von',tracking=True) + email_fix_email_sender = fields.Many2one('res.partner','Absender',help='Email Sender Adresse der Aktion',tracking=True) + email_fix_email = fields.Many2one('res.partner','Empfänger',help='Email Emüfänger Adresse für Benachrichtigung/Triggeraktion',tracking=True) + email_data_table = fields.Many2one('ir.model','Nutzbar in',help='Für welche Daten ist diese Aktion gültig ?',tracking=True) + email_data_field = fields.Many2one('ir.model.fields', help='Feldname in der Tabelle',tracking=True) + email_template = fields.Many2one('mail.template','Emailvorlage',tracking=True) + + field = fields.Char('Feldname',help='Feldname in o.g. Tebelle.',tracking=True) + type_s = fields.Char('Feldwertoperator',tracking=True) + value_s = fields.Char('Feldwert für Trigger',tracking=True) + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) + + def _default_create_date(self): + return str(date.today()) + + def _default_create_user(self): + return str(self.env.user.name) + + +class dsstriggermodel(models.Model): + _name = "dss.triggermodel" + _description = "DigitalSignage Trigger Model für Inherit" + _rec_name = "trigger_uuid" + trigger_uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') + run_trigger = fields.Boolean('Trigger aktiv',tracking=True) + triggergroup = fields.Many2one('dss.triggergroups',string='Triggergruppe',tracking=True,default=True) + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) diff --git a/models/dss_triggervalues.py b/models/dss_triggervalues.py new file mode 100644 index 0000000..346b35d --- /dev/null +++ b/models/dss_triggervalues.py @@ -0,0 +1,21 @@ +from odoo import api, fields, models, _ +from odoo import tools + + +class dssadstatus(models.Model): + _name = "dss.triggervalues" + _description = "DigitalSignage Trigger Werte" +# _rec_name = "statusname" +# _inherit = ['mail.thread', 'mail.activity.mixin'] + uuid = fields.Char(default=lambda self: self._default_uuid(), required=True, readonly=True, copy=False, string='UUID') +# uuid = fields.Char('UUID', required=True, translate=True) + valuename = fields.Char('Wertname', required=True) + value_old_bool = fields.Boolean('Alter Boolean_Wert', required=True) + value_old_string = fields.Char('Alter String_Wert', required=True) + value_old_integer = fields.Integer('Alter Integer_Wert', required=True) + icon = fields.Image() + order = fields.Integer('Reihenfolge') + + @api.model + def _default_uuid(self): + return str(uuid.uuid4()) diff --git a/odoolog b/odoolog new file mode 120000 index 0000000..217f935 --- /dev/null +++ b/odoolog @@ -0,0 +1 @@ +/var/log/odoo \ No newline at end of file diff --git a/security/groups.xml b/security/groups.xml index 3119259..54cfb2f 100755 --- a/security/groups.xml +++ b/security/groups.xml @@ -22,4 +22,17 @@ + + + Systemtechniker + + + + + + Provisionsinformationen + + + + \ No newline at end of file diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index 855c8b9..3f5b4a6 100755 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -25,3 +25,6 @@ digitalsignage_dss_screendesign_group_user,access.dss.screendesign,model_dss_scr digitalsignage_dss_triggertypes_group_user,access.dss.triggertypes,model_dss_triggertypes,base.group_user,1,1,1,1 digitalsignage_dss_triggeractions_group_user,access.dss.triggeractions,model_dss_triggeractions,base.group_user,1,1,1,1 digitalsignage_dss_triggergroups_group_user,access.dss.triggergroups,model_dss_triggergroups,base.group_user,1,1,1,1 +digitalsignage_dss_maintaintask_group_user,access.dss.maintaintask,model_dss_maintaintask,base.group_user,1,1,1,1 +digitalsignage_dss_provision_group_user,access.dss.provision,model_dss_provision,base.group_user,1,1,1,1 +digitalsignage_dss_provisionstypen_group_user,access.dss.provisionstypen,model_dss_provisionstypen,DigitalSignage.group_prov_user,1,1,1,1 diff --git a/static/src/css/dss.css b/static/src/css/dss.css index 08339bf..70c2865 100755 --- a/static/src/css/dss.css +++ b/static/src/css/dss.css @@ -34,6 +34,22 @@ width:90px; .o_FormRenderer_chatterContainer.oe_chatter.o-aside { - max-width: 20%; // The width in pixels + max-width: 30%; // The width in pixels + +} + +.my_prov_class [data-id="provisionname"] { + + width:330px !important; + + min-width: 130px !important; + +} + +.my_prov_class [data-id="Sl No"] { + + width:130px !important; + + min-width: 30px !important; } \ No newline at end of file diff --git a/static/src/helpers/img/pat-blue.jpg b/static/src/helpers/img/pat-blue.jpg new file mode 100644 index 0000000..3a553ff Binary files /dev/null and b/static/src/helpers/img/pat-blue.jpg differ diff --git a/static/src/helpers/img/pat-orange.jpg b/static/src/helpers/img/pat-orange.jpg new file mode 100644 index 0000000..a9c5e78 Binary files /dev/null and b/static/src/helpers/img/pat-orange.jpg differ diff --git a/static/src/helpers/img/pat-red.jpg b/static/src/helpers/img/pat-red.jpg new file mode 100644 index 0000000..23143dd Binary files /dev/null and b/static/src/helpers/img/pat-red.jpg differ diff --git a/static/src/helpers/img/pat-yellow.jpg b/static/src/helpers/img/pat-yellow.jpg new file mode 100644 index 0000000..2554bda Binary files /dev/null and b/static/src/helpers/img/pat-yellow.jpg differ diff --git a/static/src/helpers/v2/app.js b/static/src/helpers/v2/app.js new file mode 100644 index 0000000..9c74f49 --- /dev/null +++ b/static/src/helpers/v2/app.js @@ -0,0 +1 @@ +!function(){"use strict";var t={572:function(t,e,n){n.r(e),e.default='
\r\n\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n
\r\n \r\n
\r\n
Download DayPilot Lite for JavaScript (open-source)
\r\n
See also the advanced features of DayPilot Pro (commercial).
\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n\r\n
\r\n'},722:function(t,e){Object.defineProperty(e,"t",{value:!0}),e.i=void 0;var n=function(){function t(){}return t.o=navigator&&navigator.userAgent&&(-1!==navigator.userAgent.indexOf("MSIE")||-1!==navigator.userAgent.indexOf("Trident")),t}();e.i=n},143:function(t,e){Object.defineProperty(e,"t",{value:!0}),e.u=void 0;var n=function(){function t(){}return t.get=function(t){return document.getElementById(t)},t.query=function(t){return Array.apply(null,document.querySelectorAll(t))},t.l=function(t,e){return t.getElementsByClassName(e)[0]},t.create=function(t){return document.createElement(t)},t.h=function(){return document.createDocumentFragment()},t}();e.u=n},730:function(t,e){Object.defineProperty(e,"t",{value:!0}),e.v=void 0;var n=function(){function t(){}return t.prototype.m=function(){var t=this;document.addEventListener("DOMContentLoaded",(function(){Array.apply(null,document.querySelectorAll(".track-download")).forEach((function(e){e.addEventListener("click",(function(n){t.track(e,"/action/trialdownload")||n.preventDefault()}))}))}))},t.prototype.download=function(t){var e=document.createElement("a");e.href=t,e.download=t.split("/").pop(),document.body.appendChild(e),e.click(),document.body.removeChild(e)},t.prototype.track=function(t,e){var n=this,i=window.ga;return void 0!==i&&i("send","pageview",e),"_blank"===t.target||(setTimeout((function(){n.download(t.href)}),150),!1)},t}();e.v=n},447:function(t,e,n){var i=this&&this.p||function(t,e,n,i){return new(n||(n=Promise))((function(r,a){function o(t){try{c(i.next(t))}catch(t){a(t)}}function u(t){try{c(i.g(t))}catch(t){a(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(o,u)}c((i=i.apply(t,e||[])).next())}))},r=this&&this.k||function(t,e){var n,i,r,a,o={label:0,O:function(){if(1&r[0])throw r[1];return r[1]},M:[],T:[]};return a={next:u(0),g:u(1),_:u(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function u(u){return function(c){return function(u){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,u[0]&&(o=0)),o;)try{if(n=1,i&&(r=2&u[0]?i._:u[0]?i.g||((r=i._)&&r.call(i),0):i.next)&&!(r=r.call(i,u[1])).done)return r;switch(i=0,r&&(u=[2&u[0],r.value]),u[0]){case 0:case 1:r=u;break;case 4:return o.label++,{value:u[1],done:!1};case 5:o.label++,i=u[1],u=[0];continue;case 7:u=o.T.pop(),o.M.pop();continue;default:if(!(r=o.M,(r=r.length>0&&r[r.length-1])||6!==u[0]&&2!==u[0])){o=0;continue}if(3===u[0]&&(!r||u[1]>r[0]&&u[1]=o.scrollHeight?r.classList.add("no-gradient-bottom"):r.classList.remove("no-gradient-bottom"),0==o.scrollTop?r.classList.add("no-gradient-top"):r.classList.remove("no-gradient-top"))};c(),o.addEventListener("scroll",c),window.addEventListener("resize",c),new MutationObserver(c).observe(o,{childList:!0,subtree:!0}),o.addEventListener("mouseover",(function(e){var n=e.target;if("A"===n.tagName){var i=n.getAttribute("href");i&&t.H(i)}})),o.addEventListener("touchstart",(function(e){var n=e.target;if("A"===n.tagName){var i=n.getAttribute("href");i&&t.H(i)}})),i=o.querySelector(".active"),document.body.className="dpw-sidebar-left"}else document.body.className="dpw-no-sidebar";var s=u.u.l(n,"toolbar"),l=this.q();s.appendChild(l);var f=u.u.l(n,"placeholder");this.placeholder=f,f.appendChild(this.B(document)),d.i.o?f.appendChild(this.content):f.appendChild(this.content.content),new h.K(this.placeholder).Y(),document.body.insertBefore(n,document.body.firstChild),this.search.m(),i&&this.U(i),this.location.X&&!this.location.sandbox&&this.N.m()},t.prototype.B=function(t){var e=t.title.split("|")[0].trim(),n=t.createElement("h2");return n.className="title",n.innerHTML=e,n},t.prototype.U=function(t){var e=document.querySelector(".dp-menu");if(e){var n=e.getBoundingClientRect(),i=t.getBoundingClientRect();i.topn.bottom&&(e.scrollTop+=i.bottom-n.bottom+85)}},t.prototype.F=function(){var t=this,e=u.u.create("div");e.className="dp-menu";var n=u.u.create("ul"),i=this.location.Z;return this.R.getItems(i).forEach((function(e){var i=e.filename;"index.html"!==i||t.location.filesystem||(i="./");var r=t.$(e.text,i,e.filename===t.location.filename,e.tt);n.appendChild(r.div)})),e.appendChild(n),e},t.prototype.$=function(t,e,n,i){var r=this,a=u.u.create("li");if("string"==typeof e){var o=document.createElement("a");if(o.href=e,o.title=t,n&&(o.className="active"),this.D&&o.addEventListener("click",(function(t){window.innerWidth<=1e3||(t.preventDefault(),r.et(e))})),i){var c=u.u.create("span");c.innerText="NEW",c.className="new",o.appendChild(c)}var s=u.u.create("span");s.innerText=t,o.appendChild(s),a.appendChild(o)}else{var l=u.u.create("strong");l.innerText=t,a.appendChild(l)}return{div:a}},t.prototype.q=function(){var t=this,e=u.u.h(),n=this.location.W?"":"../",i=this.location.filesystem?"index.html":"",r=this.location.sandbox?"Sandbox":"Demo",a=this.nt(r,n+i,this.location.W);return e.appendChild(a.div),this.R.it().forEach((function(r){var a="".concat(n).concat(r.Z,"/").concat(i),o=r.Z===t.location.Z,u=t.nt(r.text,a,o);e.appendChild(u.div)})),e},t.prototype.nt=function(t,e,n){var i=u.u.create("div");i.className="dpw-header-item";var r=document.createElement("a");return r.href=e,r.innerText=t,n&&(r.className="dpw-header-item-selected"),i.appendChild(r),{div:i,a:r}},t.prototype.J=function(){var t=this;window.addEventListener("popstate",(function(e){var n=window.location.pathname,i=n.substring(n.lastIndexOf("/")+1);""!==i&&"index.html"!==i||(i="./"),t.et(i,!0)}))},t.prototype.H=function(t){return i(this,void 0,void 0,(function(){var e,n,i;return r(this,(function(r){switch(r.label){case 0:return this.P[t]?[2,this.P[t]]:[4,fetch(t)];case 1:return(e=r.O()).ok?[4,e.text()]:[2,null];case 2:return-1===(n=r.O()).indexOf("")?[2,null]:(i=new v(n),this.rt(i.ot),this.P[t]=i,[2,i])}}))}))},t.prototype.et=function(t,e){return i(this,void 0,void 0,(function(){var n,i,a,o,c,s,l,d,f,v,m;return r(this,(function(r){switch(r.label){case 0:return n=window.location.href,(i=this.P[t])?[3,2]:[4,this.H(t)];case 1:i=r.O(),r.label=2;case 2:return i?(a=i.ot,o=a.querySelector("#content").content,this.rt(a),o.querySelectorAll("script").forEach((function(t){var e=t.parentNode,n=document.createElement("script");n.innerHTML="(function() {".concat(t.innerHTML,"})();"),e.replaceChild(n,t)})),this.placeholder.innerHTML="",this.placeholder.appendChild(this.B(a)),this.placeholder.appendChild(o),(c=a.querySelector("script[src*='jquery']"))&&(s=c.getAttribute("src"))&&(document.querySelector('script[src="'.concat(s,'"]'))||((l=document.createElement("script")).setAttribute("src",s),document.head.appendChild(l))),new h.K(this.placeholder).Y(),d=a.querySelector("title"),document.title=d.innerText,e||window.history.pushState({},"",t),this.search.m(),f=u.u.l(document.body,"dp-menu"),(v=f.querySelector("a.active"))&&v.classList.remove("active"),(m=f.querySelector('a[href="'.concat(t,'"]')))&&(m.classList.add("active"),this.U(m)),this.ut({referrer:n}),[2]):[2]}}))}))},t.prototype.ut=function(t){var e=window.__sendPageView;e&&e(window.location.href,t)},t.prototype.rt=function(t){t.querySelectorAll("link[rel=stylesheet]").forEach((function(t){var e=t.getAttribute("href");if(e&&!document.querySelector('link[href="'.concat(e,'"]'))){var n=document.createElement("link");n.setAttribute("rel","stylesheet"),n.setAttribute("href",e),document.head.appendChild(n)}}))},t}();e.S=f;var v=function(){function t(t){this.ct=t}return Object.defineProperty(t.prototype,"ot",{get:function(){return(new DOMParser).parseFromString(this.ct,"text/html")},enumerable:!1,configurable:!0}),t}();e.j=v},11:function(t,e){Object.defineProperty(e,"t",{value:!0}),e.C=void 0;var n=function(){function t(t,e,n){this.st=["demo","demo2","sandbox","lite"],this.pathname=n,this.host=e,this.protocol=t,this.lt()}return Object.defineProperty(t.prototype,"W",{get:function(){return"ROOT"===this.Z},enumerable:!1,configurable:!0}),t.test=function(){},t.prototype.lt=function(){this.filename=this.ht(this.pathname),this.Z=this.dt(this.pathname),this.sandbox=this.ft(this.pathname),this.X=this.vt(this.host),this.filesystem=this.xt(this.protocol)},t.prototype.ht=function(t){var e=t.substring(t.lastIndexOf("/")+1);return""===e&&(e="index.html"),e},t.prototype.xt=function(t){return"file:"===t},t.prototype.dt=function(t){var e=t.lastIndexOf("/"),n=t.lastIndexOf("/",e-1),i=t.substring(n+1,e);return"/"===i&&(i="ROOT"),-1!==this.st.indexOf(i)&&(i="ROOT"),i},t.prototype.vt=function(t){return"javascript.daypilot.org"===t},t.prototype.ft=function(t){return 0===t.indexOf("/sandbox")},t.prototype.print=function(){window.console.log(this.pathname,this.Z,this.filename)},t}();e.C=n},463:function(t,e,n){Object.defineProperty(e,"t",{value:!0}),e.A=void 0;var i=n(143),r=function(){function t(){this.wt=null}return t.prototype.m=function(){var t=this,e=this.bt=i.u.get("search-box-input");e.addEventListener("keyup",(function(n){"Escape"!==n.key&&"Esc"!==n.key||(e.value=""),t.gt(e.value)})),i.u.get("search-box-clear").addEventListener("click",(function(n){t.yt(),e.focus()}))},t.prototype.yt=function(){this.bt.value="",this.gt("")},t.prototype.gt=function(t){var e=!t||""===t.trim();e?this.kt():this.Ot(),i.u.query(".menu li").forEach((function(n){var i=n.getElementsByTagName("a")[0],r=i&&-1!==i.innerText.toLowerCase().indexOf(t.toLowerCase()),a=e||r;n.style.display=a?"":"none"}))},t.prototype.Ot=function(){if(null==this.wt){var t=this.Mt();t&&(this.wt=t.offsetHeight,t.style.height=this.wt+"px")}},t.prototype.kt=function(){var t=this.Mt();this.wt=null,t&&(t.style.height="")},t.prototype.Mt=function(){return i.u.query(".dp-menu")[0]},t}();e.A=r},151:function(t,e,n){Object.defineProperty(e,"t",{value:!0}),e.K=void 0;var i=n(143),r=n(827),a=n(722),o=function(){function t(t){this.placeholder=t}return t.prototype.Y=function(){if(null!==this.Tt()){var t=this._t();this.placeholder.appendChild(t)}},t.prototype._t=function(){var t=this,e=i.u.create("div");e.className="space";var n=i.u.create("button");return n.className="button-source",n.innerText="Show source",n.onclick=function(){t.Et(),n.style.display="none"},e.appendChild(n),e},t.prototype.Et=function(){var t,e=this.Tt(),n=a.i.o?e.innerText:e.innerHTML,o=n;if(n.startsWith("(function() {")){var u=n.indexOf("(function() {"),c=n.lastIndexOf("})();");o=n.substring(u+13,c)}a.i.o?((t=i.u.create("div")).innerHTML="
"+r.St.jt(o)+"
",this.placeholder.appendChild(t)):((t=i.u.create("pre")).innerText=r.St.jt(o),this.placeholder.appendChild(t))},t.prototype.Tt=function(){return this.placeholder.querySelector("script:not([src])")},t}();e.K=o},4:function(t,e){Object.defineProperty(e,"t",{value:!0}),e.L=void 0;var n=[{text:"Calendar",Z:"calendar",children:[{text:"Main"},{text:"JavaScript Event Calendar",filename:"index.html"},{text:"View Types"},{text:"Day View",filename:"day.html"},{text:"Days View",filename:"days.html"},{text:"Week View",filename:"week.html"},{text:"Resources View",filename:"resources.html"},{text:"Resource Calendar"},{text:"Resource Images",filename:"resourceimages.html",tt:!0},{text:"Resource Icons",filename:"resourceicons.html",tt:!0},{text:"Grid"},{text:"Height",filename:"height.html"},{text:"Highlighting Today",filename:"today.html",tt:!0},{text:"Lunch Break",filename:"lunch.html",tt:!0},{text:"Text in Cells",filename:"textincells.html",tt:!0},{text:"Navigation"},{text:"Navigator",filename:"navigator.html"},{text:"Date Picker",filename:"datepicker.html"},{text:"Next/Previous",filename:"nextprevious.html"},{text:"Themes"},{text:"Green Theme",filename:"themegreen.html"},{text:"Transparent Theme",filename:"themetransparent.html"},{text:"White Theme",filename:"themewhite.html"},{text:"Events"},{text:"Event Active Areas",filename:"eventareas.html"},{text:"Event Context Menu",filename:"eventmenu.html"},{text:"Event Customization",filename:"eventcustomization.html"},{text:"Event Icons",filename:"eventicons.html"},{text:"Event Deleting",filename:"eventdeleting.html"},{text:"Event Types",filename:"eventtypes.html"},{text:"Localization"},{text:"Localization",filename:"localization.html"},{text:"Frameworks"},{text:"Angular",filename:"angular.html"},{text:"React",filename:"react.html"},{text:"Vue",filename:"vue.html"}]},{text:"Month",Z:"month",children:[{text:"Main"},{text:"JavaScript Monthly Event Calendar",filename:"index.html"},{text:"Navigation"},{text:"Navigator",filename:"navigator.html"},{text:"Date Picker",filename:"datepicker.html"},{text:"Next/Previous",filename:"nextprevious.html"},{text:"Themes"},{text:"Green Theme",filename:"themegreen.html"},{text:"Transparent Theme",filename:"themetransparent.html"},{text:"White Theme",filename:"themewhite.html"},{text:"Events"},{text:"Event Active Areas",filename:"eventareas.html"},{text:"Event Context Menu",filename:"eventmenu.html"},{text:"Event Customization",filename:"eventcustomization.html"},{text:"Event Deleting",filename:"eventdeleting.html"},{text:"Grid"},{text:"Cell Customization",filename:"cellcustomization.html",tt:!0},{text:"Frameworks"},{text:"Angular",filename:"angular.html"},{text:"React",filename:"react.html"},{text:"Vue",filename:"vue.html"},{text:"Localization"},{text:"Localization",filename:"localization.html"}]},{text:"Scheduler",Z:"scheduler",children:[{text:"Main"},{text:"JavaScript Scheduler",filename:"index.html"}]}],i=function(){function t(){this.Dt={},this.load()}return t.prototype.getItems=function(t){var e,n;return null!==(n=null===(e=this.Dt[t])||void 0===e?void 0:e.children)&&void 0!==n?n:[]},t.prototype.it=function(){return n},t.prototype.load=function(){var t=this;n.forEach((function(e){t.Dt[e.Z]=e}))},t}();e.L=i},827:function(t,e){Object.defineProperty(e,"t",{value:!0}),e.St=void 0;var n=function(){function t(){}return t.jt=function(t){var e=this,n=t.split(/\r?\n/),i=100;n.forEach((function(t){if(!(0===t.trim().length)){var n=e.zt(t);na,.dpw-header-item>a:visited{display:inline-block;margin-right:30px;padding:10px 0}.dpw-header-item a.dpw-header-item-selected{border-bottom:4px solid #00639e;box-sizing:border-box}.dpw-header .dpw-header-right{position:absolute;right:0;top:0}.dpw-header form{display:inline-block}.dpw-header .dpw-header-right .dpw-header-search fieldset{border:0;padding:5px 0}.dpw-header .dpw-header-right .dpw-header-search input{font-size:14px;padding:2px 5px}.dpw-subheader{border-bottom:1px solid #ccc;box-shadow:0 5px 10px -5px rgba(0,0,0,.2);min-height:40px;overflow-x:auto;overflow-y:hidden;white-space:nowrap}.dpw-subheader-inner{font-size:14px;margin:0 auto;max-width:1600px}.dpw-subheader-item{display:inline-block}.dpw-subheader a,.dpw-subheader a:visited{color:#666;text-decoration:none}.dpw-subheader>a,.dpw-subheader>a:visited{display:inline-block;margin-right:30px;padding:10px 0}.dpw-title{background-color:#f0f0f0;border-bottom:1px solid #ccc;box-shadow:0 5px 10px -5px rgba(0,0,0,.2)}.dpw-title-inner{margin:0 auto;max-width:1600px;padding:20px 0}.dpw-title h1{margin:0;padding:0}.dpw-main{display:flex;flex-direction:row;margin:20px auto 0;max-width:1600px;overflow:hidden}.dpw-body-inner{line-height:1.6}.section-highlight{box-sizing:border-box;margin:30px 0;padding:30px 0;position:relative}.section-highlight:before{background-color:#f0f0f0;content:"";height:100%;left:0;margin-left:-1000px;margin-right:-1000px;position:absolute;right:0;top:0;z-index:-1}.dpw-body-edit{background-color:red;bottom:0;color:#fff;padding:5px;position:fixed;right:0}.dpw-body-edit a{color:#fff}.dpw-body h1{font-size:30px;margin:0;padding-bottom:30px}.dpw-body h2{font-size:30px;margin:0;padding-top:40px}.dpw-body img{height:auto;max-width:100%}.dpw-body a,.dpw-sidebar a{color:#1155a3}.dpw-body pre{line-height:1.42;overflow:auto;overflow-x:auto;overflow-y:hidden;padding:.5em;width:100%}.dpw-body em,.dpw-body pre{background-color:#f7f7f9;border:1px solid #d9d9d9;box-sizing:border-box;font-size:13px}.dpw-body em{font-family:monospace;font-style:normal;padding:0 2px}.dpw-body ul{list-style-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAHAQMAAAAVq36TAAAABlBMVEX09PSTswCvaW5/AAAAAXRSTlMAQObYZgAAABxJREFUeF4NwzEBAAAIArBFJxpRjGAEPSZq7KscJF4FMTAtnEMAAAAASUVORK5CYII=);list-style-position:inside;margin:.2em 0 1em;padding:0}.dpw-body ul li{padding-left:12px;text-indent:-12px}.dpw-body ul li div{display:inline}p.image-left img{float:left;margin-right:20px;max-width:50%}p.image-right img{float:right;margin-left:20px;max-width:50%}h1,h2,h3,h4,table{clear:both}.dpw-body h2 a{color:#000;text-decoration:none}a.inline-btn{background-color:#00639e}a.inline-btn,a.inline-btn-lighter{box-sizing:border-box;color:#fff;display:inline-block;padding:10px 40px;text-decoration:none}a.inline-btn-lighter{background-color:#3495cf}table td a.inline-btn{text-align:center;width:100%}.new-label{color:#e69138;font-size:12px;font-weight:700}.breadcrumbs{color:#666;font-size:12px}.breadcrumbs a{color:#666}.dpw-footer{background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABnQAAABmCAMAAADF74/GAAAAUVBMVEUBGDABMlcBGzYBNVwBKkoBJkYBOWABFCsBLU8BI0EBIT0BHjoBL1IAPGUAS3wAT4EARXIAUoYAW5MAVosASHcAQW0AWY8AP2kAXpYAX5kAYp3CdriVAAAd7ElEQVR42uydi27bMAxF816a1K/GTdz//9FJkQQ6FhmSlu24jc/1ZGMYhhXYdnNKNl39k7JamUvMZrNZbeScJZxEfDxn/7FXsZNxlPDJslax1XEQkT3hFvONUpLUJDlNQVE940JzpfkanOvXleRC4j+GCqUgyUlqkpLkG+WGkNEcRGwN5pCyVvHJcpSwE7LXYP5LYjhJOIvYqFhpUFQJ/ytczIO7M2XjYw//DME5m9jDhuRkQ/MBIdnb2HsIya4Vrmx8/K1v6ax9/I0rG5/wQHJ4zFMyn/AQccuiwrGJKEMi6pAOOaRDAelQ3X9UlT26XNppc31Mm6+QMbi6PHCxCbdu4Zi4EyscE7x2ckiH2sSdj21jrpCIb5P7EZdOVDuZTZeDCzw9ZdsOzboTpmx8/K1v6ey6YdhDaD5C/I3mBKE525BsQsyFs3oSpmx8wgPLaKbjAkxlOozmmAjZuQgJfbMbxnQ+Ra0j5eCiMh2udgJx30hMp0Rah6DIKcsxl2scrHVm4zl3/G9Oq871oXIsoTtR3EePm05Bmk5uQptO3S0ce6NM5xsxnRtnOpmkdSy88sArLp3prFNMB9rmyJnOzkZhOuaclemsXFRApwxpOvcHqenYzM50WsrD9s0dpmogiaYT8jLTiV6XdrgJTAeqB7Gd2lzhiE3HHVjjkMXjHadAGoeoHtpzemhO0zRq2eng/hS06cBHITYdVzs+tOkAZdAdwnR8RjMdQGI64DpbhelAEk3nKDcdg8p0AEZ1Ek3nLFcd83NzMZ1/I5jOeTGdUD5C0zEoTMedIqBulKYDjWMP1UiH+sxauJNUJnrTSdKcBkHoOnjvXEMbdqhCMAobQGE6uUh1oHdQRjGd8DJJbjoGsekE/qzpnBbT2YhN52wzR9OxYUc6IROazrYb3nQUIx0QnSTTiWqnJkc6uY27o6ZDDHXwvgE18L6gGehwNE/otU9w8ReyRuAOkLYWYDoRYDodCNMpUdUB0yGGOojp3N7CdHajzXQMqUOdVNOJs5jOVKYDyE0H6ibVdF470wHTOchM57uP6WC9g1K4KEXn4jbXqmE9p2HhSgddJ7A/omUC/8eHTxZGlWPTlZ38frgg1PRUR7a9Bvy6mU7qUAe6R2Y6jsV05jrTaY90fq3phIcJTQeeJDMdg9p09KIDpiMf6QTPscGgNCcUTkGaDi46/TynESFZJ8BsBzOdsMCGULiDMh2oa8p0AHZ9TW86wOtNR68605vOfjGdYUxnM7zpPO2cV8904G9nuunwuMaZwHT0Ix3fNfqZjmRZGkD3pWEGElRhKNFp5Eg3p6FyqLVpWGBDa8dXbxfedHJCdcxBDHXKRNPJXj7Tocom3XTSZzrwinifbDqndzSdDZ305bX5ba8N/WU6/rWZdHdNYTpM6WRDmU5pD7x2ahtypoOLDjXSqe4HPdOxB5AoOo0KpepcnOrEhAU2pHoKf9Eznbh26lA86FDnz5tOeJjMdGB9TWo6+8V0FtNJNh296EDxyHpHbjr2lACKM4rp1CWzu4bZDi86ABQObjp6z2nUyFQHuECQRQLSdHByc41lOsDN5hGp6dBslTOdkDnOdHjTAeAVMcViOr/cdPaKmc5sTWedYDrM+xFk5PIaKzpgOuTyWo2+H4FmpANUKMgn2GjR4T2n6YNOdQyU6XjNiQDTiUWnFc50YKjTz3SAbOam85KZjmyos8x0FtPpub02d9M5AIzpJCyvQeGkmk4BGdJ0tJ7T9ET5hjhQim1gREW+EU5FbBIoTKd0p6sdpHgY0wEyk1TTkc90Qt2Yh/nNdFzVaE1nv5jOHzOd/aimc3zNTIcrHv07r2UG7p3XeNPxQUzHHthEhx7pQO9IRjoXGIIYUkWn6Y/YdS7uZExHqDpt04lg9tfQxnFnpDu3iGwQ09nOfKYTnjgW01lMp+dMZ6amszXxlcMDC0ESoHjI2uFNh6bmTEc/0qFNJ110mhQUG2wQxHTsgVUOrTpE59TMV+rU5hrbdDKx6Rx405l8pgN1cxR0ztuZzurNTCcWnXTTucNUzWtMZz256dzUpoONdLDWyV1ycqRTyHfXYHHNHPxEBzxHXzk/d3q1Dk4sOuFGvQEbrTpQ2bzplBLTsaSYTvbLZzrdf+a86FjmaDrnBNPhVOdtTedjWNPZzdV0tgrTcRnddEob3nSw3olUp2hFIjqA2zIeQHTIuolIdJ12HyKi406MAiUXmE6eYDqgOjMwnR4zncV0FtOZ3HR40dF/N53jLGc6Bx9+kyAbzHTY5TVzyE2nMBfWOiLTaaMXHb5x+N5JUB0A1qYVpkOvTdsoZzohbUYyHcM4pjPMUOf3z3RUpgNZTGcK09n5mwyom2lMZz3WTAcap9fyGms6NhF5jVVOf9O5EKaT6jk/gLB3hlEdc9CqU1Hf3SCmJjrHndTeNCAY6khMh2b8mU76F+q81fbaf/bOcDdtIAjCEJcWtcKkMqJK3/9B48vGGsR5fLt4fZzNzcIB6q+2SkYfs7v39hzSgYFthXQOC5DO8KZM0gllGNM52cd0oETzWiz5JegT6eCy0LmgY7AcSOs6DqSTQh1+hSib1GFfrslhD3U46XCZM529uXttv0rSuUGdlyKd3WZIR8s6ofKvXoPj5M90QDo/FyGdC72rOjwcIh2k7lrS8fEcbjt61LlS1OGkA2kmdS6oWOI5F7aTQNu+VirpKEKdmunEHlRJJzPpBGUgHYAOrjXwJx1D89rJPqYDJZrXCOlMRDok00mRztiUzgzQ+VDKzjrwnUnSkTKSTiy+fU3+m55LOk2jNhxkOm6DOgV3r+lCHVgOZR15WR/pQG6k86c80vkhlXf1Gn4+fDOdRk86UrbmNXjNo6RDLCdFOmTBNCEdOA7k5TmQHXX4smn5izDS4ZM68i9n3L4WKhYMJwvpSCWMZ0+615SDOlslnd/upNOfzyedcDiTjvhvgaQjp+vqtfWSjlfzmoF0zvKkoENJh4POVQk6xHIcXWcUdNiu6VCmUKcNT+2kDgwn3b5mH9Rxz3TgO7a7Q7NnOqj0mulSSSccRZDOr9chHVv3mj/p+Gc6/qRjb14zkc6ZkU4o4joUdGLU0XqOv+tI3YqEOuHgu3BitSAd7U6Cdzn4oA5HnfyZjnhN8ZnOl1ZPOrtKOuV2rx3zkU5zf59OcaSD79nSYzptqPHmtbM8rPsIhkH+UdIxgQ48x9911NfqDF8XQkrSCQWlSeeSIJ17KUnHP9PZ35BOUFNiprMN0tm9VdKZchxX0oH3FEo6RWY6fqRz7gukY5rS4YnOiPHM8Jz/IpXrWFew3YmTDr9UB9JuX3unoY4H6Zx8Mx2QztMynaPKcyrpFEs6A+iURjqHQknn62j8SOeEgmaN6RC/4Y7DScfWu8Yjne4h0KF+8xGKGc9DqDNJOt0o6lDSaVEW0jEM6tRMR/H1WiWdlZNOwnH8M52SSQdfMrhmOt+/HJYa0wlFNq/xTMcQ6XSTpEMiHaPnDH4D6xmzHSXqTJIOMp2gTr+T4IxQx7JnOtTsQR1mPL6ZTjO4zSOZTiWdSjrqMZ28pNOr2EwnPBxJB6jjQDok0rGSzvmGdFr1PoIgEumQa3SMnhNs5h51wmF3HXKBKCUd7aJpbMLh29fooI77SoLl5nTktWY6lXTuSOetQNI5JEkH/dLFdq8ZSacpm3TaFOmkI51OipIOGqaNoBNTToQ68mHSdTShTrR/DVLuJIB4+9pg9JR0XAd1/DMdTOnkz3SAOmnjOXh0r0GVdBSggwO1LtIpuXttMdI52UmHX6ajJR0ypiOlyXQgPqVDSMfmOaFi1PmmHSvqqEgnopw06bR0UAekk2tQxz/TAej4Zzoq1LGTDlclHQ/SgfmsnXR6FTyns1SmMwU6zqTDN69BadJhtMNJJw06nHMo6cjHGajDSOevnL06jjqGlQTjtxu8F0I6QBzV0k/xG3Omk4d0xHEq6eQjnd1LkM7xVUjnX18+mQ7fMc1Jp9XvI+CRDlm7pjcduEsEOvhocZ1rJB7q0J0E+kEdgM6DpAMtSjrNQqSz97o6VE06vSrpVNLRks7WuteaDKQDqzGN6bTJTMdlH8F1TDbPgW7f3xmRGXWSoQ4ynS7Zvga1ECMd4jwFkI68UMeZk+kE7eeRzrGSTpmks4FM50uVdEA6/veGpknHemto5xnpRG1rQ43pg6COKdSxk044TIM6F75nugzSWSjTwZu5pFMznUo6WySd/UozHRfSgdSkAzlEOtRzuPCHpu/XpDSkY9y+xgd1wvPiQDpAHW/SQekznayDOsfavfbJ3r3uOA0DUQDGsCCKtE1NCijv/6LEcrOHkkydUzuJPZ0xynL7gcRl+PaMJ3VKxzKdDOm4gtLB2U06/HtDz4x0fEo66UiHhw6cs1z4YaLpkNJBcRd1ykoHtZF0kuXCF0E6eRd1TDomnQqm10jo5EsnntLSCY+apXM9E5kOhtcWkUNIh4CO7BzUfHKalQ7OLNMhpNNx0klf1Ckqnfcs6bj4IDId4qKOZTpNS6fxTIe+pmPS4Vev8dJBJfYR9AWkI62+SVknc35tDp0oHe97XjoIdXjpgDr7SodYvUZJB0csm14z6TwjnVMp6dCRTqw6pTOeCqSDazord0yXk07G7BoBnXmsUyLU8Q+l48mVBKukg4YTP+wqnbEeRToO1MF/w2rMdEw66jMdQCctHUAnMb7GvjjUpCPNTvPSCV86cnotPOVIB5UBHZY6+aEOMp0l6sgrCeSuEw4pnXgypPNeRDru4yuW6Zh0tEmHHF671Vul0tko0/m1hXTQddB2yLfpFIt0AJ0jpIPyk3WIlQQoXjqoA6QTHinr4H068dSY6dj0mvpMp7B0onb2kQ56TUPSIV6nU146XpZOqUiHhg5+VirU4aWT90YdSTr8SoLtpRNO+JK0jqs/0zHpmHRo6YxVVDo0dPKlg87TkHSQ6aDtEG/TKSsdHjpJ6vDb1zxu6jDja+ulc2lJOnh/oWU6Jh1dmY5Jh5IOv3oN0hmfGdKBc7aRDqBDS2c4RjpROFPbUSWdqVz9mY5Nr5l02Hs61PRazdL5oi/TKSed8pHO+IUKdQpkOn5ZOhozHfcvdVzNmY5JxzIdXjrrp9e+ty2d920zHVk657LS6alrOkSkA+iw82vZF3UgHW4lgbh8rX3pOMt0TDoapTP+YVEjnbYzHWb1Wh9PUenEPkJV2fE1T0+vyXumY49vPdOZpBP+HtSb6dj0mmU6nHTi06RTNtPhpRMaEC0df4x0YJ38izr5mQ6Qo0s6DnPTlWc6Jh2TzhPS+apCOm1nOuul0+uUDqbXyEzn3C03nIYzHXcHnS+W6Zh0tGU6Jp22Mh2/TaYTCVOrdMJDko7OTOdOOq7eTMem10w6/JZpJdJ5lUxnU+kMDWY6gnSavqfjQJ2bdGrNdEw6lumYdCzTaVo6vlCmc21XOi4+LdMx6WiUjqbptVfJdLadXht2lQ55T4ebXms300HzcZN0XK2Zjk2vWabDT6/ZPZ3jM53ufPg9nWG3ezr9440Er35Px/33dHZPx6Rj0qlTOpbp7LiRgF8zfd925tDxT+9e03dP5256zTIdk45lOq1K5/jda+driUzHI9PZffcaqJOxe60vu3tN5T2d/6fX6s10bHrNpPOy02uvkukg+jhoy/QgRDqpLdOoxO41UjraMh13P71m93RMOroyHZNOFe/TEdpOeoogXzo8dbIjnf65N4e+SKYz273mLNMx6SiSDpvp1P3m0LKZDurQTGep9Rz65tAh482hcqbj++13r13akM58B47tXjPpKMp09ptec2g2DUkH1JEynVzp4LYJPb6WLx2eOoAOLZ309Jpvfvfat9LTa/W/T8ek8yLS+bFaOqfUy6rDUSKdsRqSDkroOJ1nxtcgnYLU4aHDS2e+e82vks55kk7XdqbzeIrA3qdj0jk60zlNJ186iHT2yXQ0SgeVJR1++Zo8vcaGOiR1BgI6TKbjRel00+F3r93XJSGd+Ht6uHRCuX8/2O41k44q6YQi1kzXLZ06Mh10nnSmEz/mSwfU6YlQR6LOkHBO+Eh8di06h5heIyKdRelMxklKBw0nfqxDOu72nKAD59SY6Zh01Gc6ZaWDk4JOPCYdOdPBRZ0DMh1Qh5LOnDrTkVoOnMN8dm1+M1SWzlMLCUJpks5H97FMx6SjTjpv4UlI561m6YRqRzoodvkaKR2q6wA0LHRk6cypA+hkSueMoqSDSoQ6f56UDoqSjtxtaOk4qefY9FrT0lGQ6XzVI5344ahMJy2da2amg44jhTrhzKxDUedDOoMQ5xDQAXUY6fTPSEdFpnP7tsMQAT+9hiNDx6Rj0jlcOuNRk+lULZ1l6nRPLV9bSx3p82sydfB5tBly4BwCOvEXsVY6npVOR2Y6FzQeNJzKpCNMr5XJdL5bptO0dFRkOmPpkA5mpstKh1++Jk1My9KRl691857jPRHqjE+KOpAO+s7tu6ZDQef3auk8vKYzLyHPkaUToVONdBLthpAOObxm02smneOkg86jI9PJkA5qM+mEB5npROhkSecnQ51YE3XiR7xoJ+EcNJ2kdHpBOvEsVedJ6Yj3dC58poMqJx0ccVx6os6knXXQMekol46CTOd2HlY70iEyHYk6W2Q601VFmTrE0DQynXSo85MYJUDBNcLcGtF0Jm6lVq/J7UaWznSWOs9Vks6lPulEos/aDqQz9R1meM0yHaXS+fS5Wumc1mY6Y+m5p/NlS+mgEAMkVxLImQ7+vZSoI0jHP5QO2g6kQ1IHsBlwwBwOOrHjpKTjIR0JOl5YSLAoHWH3mnBNZ2fpxBYjSAd9B9KJhx1es+k1VdJBi1w4Jh3l0rmg9axcSRCxI62ZxkWdpZbTyTsJ/EKmsyQdvuvcJzroP1TPwcD0Sun01PAapDOva1PSwVfRbw7OdNBwEj1nhXROq6Xzw6Tzt72zUW4aBoJwHVNDKSUJkIb3f1Kqqu6S0a2lrWRVTrRqHRhm+B1YvuzdKpl07gqQDrQ26UA3m+nAfVYmHWhxek0nHQY6/nDSgekQ14EC0sE3wXPiic4vK9IxhwmOR314jQxLz6STWL2mkc5TNulcnmjLtFOtTAfmk0A6cJwypPP9oZNOUdLBiaBOc9Nrn0Y6/iE1EoxJVjNJpBO4ToR0rFAHpGN4jp7p/A5vNwDoBNJcByJT0gLoOMuzuj4F0Ik3r8F5COlE13RO/pws2wlBJ5t0RiPTwQucB6SjZzqVSMerk04nnVTS2cSeziA0EjRCOniPTbhRh0ywEVHSsVBHcx0uHXSAOZx0EOn4X1YN0rF0gu3ESSeQSDojzXQGPEE61TOdTjqddFZsJGg70xkHXNwrkA7RJ5KOO38k0vHZeYg6MxBYpOMegRbfYIOKew5f0uGk46R2TNNMR4x0DhVIh2Y6U+A79TMdgA5IJ6Ke6Vw76eCPogzpbKJ77fVsKtM5LJIOcR1iOwLn2KTjSWMF1/lLPSdeR2CSzpGTzl4lHaFjGn+WxHIU0plyMh3eSOA/65dMR23n/k2ddDrpXMH02tAI6ZwjpEMXdQ6pPdNyEY7nHMN6PEOEoOOO4Dqy53DQoaRjoo7QMU1IB65TiHTOVTId0kZQIdPRSUdf03mYTyedTjpvaj7TeTmbynQOWqaDIhyW6exTSecZnQTCLAFU1HP4ko77MNs+BdL5iS2dvRHpkC0dMrxWgXRopgNN9vRaxT0dnXS842yedO6ul3R2jZJOkek1KGo2P1YknfzyNYl08u8OfTceHupYnmOGOibp/IqjDqRYTtxzyJIOC3U+2EfAbquG1iadKTvTCQTa8W7TZqbj/aYu6TwWJB2cTjoVM53sPR0ddfAeQJOZTog6vAPnlN2+tqekg1Bnn5rqeITgqMNdByrnOd7tAs3uCF2MRrA+AqV5zX0q94Z+ZqYTq14b32fXxhYznfqk81iedHafTDpfb4x0/GsV0hl+rE46uZUEMukod4diP9R8k21POgn29PZQkuoQ1Im4DiRaDvccJyvRsUhncUuH9xHgdzDMdC51aId0RoNzJrsEx52e6cik41876bRMOnL3WoVQJzfT0VGHkw7pmfbP/Bt1KOnAdizWIbEOQZ2460CS43DPMVEn9BwQTnrF9M9l0hE7pk/uM5V0ngTS4ZFOYh/BOIJ0msx0XtUQ6ew00rlrItO5NdJRptfmLxUaX6uf6TzhSKRDe6ZTx9fmkIH3TNuNBOzCak46AurAdQzZjiN4ju03ZqAD5xEjHb15DYYT2I7lOeQCt6Kkw3Z0QDopXjOf+MWhTZPO+z9wnXSul3RmiZnOlyZJZ9oq6fg31+imzp65TigPEibrUNehCgxH8pxni3NgO2aio0U6znGEPgJ+b6izHJN0ziuRzkRIBwpIJzHSGaKRznVnOirp9EynDukAdHC2TDpjeqazNunw8TWJdKB5TSW2qQPxATbddSDBc0A6BHRYogPLSYl0YDlixzQnHX8ySGdKIx3vOax6bTAzHZF0uL41Pb1WinR2Ium8vXTSIaTjVYB04DxCplObdPyjtUwHTfgHeVPH0H4+lkzS8ZbDSAeoc+k8RIU8h3cRQHQvlFxrsBzp+MVaTjrxNR1YjqkzVJB0xiXSgfVkkc7QSadnOmVI5wGnFOm8qmHSwX/4km7UySedpzjpHCjo8MtDo5s6LNQhl+pYqQ5yHYN13JOpvOe4H9EAHUY6ZIoAjkNm1/Z2xfRHSYdEOuuSDr6KTOeSdAaBdMpcp7P1TEcjnSTz+dpJpzDptJjpDPCcJBXKdNypQDpAnI+TzpFNr/kTbcOBilkOPMeS4TgYijDnCCJbOu4jcUvnwCId2A0ZXtNJB5IyHZhNtUyHm0+fXmPu00nHdBynrWc689+zJNLBGdcgnTOPdLzz5LSvIdNht4cad+pQ0nlmqONfqMp4DvIcBjp0SUcnncXmtVB0eA3ukzK8lk06Y5DpMA3uVMt0dNK5vyXSeUecTjqcdNyHeySpxUyHkE7ZToLKpAPUIcUEhjjpAHUC3GGkw5VlOfwWHX6DG0gHPkpIh2zp8EgnbF4LSAeSSAeesw7pDCP8BsbjPitmOmmkA8cpQzrfO+lcPencZ5BOlfI1dyTSGfPvDnWfoTjpnEzD4Z0EfH7N9Bt2fShIJ9zV8YdIth3dcuydUHeYjpx0FkDHPdJuDYXxaKRDLEcgHe45wfAacR51eq1E9Vo66dxfx/TazZPOYwXSyc50apWvNUE6JurAd5IvD13a1BFJB65DZKGOP0sSLIdr/sFSQOfoj1aBA+MhkQ7NdNRIx7adcxbpjAmZDgwHLdMC6WRXr61KOg+ddLJI5w5GiUNJR7hQpx7peFUhneFHFunUuVEnaVEH763511TSoaGOO2aoc5zPpcAGRqrjj8Q6UK7lvFmb5TZEgBxT1HCgCOmgek0dXoNSSGdSSYdfG4rhNXF6rUj1mjq9lgY6nXTKkk6tUOfTSQeZTpFQp8lM5+VDIh0e6hxS59cww8Yv1VFIB95DWYdLcBxDz0zzzyiVdNCAcwwsB6CT3kdwoFs6nHTcSSed6akA6VxWTIukgyxnqEI6ToHlUPPppFONdIA6TZJOvUxHX9TBdqiY6ehmA51TxtdAOsRw0jd14D401eGZDk912ASbe41LNBzomYAOR50Z14h4HYF/MSIdkXS486SBzpRNOiHogHTEjukY6nzrpHNjpLNrj3S06TWf6lQkHf+USGeUSSduO4uXG2R3EiASVy/VeREHHX9oH05cgt+Q7hvI2guFZ/IKHCY6Lu0+I6STvqVDanCIVNKx56ZxTzVIZ1BJh5tO+UynKum8Gc4tks6dRDpAnbZI58t/pz3SwYaCe5a+UYeGOu6EIkPThuX8kW8Pxci0reNiEw5LdaxlHVjPSrJHCFBDmtgvDfHeNV4xzTIdIdIRSAeoI5BOUDJtaLg4ycNrcqSTP71WjHSSQOd7MdIB52yAdFw/3NWQzgzIaaRTO9PxZ41Mh6MOG18zfWeJdMh+aBDqzA8W6pCqadjNYt00BEtYyXVgOKR0jezouFd9ds190C0dw3b0SAecU450grs4rMk1oI7UR4B31oYbJZ3d4zWTjmccZztbJx3h7tC6mQ6AJ5V0vLJJxwh14qQD0OGk4w8NdXxAboU67AZRJzPV8Q8KOuu4zvzdW4FOhHSY9pBJOlakI5IOnCcz05mSSYdHOkh1COPESadE9ZrWSNAi6TDQCf6tXpF0/gGEHoDM7PXYxAAAAABJRU5ErkJggg==");margin-top:40px;min-height:40px}.dpw-footer a{color:#fff;text-decoration:none}.dpw-footer a:hover{text-decoration:underline}.dpw-footer-inner{color:#fff;font-size:11px;margin:0 auto;max-width:1600px;padding-bottom:40px;padding-top:20px}.dpw-footer ul{margin:0;padding:0}.dpw-footer ul li{list-style:none}.dpw-four-cols .dpw-col{display:inline-block;vertical-align:top;width:24%}.dpw-cookie-main{background-color:#fff;border:1px solid gray;bottom:10px;font-family:Open Sans,sans-serif;font-size:12px;max-width:400px;padding:10px;right:10px}.dpw-cookie-main-buttons{margin-top:10px;text-align:right}.dpw-cookie-main-ok{background-color:#333;color:#fff;display:inline-block;padding:5px 15px;text-decoration:none}.dpw-no-sidebar .dpw-body-inner,.dpw-no-sidebar .dpw-footer-inner,.dpw-no-sidebar .dpw-header-inner,.dpw-no-sidebar .dpw-subheader-inner,.dpw-no-sidebar .dpw-title-inner{max-width:1600px}.dpw-body-inner,.dpw-footer-inner,.dpw-header-inner,.dpw-subheader-inner,.dpw-title-inner{box-sizing:border-box;padding-left:5px;padding-right:5px}.dpw-no-sidebar .dpw-sidebar{display:none}.dpw-no-sidebar .dpw-main{display:block;max-width:none}.dpw-no-sidebar .dpw-body-inner{margin-left:auto;margin-right:auto}.dpw-sidebar-right .dpw-body{flex-grow:1;order:1}.dpw-sidebar-right .dpw-sidebar{margin-left:10px;order:2;width:220px}.dpw-sidebar-left .dpw-body{flex-grow:1}.dpw-sidebar-left .dpw-sidebar{margin-right:10px;width:220px}.dpw-sidebar-left h1,.dpw-sidebar-left h2,.dpw-sidebar-left h3,.dpw-sidebar-left h4,.dpw-sidebar-left table{clear:none}.dpw-sidebar-bottom .dpw-body-inner,.dpw-sidebar-bottom .dpw-footer-inner,.dpw-sidebar-bottom .dpw-header-inner,.dpw-sidebar-bottom .dpw-subheader-inner,.dpw-sidebar-bottom .dpw-title-inner{max-width:870px}.dpw-sidebar-bottom .dpw-main{display:block;max-width:none}.dpw-sidebar-bottom .dpw-body-inner,.dpw-sidebar-bottom .dpw-sidebar{margin-left:auto;margin-right:auto}.dpw-sidebar-bottom .dpw-sidebar{max-width:870px}.dpw-sidebar img{height:auto;max-width:100%}a.dpw-button-action{color:#fff;text-decoration:none}.dpw-button-action{background-color:#3c78d8;border:1px solid #15c;border-radius:2px;color:#fff;cursor:pointer;padding:6px 20px}.dpw-button-action.disabled{background-color:#a7c1ed;border:1px solid #759ee3;cursor:not-allowed}.dp-menu{box-sizing:border-box;font-size:13px;padding:2px}.dp-menu ul{background:-webkit-gradient(linear,left top,right top,from(#fff),to(#f9f9f9));background:-webkit-linear-gradient(left,#fff,#f9f9f9);background:-moz-linear-gradient(left,#fff 0,#f9f9f9);background:-ms-linear-gradient(left,#fff 0,#f9f9f9);background:-o-linear-gradient(left,#fff 0,#f9f9f9);background:linear-gradient(left,#fff,#f9f9f9);border:0;filter:progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff",endColorStr="#f9f9f9",GradientType=1);list-style:none;margin:0;padding:0}.dp-menu{margin-bottom:50px}.dp-menu>ul{border-bottom:1px solid #d9d9d9;border-left:1px solid #d9d9d9;border-right:1px solid #d9d9d9}.dp-menu li{xwidth:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.dp-menu ul ul{border-bottom:none;margin-top:0}.dp-menu a,.dp-menu strong{border-top:1px solid #d9d9d9;color:#333;display:block;overflow:hidden;padding:8px 5px;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}.dp-menu a:hover{xtext-decoration:underline}.dp-menu a.active{xfont-weight:bold;background:#002449;color:#fff}.dp-menu li li a{padding-left:20px}.dp-menu li li li a{padding-left:35px}.dp-menu li li li li a{padding-left:50px}.dp-menu li li li li li a{padding-left:65px}#content{max-width:1360px}.button-source{background-color:#f3f3f3;border:1px solid silver;border-radius:2px;color:#333;cursor:pointer;margin-right:5px;padding:8px 16px}.toolbar .dpw-header-item:first-child{font-weight:700}.space{margin:10px 0}.note{margin-bottom:10px;margin-top:10px}.new{background-color:#87ab13;border-radius:2px;color:#fff;display:inline-block;font-size:8px;margin-right:3px;padding:2px;position:relative;top:-1px}.download a:not(.inline-btn){color:#00639e}.search{padding:2px}.search-box{position:relative}.search input[type=text]{border:1px solid #ccc;border-radius:2px;box-sizing:border-box;margin-right:2px;padding:5px 20px 5px 5px;width:180px;width:100%}.search input::-ms-clear{display:none}.search-box button{background-color:transparent;border:1px solid transparent;border-radius:2px;color:#666;cursor:pointer;outline:none;padding:5px 7px;position:absolute;right:0;top:0}.list-front{margin-top:20px;position:relative}.list-front div{display:inline-block;margin-bottom:20px;vertical-align:top;width:290px}.list-front a img{border:0;box-shadow:0 0 5px rgba(0,0,0,.2)}.img-link{display:inline-block;overflow:hidden;position:relative;transition:opacity .3s ease-in-out}.img-link .banner{background:linear-gradient(90deg,rgba(36,37,42,.8),rgba(64,67,77,.8));border-radius:25px;bottom:50px;box-sizing:border-box;color:#fff;font-size:20px;font-weight:700;left:50px;padding:10px;position:absolute;right:50px;text-align:center;text-shadow:2px 2px 4px rgba(0,0,0,.2);transform:translateY(20%);transition:all .3s ease-in-out;visibility:hidden}.img-link:hover .banner{transform:translateY(0);visibility:visible}a.img-link{color:#fff;opacity:.7;text-decoration:none}a.img-link:hover{opacity:1}@media (-ms-high-contrast:none){template{opacity:0}.placeholder template{opacity:1}}@media screen and (max-width:1000px){.dpw-sidebar-right .dpw-body-inner{margin-right:0}.dpw-sidebar-right .dpw-sidebar{box-sizing:border-box;-moz-box-sizing:border-box;float:left;margin-left:0;width:100%}.dpw-sidebar-left .dpw-main{display:flex;flex-direction:column}.dpw-sidebar-left .dpw-body{margin-left:0;order:1}.dpw-sidebar-left .dpw-sidebar{box-sizing:border-box;-moz-box-sizing:border-box;margin-left:0;margin-top:20px;order:2;width:100%}}@media screen and (max-width:600px){.dpw-header-search input[type=text]{max-width:100px}.dpw-four-cols .dpw-col{width:49%}.breadcrumbs-segment,.breadcrumbs-segment-this,.breadcrumbs-separator{display:none}.breadcrumbs-segment-last:before,.breadcrumbs-segment.breadcrumbs-segment-last{display:inline-block;font-size:14px}.breadcrumbs-segment-last:before{content:"\ab";margin-right:5px}}@media screen and (max-width:400px){.dpw-four-cols .dpw-col{width:99%}}.dpw-body h2.title{padding-top:0}.dp-menu li{position:relative}.dp-menu a,.dp-menu a:after{transition:opacity .15s ease-in-out}.dp-menu a:after{background-color:#cccccc33;bottom:0;content:"";left:0;opacity:0;position:absolute;right:0;top:0}.dp-menu a:hover:after{opacity:1}.dp-menu a.active:hover:after{opacity:0}.dpw-body code{background:rgba(0,0,0,.1);border-radius:5px;color:rgba(0,0,0,.8);font-family:monospace;font-size:.8rem;font-style:normal;font-weight:700;padding:.2rem .4rem}@media screen and (min-width:1001px){.dp-menu{margin-bottom:0;max-height:calc(100vh - 284px)}.dp-menu,.dpw-body{overflow-y:auto;scrollbar-width:thin}.dpw-body{max-height:calc(100vh - 250px)}.dp-menu::-webkit-scrollbar,.dpw-body::-webkit-scrollbar{width:8px}.dp-menu::-webkit-scrollbar-track,.dpw-body::-webkit-scrollbar-track{background:none}.dp-menu::-webkit-scrollbar-thumb,.dpw-body::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.2);border-radius:4px}.dp-menu::-webkit-scrollbar-thumb:hover,.dpw-body::-webkit-scrollbar-thumb:hover{background-color:rgba(0,0,0,.4)}.dpw-footer{margin-top:5px}.dpw-sidebar.menu .search{padding-right:10px}@supports (-moz-appearance:none){.dp-menu,.dpw-sidebar.menu .search{padding-right:8px}}@media (pointer:coarse){.dpw-sidebar.menu .search{padding-right:2px}}.dp-menu,.dpw-sidebar.menu{position:relative}.dpw-sidebar.menu:after,.dpw-sidebar.menu:before{background:linear-gradient(180deg,#ffffffbb,transparent);content:"";height:40px;left:0;margin-right:10px;pointer-events:none;position:absolute;right:0;z-index:2}.dpw-sidebar.menu:before{top:35px}.dpw-sidebar.menu:after{background:linear-gradient(0deg,#ffffffbb,transparent);bottom:0}.dpw-sidebar.menu.no-gradient-bottom:after,.dpw-sidebar.menu.no-gradient-top:before{display:none}}.note{align-items:center;background-color:#f9f9f9;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.1);color:#333;font-size:14px;margin:20px 0;padding:12px 20px 12px 55px;position:relative}.note:after{border:3px solid #666;border-radius:50%;box-sizing:border-box;color:#666;content:"i";font-size:18px;font-weight:700;height:30px;justify-content:center;left:15px;position:absolute;top:50%;transform:translateY(-50%);width:30px}.note:after,.tools{align-items:center;display:flex}.tools{background-color:#f9f9f9;border:1px solid #e0e0e0;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.1);flex-wrap:wrap;justify-content:start;margin:20px 0;padding:10px 20px}.tools a,.tools button{background-color:#e0e0e0;border:none;border-radius:15px;color:#333;cursor:pointer;margin:0 10px;outline:none;padding:5px 15px;text-decoration:none;transition:all .3s}.tools a:hover,.tools button:hover{background-color:#007bff;color:#fff}.tools button{background-color:#666;color:#fff;padding:7px 17px}.tools select{background-color:#fff;border:1px solid #e0e0e0;border-radius:15px;cursor:pointer;margin:0 10px;outline:none;padding:5px 15px;transition:border-color .3s}.tools select:focus{border-color:#007bff}.tools select option{padding:5px 10px}.tools label{align-items:center;cursor:pointer;display:flex;margin:0 10px}.tools input[type=radio]{margin-bottom:4px;margin-right:5px}.tools input[type=checkbox]{margin-right:5px}.tools input[type=text]{border:1px solid #e0e0e0;border-radius:15px;margin:0 10px;outline:none;padding:5px 10px;transition:border-color .3s}.tools input[type=text]:focus{border-color:#007bff} \ No newline at end of file diff --git a/static/src/helpers/v2/reporter.js b/static/src/helpers/v2/reporter.js new file mode 100644 index 0000000..41d3cff --- /dev/null +++ b/static/src/helpers/v2/reporter.js @@ -0,0 +1 @@ +(new(function(){function n(){}return n.prototype.init=function(){this.t(5),this.i(5)},n.prototype.send=function(n,t,i){try{var o=new XMLHttpRequest;o.open("POST","https://log.daypilot.org/api/v1/message/error",!0);var r=JSON.stringify({key:"3-m81KH05IiFxaf4ZdDy1n_4AOsK_Ub9k9Lc_A6AnGRoynqRNwd0WRUiYhXh74UOppGhK5vs3LqvtLsdDhUe8A",message:n,filename:t,stacktrace:i,url:document.location.href});o.send(r)}catch(n){}},n.prototype.i=function(n){var t=this,i=0;document.addEventListener("DOMContentLoaded",(function(){Array.apply(null,document.querySelectorAll("img")).forEach((function(o){o.addEventListener("error",(function(r){if(!(i>=n)){i+=1;var e=o.src;t.send("error loading image",e,o.outerHTML)}}))}))}))},n.prototype.t=function(n){var t=this,i=0;window.onerror=function(o,r,e,c,a){try{if(i>=n)return;i+=1,window.setTimeout((function(){t.send(o,r,a?a.stack:"")}),100)}catch(n){}}},n}())).init(); \ No newline at end of file diff --git a/static/src/img/calendar.png b/static/src/img/calendar.png new file mode 100644 index 0000000..b67ffd8 Binary files /dev/null and b/static/src/img/calendar.png differ diff --git a/static/src/img/calendar_rf.png b/static/src/img/calendar_rf.png new file mode 100644 index 0000000..d9e8997 Binary files /dev/null and b/static/src/img/calendar_rf.png differ diff --git a/static/src/img/conv30.png b/static/src/img/conv30.png new file mode 100644 index 0000000..a50f61f Binary files /dev/null and b/static/src/img/conv30.png differ diff --git a/static/src/img/conv40.png b/static/src/img/conv40.png new file mode 100644 index 0000000..2fe31a5 Binary files /dev/null and b/static/src/img/conv40.png differ diff --git a/static/src/img/conv50.png b/static/src/img/conv50.png new file mode 100644 index 0000000..cbab98b Binary files /dev/null and b/static/src/img/conv50.png differ diff --git a/static/src/img/heart30.png b/static/src/img/heart30.png new file mode 100644 index 0000000..c6067a7 Binary files /dev/null and b/static/src/img/heart30.png differ diff --git a/static/src/img/heart40.png b/static/src/img/heart40.png new file mode 100644 index 0000000..e79ba0a Binary files /dev/null and b/static/src/img/heart40.png differ diff --git a/static/src/img/heart50.png b/static/src/img/heart50.png new file mode 100644 index 0000000..26c2252 Binary files /dev/null and b/static/src/img/heart50.png differ diff --git a/static/src/img/img_107_b.jpg b/static/src/img/img_107_b.jpg new file mode 100644 index 0000000..4bbf0ec Binary files /dev/null and b/static/src/img/img_107_b.jpg differ diff --git a/static/src/img/img_108_b.jpg b/static/src/img/img_108_b.jpg new file mode 100644 index 0000000..ec64b07 Binary files /dev/null and b/static/src/img/img_108_b.jpg differ diff --git a/static/src/img/img_113_b.jpg b/static/src/img/img_113_b.jpg new file mode 100644 index 0000000..46c9453 Binary files /dev/null and b/static/src/img/img_113_b.jpg differ diff --git a/static/src/img/img_115_b.jpg b/static/src/img/img_115_b.jpg new file mode 100644 index 0000000..8cd72fb Binary files /dev/null and b/static/src/img/img_115_b.jpg differ diff --git a/static/src/img/img_117_b.jpg b/static/src/img/img_117_b.jpg new file mode 100644 index 0000000..abfbb6a Binary files /dev/null and b/static/src/img/img_117_b.jpg differ diff --git a/static/src/img/img_119_b.jpg b/static/src/img/img_119_b.jpg new file mode 100644 index 0000000..8a4dcd0 Binary files /dev/null and b/static/src/img/img_119_b.jpg differ diff --git a/static/src/img/img_134_b.jpg b/static/src/img/img_134_b.jpg new file mode 100644 index 0000000..8644560 Binary files /dev/null and b/static/src/img/img_134_b.jpg differ diff --git a/static/src/img/img_14_b.jpg b/static/src/img/img_14_b.jpg new file mode 100644 index 0000000..3b86854 Binary files /dev/null and b/static/src/img/img_14_b.jpg differ diff --git a/static/src/img/img_15_b.jpg b/static/src/img/img_15_b.jpg new file mode 100644 index 0000000..8644560 Binary files /dev/null and b/static/src/img/img_15_b.jpg differ diff --git a/static/src/img/img_17_b.jpg b/static/src/img/img_17_b.jpg new file mode 100644 index 0000000..e7e97cc Binary files /dev/null and b/static/src/img/img_17_b.jpg differ diff --git a/static/src/img/img_18_b.jpg b/static/src/img/img_18_b.jpg new file mode 100644 index 0000000..310ebf7 Binary files /dev/null and b/static/src/img/img_18_b.jpg differ diff --git a/static/src/img/img_19_b.jpg b/static/src/img/img_19_b.jpg new file mode 100644 index 0000000..65bb8f5 Binary files /dev/null and b/static/src/img/img_19_b.jpg differ diff --git a/static/src/img/img_21_b.jpg b/static/src/img/img_21_b.jpg new file mode 100644 index 0000000..4b16535 Binary files /dev/null and b/static/src/img/img_21_b.jpg differ diff --git a/static/src/img/img_4_b.jpg b/static/src/img/img_4_b.jpg new file mode 100644 index 0000000..a3dd97c Binary files /dev/null and b/static/src/img/img_4_b.jpg differ diff --git a/static/src/img/img_5_b.jpg b/static/src/img/img_5_b.jpg new file mode 100644 index 0000000..2b50d65 Binary files /dev/null and b/static/src/img/img_5_b.jpg differ diff --git a/static/src/img/img_62_b.jpg b/static/src/img/img_62_b.jpg new file mode 100644 index 0000000..4e4d56b Binary files /dev/null and b/static/src/img/img_62_b.jpg differ diff --git a/static/src/img/img_63_b.jpg b/static/src/img/img_63_b.jpg new file mode 100644 index 0000000..6277cd8 Binary files /dev/null and b/static/src/img/img_63_b.jpg differ diff --git a/static/src/img/img_65_b.jpg b/static/src/img/img_65_b.jpg new file mode 100644 index 0000000..a905ca9 Binary files /dev/null and b/static/src/img/img_65_b.jpg differ diff --git a/static/src/img/img_66_b.jpg b/static/src/img/img_66_b.jpg new file mode 100644 index 0000000..b6b9111 Binary files /dev/null and b/static/src/img/img_66_b.jpg differ diff --git a/static/src/img/img_67_b.jpg b/static/src/img/img_67_b.jpg new file mode 100644 index 0000000..ee826d1 Binary files /dev/null and b/static/src/img/img_67_b.jpg differ diff --git a/static/src/img/img_68_b.jpg b/static/src/img/img_68_b.jpg new file mode 100644 index 0000000..e234596 Binary files /dev/null and b/static/src/img/img_68_b.jpg differ diff --git a/static/src/img/img_69_b.jpg b/static/src/img/img_69_b.jpg new file mode 100644 index 0000000..169f33a Binary files /dev/null and b/static/src/img/img_69_b.jpg differ diff --git a/static/src/img/img_70_b.jpg b/static/src/img/img_70_b.jpg new file mode 100644 index 0000000..132dec1 Binary files /dev/null and b/static/src/img/img_70_b.jpg differ diff --git a/static/src/img/img_71_b.jpg b/static/src/img/img_71_b.jpg new file mode 100644 index 0000000..cefcc0c Binary files /dev/null and b/static/src/img/img_71_b.jpg differ diff --git a/static/src/img/img_72_b.jpg b/static/src/img/img_72_b.jpg new file mode 100644 index 0000000..f543941 Binary files /dev/null and b/static/src/img/img_72_b.jpg differ diff --git a/static/src/img/img_73_b.jpg b/static/src/img/img_73_b.jpg new file mode 100644 index 0000000..a01fbab Binary files /dev/null and b/static/src/img/img_73_b.jpg differ diff --git a/static/src/img/img_74_b.jpg b/static/src/img/img_74_b.jpg new file mode 100644 index 0000000..056424c Binary files /dev/null and b/static/src/img/img_74_b.jpg differ diff --git a/static/src/img/img_76_b.jpg b/static/src/img/img_76_b.jpg new file mode 100644 index 0000000..9fd6786 Binary files /dev/null and b/static/src/img/img_76_b.jpg differ diff --git a/static/src/img/img_77_b.jpg b/static/src/img/img_77_b.jpg new file mode 100644 index 0000000..9ecbed6 Binary files /dev/null and b/static/src/img/img_77_b.jpg differ diff --git a/static/src/img/img_78_b.jpg b/static/src/img/img_78_b.jpg new file mode 100644 index 0000000..ae2c55e Binary files /dev/null and b/static/src/img/img_78_b.jpg differ diff --git a/static/src/img/img_79_b.jpg b/static/src/img/img_79_b.jpg new file mode 100644 index 0000000..75c94fe Binary files /dev/null and b/static/src/img/img_79_b.jpg differ diff --git a/static/src/img/img_81_b.jpg b/static/src/img/img_81_b.jpg new file mode 100644 index 0000000..59a7d26 Binary files /dev/null and b/static/src/img/img_81_b.jpg differ diff --git a/static/src/img/img_83_b.jpg b/static/src/img/img_83_b.jpg new file mode 100644 index 0000000..210958f Binary files /dev/null and b/static/src/img/img_83_b.jpg differ diff --git a/static/src/img/img_84_b.jpg b/static/src/img/img_84_b.jpg new file mode 100644 index 0000000..b70e93a Binary files /dev/null and b/static/src/img/img_84_b.jpg differ diff --git a/static/src/img/img_85_b.jpg b/static/src/img/img_85_b.jpg new file mode 100644 index 0000000..2f41cc2 Binary files /dev/null and b/static/src/img/img_85_b.jpg differ diff --git a/static/src/img/img_86_b.jpg b/static/src/img/img_86_b.jpg new file mode 100644 index 0000000..d4a10fe Binary files /dev/null and b/static/src/img/img_86_b.jpg differ diff --git a/static/src/img/img_87_b.jpg b/static/src/img/img_87_b.jpg new file mode 100644 index 0000000..11c2192 Binary files /dev/null and b/static/src/img/img_87_b.jpg differ diff --git a/static/src/img/img_88_b.jpg b/static/src/img/img_88_b.jpg new file mode 100644 index 0000000..e9f96e5 Binary files /dev/null and b/static/src/img/img_88_b.jpg differ diff --git a/static/src/img/img_90_b.jpg b/static/src/img/img_90_b.jpg new file mode 100644 index 0000000..9c625ae Binary files /dev/null and b/static/src/img/img_90_b.jpg differ diff --git a/static/src/img/img_91_b.jpg b/static/src/img/img_91_b.jpg new file mode 100644 index 0000000..cb4e056 Binary files /dev/null and b/static/src/img/img_91_b.jpg differ diff --git a/static/src/img/img_92_b.jpg b/static/src/img/img_92_b.jpg new file mode 100644 index 0000000..2181263 Binary files /dev/null and b/static/src/img/img_92_b.jpg differ diff --git a/static/src/img/img_93_b.jpg b/static/src/img/img_93_b.jpg new file mode 100644 index 0000000..de31d06 Binary files /dev/null and b/static/src/img/img_93_b.jpg differ diff --git a/static/src/img/img_95_b.jpg b/static/src/img/img_95_b.jpg new file mode 100644 index 0000000..f8881b7 Binary files /dev/null and b/static/src/img/img_95_b.jpg differ diff --git a/static/src/img/img_96_b.jpg b/static/src/img/img_96_b.jpg new file mode 100644 index 0000000..c47aca9 Binary files /dev/null and b/static/src/img/img_96_b.jpg differ diff --git a/static/src/img/img_97_b.jpg b/static/src/img/img_97_b.jpg new file mode 100644 index 0000000..82d8498 Binary files /dev/null and b/static/src/img/img_97_b.jpg differ diff --git a/static/src/img/img_98_b.jpg b/static/src/img/img_98_b.jpg new file mode 100644 index 0000000..6a726c8 Binary files /dev/null and b/static/src/img/img_98_b.jpg differ diff --git a/static/src/img/img_99_b.jpg b/static/src/img/img_99_b.jpg new file mode 100644 index 0000000..08e1dd0 Binary files /dev/null and b/static/src/img/img_99_b.jpg differ diff --git a/static/src/img/m0.png b/static/src/img/m0.png new file mode 100644 index 0000000..329ff52 Binary files /dev/null and b/static/src/img/m0.png differ diff --git a/static/src/img/m1.png b/static/src/img/m1.png new file mode 100644 index 0000000..511fb29 Binary files /dev/null and b/static/src/img/m1.png differ diff --git a/static/src/img/m2.png b/static/src/img/m2.png new file mode 100644 index 0000000..c632633 Binary files /dev/null and b/static/src/img/m2.png differ diff --git a/static/src/img/m3.png b/static/src/img/m3.png new file mode 100644 index 0000000..9f30b30 Binary files /dev/null and b/static/src/img/m3.png differ diff --git a/static/src/img/m4.png b/static/src/img/m4.png new file mode 100644 index 0000000..0d3f826 Binary files /dev/null and b/static/src/img/m4.png differ diff --git a/static/src/img/m5.png b/static/src/img/m5.png new file mode 100644 index 0000000..61387d2 Binary files /dev/null and b/static/src/img/m5.png differ diff --git a/static/src/img/people35.png b/static/src/img/people35.png new file mode 100644 index 0000000..6a5a209 Binary files /dev/null and b/static/src/img/people35.png differ diff --git a/static/src/img/people45.png b/static/src/img/people45.png new file mode 100644 index 0000000..219c62e Binary files /dev/null and b/static/src/img/people45.png differ diff --git a/static/src/img/people55.png b/static/src/img/people55.png new file mode 100644 index 0000000..6e88d1e Binary files /dev/null and b/static/src/img/people55.png differ diff --git a/static/src/img/pin.png b/static/src/img/pin.png new file mode 100644 index 0000000..3f830a3 Binary files /dev/null and b/static/src/img/pin.png differ diff --git a/static/src/img/pin2.png b/static/src/img/pin2.png new file mode 100644 index 0000000..3ed727e Binary files /dev/null and b/static/src/img/pin2.png differ diff --git a/static/src/img/pin_display.png b/static/src/img/pin_display.png new file mode 100644 index 0000000..7c293ce Binary files /dev/null and b/static/src/img/pin_display.png differ diff --git a/static/src/img/pin_display_touch.png b/static/src/img/pin_display_touch.png new file mode 100644 index 0000000..7ce5922 Binary files /dev/null and b/static/src/img/pin_display_touch.png differ diff --git a/static/src/img/pin_led.png b/static/src/img/pin_led.png new file mode 100644 index 0000000..269f3f5 Binary files /dev/null and b/static/src/img/pin_led.png differ diff --git a/static/src/js/daypilot-all.min.d.ts b/static/src/js/daypilot-all.min.d.ts new file mode 100644 index 0000000..bbefd00 --- /dev/null +++ b/static/src/js/daypilot-all.min.d.ts @@ -0,0 +1,1212 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +type GlobalDate = Date; + +export module DayPilot { + + export class CalendarPropsAndEvents { + backendUrl?: string; + businessBeginsHour?: number; + businessEndsHour?: number; + cellHeight?: number; + columnMarginRight?: number; + columnsLoadMethod?: "POST" | "GET"; + contextMenu?: DayPilot.Menu; + days?: number; + doubleClickTimeout?: number; + durationBarVisible?: boolean; + eventClickHandling?: "Enabled" | "Disabled" | "CallBack" | "ContextMenu"; + eventDeleteHandling?: "Update" | "Disabled" | "CallBack"; + eventMoveHandling?: "Update" | "CallBack" | "Disabled"; + eventResizeHandling?: "Update" | "CallBack" | "Disabled"; + eventRightClickHandling?: "ContextMenu" | "Enabled" | "Disabled"; + headerClickHandling?: "Enabled" | "Disabled"; + headerDateFormat?: string; + headerHeight?: number; + headerTextWrappingEnabled?: boolean; + height?: number; + heightSpec?: "BusinessHours" | "BusinessHoursNoScroll" | "Full"; + hideUntilInit?: boolean; + hourWidth?: number; + initScrollPos?: number; + loadingLabelText?: string; + loadingLabelHtml?: string; + loadingLabelVisible?: boolean; + locale?: string; + showToolTip?: boolean; + startDate?: DayPilot.Date | string; + theme?: string; + timeFormat?: "Auto" | "Clock12Hours" | "Clock24Hours"; + timeRangeSelectedHandling?: "Enabled" | "Disabled" | "CallBack"; + viewType?: "Day" | "Days" | "Week" | "WorkWeek" | "Resources"; + visible?: boolean; + weekStarts?: "Auto" | number; + xssProtection?: "Enabled" | "Disabled"; + + onAfterEventRender?: EventHandler; + + onBeforeCellRender?: EventHandler; + onBeforeEventRender?: EventHandler; + onBeforeHeaderRender?: EventHandler; + + onEventClick?: EventHandler; + onEventClicked?: EventHandler; + onEventDelete?: EventHandler; + onEventDeleted?: EventHandler; + onEventMove?: EventHandler; + onEventMoved?: EventHandler; + onEventResize?: EventHandler; + onEventResized?: EventHandler; + onEventRightClick?: EventHandler; + onEventRightClicked?: EventHandler; + onHeaderClick?: EventHandler; + onHeaderClicked?: EventHandler; + onTimeRangeSelect?: EventHandler; + onTimeRangeSelected?: EventHandler; + + } + + export class CalendarConfig extends CalendarPropsAndEvents { + columns?: CalendarColumnData[]; + events?: EventData[]; + } + + export class Calendar extends CalendarPropsAndEvents { + v: string; + columns: { + list: CalendarColumnData[]; + load(url: string, + success: (args: { data: any; preventDefault(): void; }) => void, + error: (args: { request: XMLHttpRequest, exception: any; }) => void + ): void; + }; + events: { + list: EventData[]; + add(e: DayPilot.Event | EventData): void; + find(id: string): DayPilot.Event; + find(filter: (e: DayPilot.Event) => boolean): DayPilot.Event; + load(url: string, + success: (args: { data: any; preventDefault(): void; }) => void, + error: (args: { request: XMLHttpRequest, exception: any; }) => void + ): void; + remove(e: DayPilot.Event): void; + remove(id: EventId): void; + update(e: DayPilot.Event | EventData): void; + }; + + constructor(id: string | HTMLElement, options?: CalendarConfig); + + clearSelection(): void; + + dispose(): void; + + disposed(): boolean; + + getSelection(): DayPilot.Selection; + + hide(): void; + + init(): void; + + show(): void; + + update(options?: CalendarConfig): void; + + visibleStart(): DayPilot.Date; + + visibleEnd(): DayPilot.Date; + + } + + export interface CalendarColumnData { + name: string; + id?: ResourceId; + start?: DayPilot.Date | string; + html?: string; + toolTip?: string; + tags?: any; + } + + export interface CalendarAfterEventRenderArgs { + readonly e: DayPilot.Event; + readonly div: HTMLElement; + } + + export interface CalendarBeforeCellRenderArgs { + readonly cell: { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly resource: ResourceId; + readonly properties: { + html: string; + business: boolean; + backColor: string; + backImage: string; + backRepeat: string; + cssClass: string; + }; + }; + } + + export interface CalendarBeforeEventRenderArgs { + readonly control: DayPilot.Calendar; + readonly data: EventData; + } + + export interface CalendarBeforeHeaderRenderArgs { + readonly header: { + readonly id: ResourceId; + readonly start: DayPilot.Date; + readonly name: string; + readonly children: CalendarColumnData[]; + html: string; + backColor: string; + cssClass?: string; + verticalAlignment?: "top" | "center" | "bottom"; + toolTip: string; + areas: AreaData[]; + }; + readonly column: Column; + } + + export interface CalendarEventClickArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + readonly ctrl: boolean; + readonly meta: boolean; + readonly originalEvent: MouseEvent; + preventDefault(): void; + } + + + export interface CalendarEventClickedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + readonly ctrl: boolean; + readonly meta: boolean; + readonly originalEvent: MouseEvent; + } + + export interface CalendarEventRightClickArgs { + readonly e: DayPilot.Event; + preventDefault(): void; + } + + export interface CalendarEventRightClickedArgs { + readonly e: DayPilot.Event; + } + + export interface CalendarEventDeleteArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + preventDefault(): void; + } + + + export interface CalendarEventDeletedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + } + + + export interface CalendarEventMoveArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + readonly newResource: ResourceId; + readonly ctrl: boolean; + readonly shift: boolean; + + preventDefault(): void; + } + + + export interface CalendarEventMovedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + readonly newResource: ResourceId; + readonly ctrl: boolean; + readonly shift: boolean; + } + + + export interface CalendarEventResizeArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + + preventDefault(): void; + } + + + export interface CalendarEventResizedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Calendar; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + } + + export interface CalendarHeaderClickArgs { + readonly column: Column; + readonly originalEvent: MouseEvent; + readonly shift: boolean; + readonly meta: boolean; + readonly ctrl: boolean; + preventDefault(): void; + } + + export interface CalendarHeaderClickedArgs { + readonly column: Column; + readonly originalEvent: MouseEvent; + readonly shift: boolean; + readonly meta: boolean; + readonly ctrl: boolean; + } + + export interface CalendarTimeRangeSelectArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly resource: ResourceId; + readonly control: DayPilot.Calendar; + preventDefault(): void; + } + + + export interface CalendarTimeRangeSelectedArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly resource: ResourceId; + readonly control: DayPilot.Calendar; + } + + export class Column { + readonly id: ResourceId; + readonly start: DayPilot.Date; + readonly name: string; + readonly data: CalendarColumnData; + } + + export class MonthPropsAndEvents { + backendUrl?: string; + cellHeaderClickHandling?: "Enabled" | "Disabled"; + cellHeaderHeight?: number; + cellHeight?: number; + cellMarginBottom?: number; + contextMenu?: DayPilot.Menu; + eventBarVisible?: boolean; + eventClickHandling?: "Enabled" | "Disabled" | "CallBack" | "ContextMenu"; + eventRightClickHandling?: "ContextMenu" | "Enabled" | "Disabled"; + eventHeight?: number; + eventDeleteHandling?: "Update" | "Disabled"; + eventMoveHandling?: "Update" | "CallBack" | "Notify" | "Disabled"; + eventResizeHandling?: "Update" | "CallBack" | "Notify" | "Disabled"; + headerClickHandling?: "Enabled" | "Disabled" | "CallBack"; + headerHeight?: number; + hideUntilInit?: boolean; + lineSpace?: number; + locale?: string; + showToolTip?: boolean; + startDate?: DayPilot.Date | string; + theme?: string; + timeRangeSelectedHandling?: "Enabled" | "Disabled" | "CallBack"; + visible?: boolean; + weekStarts?: "Auto" | number; + width?: string; + xssProtection?: "Enabled" | "Disabled"; + + onAfterEventRender?: EventHandler; + + onBeforeEventRender?: EventHandler; + onBeforeCellRender?: EventHandler; + + onCellHeaderClick?: EventHandler; + onCellHeaderClicked?: EventHandler; + onEventClick?: EventHandler; + onEventClicked?: EventHandler; + onEventDelete?: EventHandler; + onEventDeleted?: EventHandler; + onEventMove?: EventHandler; + onEventMoved?: EventHandler; + onEventResize?: EventHandler; + onEventResized?: EventHandler; + onEventRightClick?: EventHandler; + onEventRightClicked?: EventHandler; + onTimeRangeSelect?: EventHandler; + onTimeRangeSelected?: EventHandler; + } + + export class MonthConfig extends MonthPropsAndEvents { + events?: EventData[]; + } + + export class Month extends MonthPropsAndEvents { + v: string; + events: { + list: EventData[]; + add(e: DayPilot.Event | EventData): void; + find(id: string): DayPilot.Event; + find(filter: (e: DayPilot.Event) => boolean): DayPilot.Event; + load(url: string, + success: (args: { data: any; preventDefault(): void; }) => void, + error: (args: { request: XMLHttpRequest, exception: any; }) => void + ): void; + remove(e: DayPilot.Event): void; + remove(id: EventId): void; + update(e: DayPilot.Event): void; + }; + + constructor(id: string | HTMLElement, options?: MonthConfig); + + clearSelection(): void; + + dispose(): void; + + disposed(): boolean; + + init(): void; + + show(): void; + + hide(): void; + + update(options?: MonthConfig): void; + + visibleStart(): DayPilot.Date; + + visibleEnd(): DayPilot.Date; + + } + + export interface MonthAfterEventRenderArgs { + readonly e: DayPilot.Event; + readonly div: HTMLElement; + } + + export interface MonthBeforeEventRenderArgs { + readonly control: DayPilot.Month; + readonly data: EventData; + } + + export interface MonthBeforeCellRenderArgs { + readonly control: DayPilot.Month; + readonly cell: { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly properties: { + business: boolean; + headerHtml: string; + html: string; + backColor: string; + } + } + } + + export interface MonthCellHeaderClickArgs { + readonly control: DayPilot.Month; + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + preventDefault(): void; + } + + export interface MonthCellHeaderClickedArgs { + readonly control: DayPilot.Month; + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + } + + export interface MonthEventClickArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + readonly div: HTMLElement; + readonly originalEvent: MouseEvent; + readonly meta: boolean; + readonly ctrl: boolean; + preventDefault(): void; + } + + export interface MonthEventClickedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + readonly div: HTMLElement; + readonly originalEvent: MouseEvent; + readonly meta: boolean; + readonly ctrl: boolean; + } + + export interface MonthEventRightClickArgs { + readonly e: DayPilot.Event; + preventDefault(): void; + } + + export interface MonthEventRightClickedArgs { + readonly e: DayPilot.Event; + } + + export interface MonthEventDeleteArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + preventDefault(): void; + } + + export interface MonthEventDeletedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + } + + export interface MonthEventMoveArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + readonly ctrl: boolean; + readonly shift: boolean; + preventDefault(): void; + } + + + export interface MonthEventMovedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + readonly ctrl: boolean; + readonly shift: boolean; + } + + + export interface MonthEventResizeArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + preventDefault(): void; + } + + + export interface MonthEventResizedArgs { + readonly e: DayPilot.Event; + readonly control: DayPilot.Month; + readonly newStart: DayPilot.Date; + readonly newEnd: DayPilot.Date; + } + + + export interface MonthTimeRangeSelectArgs { + readonly control: DayPilot.Month; + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + preventDefault(): void; + } + + + export interface MonthTimeRangeSelectedArgs { + readonly control: DayPilot.Month; + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + } + + export class NavigatorPropsAndEvents { + cellHeight?: number; + cellWidth?: number; + command?: string; + dayHeaderHeight?: number; + freeHandSelectionEnabled?: boolean; + locale?: string; + orientation?: "Vertical" | "Horizontal"; + rowsPerMonth?: "Auto" | "Six"; + selectionDay?: DayPilot.Date; + selectionEnd?: DayPilot.Date; + selectionStart?: DayPilot.Date; + selectMode?: "Day" | "Week" | "Month" | "None"; + showMonths?: number; + showWeekNumbers?: boolean; + skipMonths?: number; + startDate?: DayPilot.Date | string; + theme?: string; + titleHeight?: number; + weekStarts?: "Auto" | number; + weekNumberAlgorithm?: "Auto" | "US" | "ISO8601"; + timeRangeSelectedHandling?: "Bind" | "None"; + visibleRangeChangedHandling?: "Enabled" | "Disabled" | "CallBack"; + + onBeforeCellRender?: EventHandler; + onTimeRangeSelect?: EventHandler; + onTimeRangeSelected?: EventHandler; + onVisibleRangeChange?: EventHandler; + onVisibleRangeChanged?: EventHandler; + } + + export class NavigatorConfig extends NavigatorPropsAndEvents { + events?: EventData[]; + } + + interface NavigatorSelectOptions { + dontFocus?: boolean; + dontNotify?: boolean; + } + + export class Navigator extends NavigatorPropsAndEvents { + v: string; + events: { + list: EventDataShort[]; + }; + + constructor(id: string | HTMLElement, options?: NavigatorConfig); + + init(): void; + + dispose(): void; + + update(options?: NavigatorConfig): void; + + select(date: DayPilot.Date | string, options?: NavigatorSelectOptions): void; + select(start: DayPilot.Date | string, end: DayPilot.Date | string, options?: NavigatorSelectOptions): void; + + hide(): void; + + show(): void; + + visibleEnd(): DayPilot.Date; + + visibleStart(): DayPilot.Date; + } + + interface NavigatorBeforeCellRenderArgs { + readonly cell: { + readonly day: DayPilot.Date; + readonly isCurrentMonth: boolean; + readonly isToday: boolean; + readonly isWeekend: boolean; + html: string; + cssClass: string; + }; + } + + interface NavigatorTimeRangeSelectArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly day: DayPilot.Date; + readonly days: number; + readonly mode: "Day" | "Week" | "Month" | "None" | "FreeHand"; + preventDefault(): void; + } + + interface NavigatorTimeRangeSelectedArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly day: DayPilot.Date; + readonly days: number; + readonly mode: "Day" | "Week" | "Month" | "None" | "FreeHand"; + } + + interface NavigatorVisibleRangeChangeArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + preventDefault(): void; + } + + interface NavigatorVisibleRangeChangedArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + } + + export class Locale { + datePattern: string; + dateTimePattern: string; + dayNames: string[]; + dayNamesShort: string[]; + monthNames: string[]; + monthNamesShort: string[]; + timeFormat: "Clock12Hours" | "Clock24Hours"; + timePattern: string; + weekStarts: number; + + constructor(id: string, properties: { + dayNames: string[]; + dayNamesShort: string[]; + monthNames: string[]; + monthNamesShort: string[]; + timePattern: string; + datePattern: string; + dateTimePattern: string; + timeFormat: "Clock12Hours" | "Clock24Hours"; + weekStarts: number; + }); + + static register(locale: DayPilot.Locale): void; + static find(id: string): DayPilot.Locale; + } + + + export class MenuPropsAndEvents { + hideOnMouseOut?: boolean; + items?: MenuItemData[]; + menuTitle?: string; + onShow?: EventHandler; + onHide?: EventHandler; + showMenuTitle?: boolean; + zIndex?: number; + theme?: string; + } + + export class MenuConfig extends MenuPropsAndEvents { + } + + + export class Menu extends MenuPropsAndEvents { + v: string; + constructor(options?: MenuConfig); + + show(target?: any): void; + hide(): void; + + static hide(): void; + } + + export interface MenuShowArgs { + readonly source: any; + readonly menu: DayPilot.Menu; + preventDefault(): void; + } + + export interface MenuHideArgs { + } + + export class MenuBar { + items: any[]; + + constructor(id: string, options?: any); + + init(): void; + + dispose(): void; + } + + export interface MenuItemData { + action?: "CallBack" | "PostBack"; + command?: string; + cssClass?: string; + disabled?: boolean; + hidden?: boolean; + href?: string; + icon?: string; + image?: string; + items?: MenuItemData[]; + onClick?: EventHandler; + symbol?: string; + tags?: any; + target?: string; + text?: string; + html?: string; + } + + export interface MenuItemClickArgs { + readonly item: MenuItemData; + readonly source: any; + readonly originalEvent: MouseEvent; + preventDefault(): void; + } + + + export class SwitcherPropsAndEvents { + selectedClass?: string; + + onChange?: EventHandler; + onChanged?: EventHandler; + onSelect?: EventHandler; + } + + export class SwitcherConfig extends SwitcherPropsAndEvents { + triggers?: SwitcherTrigger[]; + navigator?: DayPilot.Navigator; + } + + export class Switcher extends SwitcherPropsAndEvents { + constructor(options?: SwitcherConfig); + readonly active: SwitcherView; + + addTrigger(id: string | HTMLElement, view: SwitcherViewControl): void; + addNavigator(navigator: DayPilot.Navigator): void; + select(triggerId: string): void; + + events: { + load(url: string, + success: (args: { data: any; preventDefault(): void; }) => void, + error: (args: { request: XMLHttpRequest, exception: any; }) => void + ): void; + } + + } + + export interface SwitcherView { + control: SwitcherViewControl; + } + + export interface SwitcherTrigger { + id: string | HTMLElement; + view: SwitcherViewControl; + } + + export interface SwitcherChangeArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly day: DayPilot.Date; + readonly target: SwitcherView; + preventDefault(): void; + } + + export interface SwitcherChangedArgs { + readonly start: DayPilot.Date; + readonly end: DayPilot.Date; + readonly day: DayPilot.Date; + readonly target: SwitcherView; + } + + export interface SwitcherSelectArgs { + readonly source: HTMLElement; + readonly target: SwitcherViewControl; + } + + export type SwitcherViewControl = DayPilot.Calendar | DayPilot.Month; + + + export class Date { + constructor(str?: string | DayPilot.Date); + constructor(date: GlobalDate, isLocal?: boolean); + + addDays(days: number): DayPilot.Date; + + addHours(hours: number): DayPilot.Date; + + addMilliseconds(millis: number): DayPilot.Date; + + addMinutes(minutes: number): DayPilot.Date; + + addMonths(months: number): DayPilot.Date; + + addSeconds(seconds: number): DayPilot.Date; + + addTime(ticks: number): DayPilot.Date; + addTime(duration: DayPilot.Duration): DayPilot.Date; + + addYears(years: number): DayPilot.Date; + + dayOfWeek(): number; + + dayOfWeekISO(): number; + + dayOfYear(): number; + + daysInMonth(): number; + + daysInYear(): number; + + equals(another: DayPilot.Date): boolean; + + firstDayOfMonth(): DayPilot.Date; + + firstDayOfWeek(locale?: string | DayPilot.Locale): DayPilot.Date; + firstDayOfWeek(firstDayOfWeek?: number): DayPilot.Date; + + firstDayOfYear(): DayPilot.Date; + + getDatePart(): DayPilot.Date; + + getDay(): number; + + getDayOfWeek(): number; + + getYear(): number; + + getHours(): number; + + getMilliseconds(): number; + + getMinutes(): number; + + getMonth(): number; + + getSeconds(): number; + + getTime(): number; + + getTimePart(): number; + + getTotalTicks(): number; + + getYear(): number; + + lastDayOfMonth(): DayPilot.Date; + + toDate(): GlobalDate; + + toDateLocal(): GlobalDate; + + toString(pattern?: string, locale?: string | DayPilot.Locale): string; + + toStringSortable(): string; + + weekNumber(): number; + + weekNumberISO(): number; + + static fromYearMonthDay(year: number, month: number, day: number): DayPilot.Date; + static parse(input: string, pattern: string, locale?: string | DayPilot.Locale): DayPilot.Date; + static today(): DayPilot.Date; + static now(): DayPilot.Date; + static Cache: DayPilotDateCache; + } + + export class DayPilotDateCache { + static clear(): void; + } + + export class Util { + static overlaps(start1: DayPilot.Date, end1: DayPilot.Date, start2: DayPilot.Date, end2: DayPilot.Date): boolean; + static overlaps(start1: number, end1: number, start2: number, end2: number): boolean; + static escapeHtml(text: string): string; + } + + export class ColorUtil { + static darker(color: string, steps?: number): string; + static lighter(color: string, steps?: number): string; + static contrasting(color: string, light?: string, dark?: string): string; + } + + export class Http { + static get(url: string, options?: HttpGetOptions): Promise; + static post(url: string, data?: object | string, options?: HttpPostOptions): Promise; + static put(url: string, data?: object | string, options?: HttpPutOptions): Promise; + static delete(url: string, options?: HttpDeleteOptions): Promise; + } + + export interface HttpDeleteOptions { + headers?: HttpHeaders; + } + + export interface HttpGetOptions { + headers?: HttpHeaders; + } + + export interface HttpPostOptions { + headers?: HttpHeaders; + contentType?: string; + } + + export interface HttpPutOptions { + headers?: HttpHeaders; + contentType?: string; + } + + export interface HttpPromiseArgs { + readonly data: any; + readonly request: XMLHttpRequest; + } + + export interface HttpHeaders { + [header: string]: string; + } + + export class Duration { + + ticks: number; + + constructor(ticks: number); + + constructor(start: DayPilot.Date | string, end: DayPilot.Date | string); + + toString(pattern?: string): string; + + totalMilliseconds(): number; + + totalSeconds(): number; + + totalMinutes(): number; + + totalHours(): number; + + totalDays(): number; + + milliseconds(): number; + + seconds(): number; + + minutes(): number; + + hours(): number; + + days(): number; + + add(d: DayPilot.Duration): DayPilot.Duration; + + static ofWeeks(i: number): DayPilot.Duration; + + static ofDays(i: number): DayPilot.Duration; + + static ofHours(i: number): DayPilot.Duration; + + static ofMinutes(i: number): DayPilot.Duration; + + static ofSeconds(i: number): DayPilot.Duration; + + } + + export class Event { + data: any; + + constructor(data: EventData); + + start(): DayPilot.Date; + start(newStart: DayPilot.Date): void; + + end(): DayPilot.Date; + end(newEnd: DayPilot.Date): void; + + id(): EventId; + + text(): string; + text(newText: string): void; + + resource(): string; + resource(newResource: string): void; + + duration(): DayPilot.Duration; + } + + export class Selection { + start: DayPilot.Date; + end: DayPilot.Date; + resource: string; + } + + export interface EventDataShort { + start: string | DayPilot.Date; + end: string | DayPilot.Date; + } + + export interface EventData { + start: string | DayPilot.Date; + end: string | DayPilot.Date; + id: EventId; + text: string; + resource?: ResourceId; + + areas?: AreaData[]; + backColor?: string; + barBackColor?: string; + barColor?: string; + barHidden?: boolean; + borderColor?: string; + cssClass?: string; + fontColor?: string; + html?: string; + tags?: any; + } + + export interface AreaData { + action?: "Default" | "None" | "ContextMenu" | "ResizeEnd" | "ResizeStart" | "Move"; + backColor?: string; + background?: string; + bottom?: number | string; + cssClass?: string; + fontColor?: string; + height?: number | string; + horizontalAlignment?: HorizontalAlignment; + html?: string; + icon?: string; + id?: AreaId; + image?: string; + left?: number | string; + menu?: Menu | string; + onClick?: (args: any) => void; + onClicked?: (args: any) => void; + onMouseEnter?: (args: any) => void; + onMouseLeave?: (args: any) => void; + padding?: number; + right?: number | string; + style?: string; + symbol?: string; + text?: string; + toolTip?: string; + top?: number | string; + verticalAlignment?: VerticalAlignment; + visibility?: "Hover" | "Visible" | "TouchVisible"; + width?: number | string; + } + + + export function guid(): string; + + export interface EventHandler { + (args: T): void; + } + + export type ResourceId = string | number; + export type EventId = string | number; + export type AreaId = string | number; + + export type HorizontalAlignment = "right" | "center" | "left"; + export type VerticalAlignment = "top" | "center" | "bottom"; + + // modal + + export class ModalPropsAndEvents { + autoFocus?: boolean; + autoStretch?: boolean; + autoStretchFirstLoadOnly?: boolean; + container?: HTMLElement; + disposeOnClose?: boolean; + dragDrop?: boolean; + focus?: string | { id: string, value: string | number }; + height?: number; + left?: number; + loadingHtml?: string; + maxHeight?: number; + scrollWithPage?: boolean; + theme?: string; + top?: number; + useIframe?: boolean; + width?: number; + zIndex?: number; + + onClose?: EventHandler; + onClosed?: EventHandler; + onShow?: EventHandler; + } + + export class ModalConfig extends ModalPropsAndEvents { + } + + export class Modal extends ModalPropsAndEvents { + constructor(options?: ModalConfig) + + close(result?: any): void; + + closeSerialized(): void; + + showHtml(html: string | HTMLElement): void; + + showUrl(url: string): void; + + stretch(): void; + + static close(): void; + + static opener(): void; + + static prompt(message: string, defaultValue?: string, options?: ModalPromptConfig): Promise; + + static alert(message: string, options?: ModalAlertConfig): Promise; + + static confirm(message: string, options?: ModalConfirmConfig): Promise; + + static form(form?: ModalFormItem[], data?: any, options?: ModalFormConfig): Promise; + } + + export class ModalAlertConfig extends ModalConfig { + okText?: string; + } + + export class ModalConfirmConfig extends ModalConfig { + okText?: string; + cancelText?: string; + } + + export class ModalPromptConfig extends ModalConfig { + okText?: string; + cancelText?: string; + } + + export class ModalFormConfig extends ModalConfig { + okText?: string; + cancelText?: string; + locale?: string; + plugins?: any; + } + + export interface ModalCloseArgs { + canceled: boolean; + result: any; + backgroundClick: boolean; + + preventDefault(): void; + } + + export interface ModalClosedArgs { + canceled: boolean; + result: any; + backgroundClick: boolean; + } + + export interface ModalShowArgs { + root: Node + } + + + export interface ModalFormItem { + id?: string; + name?: string; + type?: "text" | "date" | "searchable" | "select" | "radio" | "checkbox" | "table" | "title" | "image" | "html" | "textarea" | "scrollable" | string; + image?: string; + dateFormat?: string; + disabled?: boolean; + cssClass?: string; + options?: ModalFormOption[]; + children?: ModalFormItem[]; + columns?: ModalFormTableColumns[]; + onValidate?: EventHandler; + onNewRow?: EventHandler; + height?: number; + text?: string; + html?: string; + } + + export interface ModalFormOption { + id: string | number; + name?: string; + children?: ModalFormItem[]; + } + + export interface ModalFormTableColumns { + id: string; + name: string; + type?: "text" | "number" | "select"; + options?: ModalFormOption[]; + } + + export interface ModalFormItemValidationArgs { + value: any; + result: any; + valid: boolean; + message: string; + } + + export interface ModalFormTableItemNewRowArgs { + value: any; + result: any; + } + +} diff --git a/static/src/js/daypilot-all.min.js b/static/src/js/daypilot-all.min.js new file mode 100644 index 0000000..1e858f2 --- /dev/null +++ b/static/src/js/daypilot-all.min.js @@ -0,0 +1,16 @@ +/* +DayPilot Lite +Copyright (c) 2005 - 2024 Annpoint s.r.o. +https://www.daypilot.org/ +Licensed under Apache Software License 2.0 +Version: 2024.3.539-lite +*/ +var DayPilot={};if("undefined"==typeof DayPilot)var DayPilot={};if(function(){function e(e){var t=DayPilot.Date.Cache.Ticks;if(t[e])return DayPilot.Stats.cacheHitsTicks+=1,t[e];var i,a=new Date(e),n=a.getUTCMilliseconds();i=0===n?"":n<10?".00"+n:n<100?".0"+n:"."+n;var o=a.getUTCSeconds();o<10&&(o="0"+o);var r=a.getUTCMinutes();r<10&&(r="0"+r);var s=a.getUTCHours();s<10&&(s="0"+s);var l=a.getUTCDate();l<10&&(l="0"+l);var d=a.getUTCMonth()+1;d<10&&(d="0"+d);var c=a.getUTCFullYear();if(c<=0)throw"The minimum year supported is 1.";c<10?c="000"+c:c<100?c="00"+c:c<1e3&&(c="0"+c);var u=c+"-"+d+"-"+l+"T"+s+":"+r+":"+o+i;return t[e]=u,u}function t(e,t){return!DayPilot.Util.isNullOrUndefined(e)&&(!DayPilot.Util.isNullOrUndefined(t)&&e.toLocaleLowerCase()===t.toLocaleLowerCase())}function i(e){e=Math.min(e,255),e=Math.max(e,0);var t=e.toString(16);return e<16?"0"+t:t}if("undefined"==typeof DayPilot.$){"undefined"==typeof DayPilot.Global&&(DayPilot.Global={}),DayPilot.$=function(e){return document.getElementById(e)},Object.defineProperty(DayPilot,"isKhtml",{get:function(){return"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.indexOf("KHTML")!==-1}}),DayPilot.mo2=function(e,t){if(t=t||window.event,"undefined"!=typeof t.offsetX){var i={x:t.offsetX+1,y:t.offsetY+1};if(!e)return i;for(var a=t.srcElement;a&&a!==e;)"SPAN"!==a.tagName&&(i.x+=a.offsetLeft,a.offsetTop>0&&(i.y+=a.offsetTop-a.scrollTop)),a=a.offsetParent;return a?i:null}if("undefined"!=typeof t.layerX){var i={x:t.layerX,y:t.layerY,src:t.target};if(!e)return i;for(var a=t.target;a&&"absolute"!==a.style.position&&"relative"!==a.style.position;)a=a.parentNode,DayPilot.isKhtml&&(i.y+=a.scrollTop);for(;a&&a!==e;)i.x+=a.offsetLeft,i.y+=a.offsetTop-a.scrollTop,a=a.offsetParent;return a?i:null}return null},DayPilot.mo3=function(e,t){var i,a=DayPilot.page(t);if(a)if(e){var n=DayPilot.abs(e);if(!n)throw new Error("no abs");i={x:a.x-n.x,y:a.y-n.y}}else i={x:a.x,y:a.y};else if(i=DayPilot.mo2(e,t),!i)return null;return i.shift=t.shiftKey,i.meta=t.metaKey,i.ctrl=t.ctrlKey,i.alt=t.altKey,i},DayPilot.browser={},Object.defineProperty(DayPilot.browser,"hover",{get:function(){return!window.matchMedia("(any-hover: none)").matches}}),DayPilot.touch={},DayPilot.page=function(e){var t=e.changedTouches&&e.changedTouches[0]?e.changedTouches[0]:e;return"undefined"!=typeof t.pageX?{x:t.pageX,y:t.pageY}:"undefined"!=typeof e.clientX&&document.body&&document.documentElement?{x:e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,y:e.clientY+document.body.scrollTop+document.documentElement.scrollTop}:null},DayPilot.abs=function(e,t){if(!e)return null;if(e.getBoundingClientRect){var i=DayPilot.absBoundingClientBased(e);if(t){var a=DayPilot.absOffsetBased(e,!1),t=DayPilot.absOffsetBased(e,!0);i.x+=t.x-a.x,i.y+=t.y-a.y,i.w=t.w,i.h=t.h}return i}return DayPilot.absOffsetBased(e,t)},DayPilot.absBoundingClientBased=function(e){var t=e.getBoundingClientRect();return{x:t.left+window.pageXOffset,y:t.top+window.pageYOffset,w:e.clientWidth,h:e.clientHeight,toString:function(){return"x:"+this.x+" y:"+this.y+" w:"+this.w+" h:"+this.h}}},DayPilot.absOffsetBased=function(e,t){for(var i={x:e.offsetLeft,y:e.offsetTop,w:e.clientWidth,h:e.clientHeight,toString:function(){return"x:"+this.x+" y:"+this.y+" w:"+this.w+" h:"+this.h}};e.offsetParent;)e=e.offsetParent,i.x-=e.scrollLeft,i.y-=e.scrollTop,t&&(i.x<0&&(i.w+=i.x,i.x=0),i.y<0&&(i.h+=i.y,i.y=0),e.scrollLeft>0&&i.x+i.w>e.clientWidth&&(i.w-=i.x+i.w-e.clientWidth),e.scrollTop&&i.y+i.h>e.clientHeight&&(i.h-=i.y+i.h-e.clientHeight)),i.x+=e.offsetLeft,i.y+=e.offsetTop;var a=DayPilot.pageOffset();return i.x+=a.x,i.y+=a.y,i},DayPilot.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},DayPilot.distance=function(e,t){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},DayPilot.sheet=function(){if("undefined"==typeof window){var e={};return e.add=function(){},e.commit=function(){},e}var t=document.createElement("style");t.setAttribute("type","text/css"),t.styleSheet||t.appendChild(document.createTextNode("")),(document.head||document.getElementsByTagName("head")[0]).appendChild(t);var i=!!t.styleSheet,e={};return e.rules=[],e.commit=function(){i&&(t.styleSheet.cssText=this.rules.join("\n"))},e.add=function(e,a,n){return i?void this.rules.push(e+"{"+a+"}"):void(t.sheet.insertRule?("undefined"==typeof n&&(n=t.sheet.cssRules.length),t.sheet.insertRule(e+"{"+a+"}",n)):t.sheet.addRule&&t.sheet.addRule(e,a,n))},e},DayPilot.gs=function(e,t){return window.getComputedStyle(e,null).getPropertyValue(t)||""},DayPilot.StyleReader=function(e){this.get=function(t){return e?DayPilot.gs(e,t):null},this.getPx=function(e){var t=this.get(e);return t.indexOf("px")===-1?void 0:parseInt(t,10)}},function(){if(!DayPilot.Global.defaultCss){var e=DayPilot.sheet();e.add(".calendar_default_main","border: 1px solid #c0c0c0; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;"),e.add(".calendar_default_main *, .calendar_default_main *:before, .calendar_default_main *:after","box-sizing: content-box;"),e.add(".calendar_default_rowheader_inner,.calendar_default_cornerright_inner,.calendar_default_corner_inner,.calendar_default_colheader_inner,.calendar_default_alldayheader_inner","color: #333;background: #f3f3f3;"),e.add(".calendar_default_cornerright_inner","position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;\tborder-bottom: 1px solid #c0c0c0;"),e.add(".calendar_default_direction_rtl .calendar_default_cornerright_inner","border-right: 1px solid #c0c0c0;"),e.add(".calendar_default_rowheader_inner","font-size: 16pt;text-align: right; position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0; padding: 3px;"),e.add(".calendar_default_direction_rtl .calendar_default_rowheader_inner","border-right: none;"),e.add(".calendar_default_corner_inner","position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"),e.add(".calendar_default_direction_rtl .calendar_default_corner_inner","border-right: none;"),e.add(".calendar_default_rowheader_minutes","font-size:10px;vertical-align: super;padding-left: 2px;padding-right: 2px;"),e.add(".calendar_default_colheader_inner","position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0; display: flex; align-items: center; justify-content: center; font-size: 13px;"),e.add(".calendar_default_cell_inner","position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #ddd;border-bottom: 1px solid #ddd; background: #f9f9f9;"),e.add(".calendar_default_cell_business .calendar_default_cell_inner","background: #fff"),e.add(".calendar_default_alldayheader_inner","text-align: center;position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"),e.add(".calendar_default_message","opacity: 0.9; padding: 10px; color: #ffffff;background: #ffa216;"),e.add(".calendar_default_alldayevent_inner,.calendar_default_event_inner","color: #333; border: 1px solid #999;"),e.add(".calendar_default_event_bar","top: 0px;bottom: 0px;left: 0px;width: 6px;background-color: #9dc8e8;"),e.add(".calendar_default_event_bar_inner","position: absolute;width: 6px;background-color: #1066a8;"),e.add(".calendar_default_alldayevent_inner,.calendar_default_event_inner",'background: #fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'),e.add(".calendar_default_selected .calendar_default_event_inner","background: #ddd;"),e.add(".calendar_default_alldayevent_inner","position: absolute;top: 2px;bottom: 2px;left: 2px;right: 2px;overflow:hidden;padding: 2px;margin-right: 1px; font-size: 13px;"),e.add(".calendar_default_event_withheader .calendar_default_event_inner","padding-top: 15px;"),e.add(".calendar_default_event","cursor: default;"),e.add(".calendar_default_event_inner","position: absolute;overflow: hidden;top: 0px;bottom: 0px;left: 0px;right: 0px;padding: 2px 2px 2px 8px; font-size: 13px;"),e.add(".calendar_default_event_delete","background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat; opacity: 0.6; cursor: pointer;"),e.add(".calendar_default_event_delete:hover","opacity: 1;-ms-filter: none;"),e.add(".calendar_default_scroll_up","background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAB3RJTUUH2wESDiYcrhwCiQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAARnQU1BAACxjwv8YQUAAACcSURBVHjaY2AgF9wWsTW6yGMlhi7OhC7AyMDQzMnBXIpFHAFuCtuaMTP+P8nA8P/b1x//FfW/HHuF1UQmxv+NUP1c3OxMVVhNvCVi683E8H8LXOY/w9+fTH81tF8fv4NiIpBRj+YoZtZ/LDUoJmKYhsVUpv0MDiyMDP96sIYV0FS2/8z9ICaLlOhvS4b/jC//MzC8xBG0vJeF7GQBlK0xdiUzCtsAAAAASUVORK5CYII=);"),e.add(".calendar_default_scroll_down","background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAALiMAAC4jAXilP3YAAACqSURBVChTY7wpam3L9J+xmQEP+PGPKZZxP4MDi4zI78uMDIwa2NT+Z2DYovrmiC+TI8OBP/8ZmEqwGvif4e8vxr+FIDkmEKH25vBWBgbG0+iK/zEwLtF+ffwOXCGI8Y+BoRFFIdC030x/WmBiYBNhpgLdswNJ8RSYaSgmgk39z1gPUfj/29ef/9rwhQTDHRHbrbdEbLvRFcGthkkAra/9/uMvhkK8piNLAgCRpTnNn4AEmAAAAABJRU5ErkJggg==);"),e.add(".calendar_default_now","background-color: red;"),e.add(".calendar_default_now:before","content: ''; top: -5px; border-width: 5px; border-color: transparent transparent transparent red; border-style: solid; width: 0px; height:0px; position: absolute; -moz-transform: scale(.9999);"),e.add(".calendar_default_shadow_top",'box-sizing: border-box; padding:2px;border:1px solid #ccc;background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'),e.add(".calendar_default_shadow_bottom",'box-sizing: border-box; padding:2px;border:1px solid #ccc;background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'),e.add(".calendar_default_crosshair_vertical, .calendar_default_crosshair_horizontal, .calendar_default_crosshair_left, .calendar_default_crosshair_top","background-color: gray; opacity: 0.2;"),e.add(".calendar_default_loading","background-color: orange; color: white; padding: 2px;"),e.add(".calendar_default_scroll","background-color: #f3f3f3;"),e.add(".calendar_default_event_moving_source","opacity: 0.5;"),e.add(".calendar_default_shadow_inner","box-sizing: border-box; background-color: #bbbbbb;border: 1px solid #888888;opacity: 0.5;height: 100%;"),e.add(".calendar_default_shadow","box-shadow: 0 2px 5px rgba(0,0,0,.2);"),e.add(".menu_default_main","user-select:none; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size: 13px;border: 1px solid #dddddd;background-color: white;padding: 0px;cursor: default;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAABCAIAAABG0om7AAAAKXRFWHRDcmVhdGlvbiBUaW1lAHBvIDEwIDUgMjAxMCAyMjozMzo1OSArMDEwMGzy7+IAAAAHdElNRQfaBQoUJAesj4VUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAABGdBTUEAALGPC/xhBQAAABVJREFUeNpj/P//PwO1weMnT2RlZAAYuwX/4oA3BgAAAABJRU5ErkJggg==);background-repeat: repeat-y;xborder-radius: 5px;-moz-box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);-webkit-box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);"),e.add(".menu_default_main, .menu_default_main *, .menu_default_main *:before, .menu_default_main *:after","box-sizing: content-box;"),e.add(".menu_default_title","background-color: #f2f2f2;border-bottom: 1px solid gray;padding: 4px 4px 4px 37px;"),e.add(".menu_default_main a","padding: 2px 2px 2px 35px;color: black;text-decoration: none;cursor: default;"),e.add(".menu_default_main.menu_default_withchildren a","padding: 2px 35px 2px 35px;"),e.add(".menu_default_main a img","margin-left: 6px;margin-top: 2px;"),e.add(".menu_default_item_text","display: block;height: 20px;line-height: 20px; overflow:hidden;padding-left: 2px;padding-right: 20px; white-space: nowrap;"),e.add(".menu_default_main a:hover","background-color: #f3f3f3;"),e.add(".menu_default_main div div","border-top: 1px solid #dddddd;margin-top: 2px;margin-bottom: 2px;margin-left: 28px;"),e.add(".menu_default_main a.menu_default_item_disabled","color: #ccc"),e.add(".menu_default_item_haschildren.menu_default_item_haschildren_active","background-color: #f3f3f3;"),e.add(".menu_default_item_haschildren a:before","content: ''; border-width: 5px; border-color: transparent transparent transparent #666; border-style: solid; width: 0px; height:0px; position: absolute; right: 5px; margin-top: 5px;"),e.add(".menu_default_item_icon","position: absolute; top:0px; left: 0px; padding: 2px 2px 2px 8px;"),e.add(".menu_default_item a i","height: 20px;line-height: 20px;"),e.add(".menu_default_item .menu_default_item_symbol","width: 18px; height: 18px; color: #999; margin-left: 6px;margin-top: 2px;"),e.add(".menubar_default_main","border-bottom: 1px solid #ccc; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px; user-select:none;"),e.add(".menubar_default_item","display: inline-block; padding: 6px 10px; cursor: default;"),e.add(".menubar_default_item:hover","background-color: #f2f2f2;"),e.add(".menubar_default_item_active","background-color: #f2f2f2;"),e.add(".scheduler_default_selected .scheduler_default_event_inner","background: #ddd;"),e.add(".scheduler_default_main","border: 1px solid #c0c0c0;font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;"),e.add(".scheduler_default_timeheader","cursor: default;color: #333;"),e.add(".scheduler_default_message","opacity: 0.9;filter: alpha(opacity=90);padding: 10px; color: #ffffff;background: #ffa216;"),e.add(".scheduler_default_timeheadergroup,.scheduler_default_timeheadercol","color: #333;background: #f3f3f3;"),e.add(".scheduler_default_rowheader,.scheduler_default_corner","color: #333;background: #f3f3f3;"),e.add(".scheduler_default_rowheader_inner","position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #eee;padding: 2px;"),e.add(".scheduler_default_timeheadergroup, .scheduler_default_timeheadercol","text-align: center;"),e.add(".scheduler_default_timeheadergroup_inner","position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"),e.add(".scheduler_default_timeheadercol_inner","position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #c0c0c0;"),e.add(".scheduler_default_divider","background-color: #c0c0c0;"),e.add(".scheduler_default_divider_horizontal","background-color: #c0c0c0;"),e.add(".scheduler_default_matrix_vertical_line","background-color: #eee;"),e.add(".scheduler_default_matrix_vertical_break","background-color: #000;"),e.add(".scheduler_default_matrix_horizontal_line","background-color: #eee;"),e.add(".scheduler_default_resourcedivider","background-color: #c0c0c0;"),e.add(".scheduler_default_shadow_inner","background-color: #666666;opacity: 0.5;filter: alpha(opacity=50);height: 100%;xborder-radius: 5px;"),e.add(".scheduler_default_event","color:#333; font-size: 13px;"),e.add(".scheduler_default_event_inner","position:absolute;top:0px;left:0px;right:0px;bottom:0px;padding:5px 2px 2px 2px;overflow:hidden;border:1px solid #ccc;"),e.add(".scheduler_default_event_bar","top:0px;left:0px;right:0px;height:4px;background-color:#9dc8e8;"),e.add(".scheduler_default_event_bar_inner","position:absolute;height:4px;background-color:#1066a8;"),e.add(".scheduler_default_event_inner",'background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'),e.add(".scheduler_default_event_float_inner","padding:6px 2px 2px 8px;"),e.add(".scheduler_default_event_float_inner:after",'content:"";border-color: transparent #666 transparent transparent;border-style:solid;border-width:5px;width:0;height:0;position:absolute;top:8px;left:-4px;'),e.add(".scheduler_default_columnheader_inner","font-weight: bold;"),e.add(".scheduler_default_columnheader_splitter","background-color: #666;opacity: 0.5;filter: alpha(opacity=50);"),e.add(".scheduler_default_columnheader_cell_inner","padding: 2px;"),e.add(".scheduler_default_cell","background-color: #f9f9f9;"),e.add(".scheduler_default_cell.scheduler_default_cell_business","background-color: #fff;"),e.add(".navigator_default_main","border-left: 1px solid #c0c0c0;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;background-color: white;color: #000000; box-sizing: content-box;"),e.add(".navigator_default_main *, .navigator_default_main *:before, .navigator_default_main *:after","box-sizing: content-box;"),e.add(".navigator_default_month","font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 12px;"),e.add(".navigator_default_day","color: black;"),e.add(".navigator_default_weekend","background-color: #f0f0f0;"),e.add(".navigator_default_dayheader","color: black;"),e.add(".navigator_default_line","border-bottom: 1px solid #c0c0c0;"),e.add(".navigator_default_dayother","color: gray;"),e.add(".navigator_default_todaybox","border: 1px solid red;"),e.add(".navigator_default_title, .navigator_default_titleleft, .navigator_default_titleright","border-top: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;color: #333;background: #f3f3f3;"),e.add(".navigator_default_busy","font-weight: bold;"),e.add(".navigator_default_cell","text-align: center;"),e.add(".navigator_default_select .navigator_default_cell_box","background-color: #FFE794; opacity: 0.5;"),e.add(".navigator_default_title","text-align: center;"),e.add(".navigator_default_titleleft, .navigator_default_titleright","text-align: center;"),e.add(".navigator_default_dayheader","text-align: center;"),e.add(".navigator_default_weeknumber","text-align: center; color: #999;"),e.add(".navigator_default_cell_text","cursor: pointer;"),e.add(".month_default_main","border: 1px solid #c0c0c0;font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;color: #333;"),e.add(".month_default_main *, .month_default_main *:before, .month_default_main *:after","box-sizing: content-box;"),e.add(".month_default_cell_inner","border-right: 1px solid #ddd;border-bottom: 1px solid #ddd;position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;background-color: #f9f9f9;"),e.add(".month_default_cell_business .month_default_cell_inner","background-color: #fff;"),e.add(".month_default_cell_header","text-align: right; padding: 4px; box-sizing: border-box;"),e.add(".month_default_header_inner","position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;cursor: default;color: #333;background: #f3f3f3; overflow:hidden; display: flex; align-items: center; justify-content: center;"),e.add(".month_default_message","padding: 10px;opacity: 0.9; color: #ffffff;background: #ffa216;"),e.add(".month_default_event_inner","position: absolute;top: 0px;bottom: 0px;left: 1px;right: 1px;overflow:hidden;padding: 2px;padding-left: 10px;color: #333;background: #fff;background: linear-gradient(to bottom, #ffffff 0%, #eeeeee);border: 1px solid #999;border-radius: 0px;display: flex; align-items: center; font-size: 13px;"),e.add(".month_default_event_continueright .month_default_event_inner","border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-right-style: dotted;"),e.add(".month_default_event_continueleft .month_default_event_inner","border-top-left-radius: 0px;border-bottom-left-radius: 0px;border-left-style: dotted;"),e.add(".month_default_event_bar","top: 0px;bottom: 0px;left: 0px;width: 6px;"),e.add(".month_default_event_bar_inner","position: absolute;width: 6px;background-color: #1066a8;"),e.add(".month_default_event_continueleft .month_default_event_bar","display: none;"),e.add(".month_default_selected .month_default_event_inner","background: #ddd;"),e.add(".month_default_event_delete","background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat; opacity: 0.6; cursor: pointer;"),e.add(".month_default_event_delete:hover","opacity: 1;-ms-filter: none;"),e.add(".month_default_event_timeleft","color: #ccc; font-size: 8pt"),e.add(".month_default_event_timeright","color: #ccc; font-size: 8pt; text-align: right;"),e.add(".month_default_loading","background-color: orange; color: white; padding: 2px;"),e.add(".month_default_shadow_inner","box-sizing: border-box; background-color: #bbbbbb;border: 1px solid #888888;opacity: 0.5;height: 100%;"),e.add(".month_default_shadow","box-shadow: 0 2px 5px rgba(0,0,0,.2);"),e.commit(),DayPilot.Global.defaultCss=!0}}(),DayPilot.doc=function(){var e=document.documentElement;return e&&e.clientHeight?e:document.body},DayPilot.guid=function(){var e=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)};return""+e()+e()+"-"+e()+"-"+e()+"-"+e()+"-"+e()+e()+e()},DayPilot.pageOffset=function(){if("undefined"!=typeof pageXOffset)return{x:pageXOffset,y:pageYOffset};var e=DayPilot.doc();return{x:e.scrollLeft,y:e.scrollTop}},DayPilot.indexOf=function(e,t){if(!e||!e.length)return-1;for(var i=0;i0)for(var o=0;o0)){e.areas=[];for(var o=0;o2&&(t=DayPilot.Util.replaceCharAt(t,2,"-")),DayPilot.Locale.all[t]},DayPilot.Locale.register=function(e){DayPilot.Locale.all[e.id]=e},DayPilot.Locale.register(new DayPilot.Locale("ca-es",{"dayNames":["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],"dayNamesShort":["dg","dl","dt","dc","dj","dv","ds"],"monthNames":["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre",""],"monthNamesShort":["gen.","febr.","març","abr.","maig","juny","jul.","ag.","set.","oct.","nov.","des.",""],"timePattern":"H:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("cs-cz",{"dayNames":["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"],"dayNamesShort":["ne","po","út","st","čt","pá","so"],"monthNames":["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec",""],"monthNamesShort":["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII",""],"timePattern":"H:mm","datePattern":"d. M. yyyy","dateTimePattern":"d. M. yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("da-dk",{"dayNames":["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],"dayNamesShort":["sø","ma","ti","on","to","fr","lø"],"monthNames":["januar","februar","marts","april","maj","juni","juli","august","september","oktober","november","december",""],"monthNamesShort":["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""],"timePattern":"HH:mm","datePattern":"dd-MM-yyyy","dateTimePattern":"dd-MM-yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("de-at",{"dayNames":["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],"dayNamesShort":["So","Mo","Di","Mi","Do","Fr","Sa"],"monthNames":["Jänner","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""],"monthNamesShort":["Jän","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("de-ch",{"dayNames":["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],"dayNamesShort":["So","Mo","Di","Mi","Do","Fr","Sa"],"monthNames":["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""],"monthNamesShort":["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("de-de",{"dayNames":["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],"dayNamesShort":["So","Mo","Di","Mi","Do","Fr","Sa"],"monthNames":["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""],"monthNamesShort":["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("de-lu",{"dayNames":["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],"dayNamesShort":["So","Mo","Di","Mi","Do","Fr","Sa"],"monthNames":["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember",""],"monthNamesShort":["Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("en-au",{"dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Su","Mo","Tu","We","Th","Fr","Sa"],"monthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"timePattern":"h:mm tt","datePattern":"d/MM/yyyy","dateTimePattern":"d/MM/yyyy h:mm tt","timeFormat":"Clock12Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("en-ca",{"dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Su","Mo","Tu","We","Th","Fr","Sa"],"monthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"timePattern":"h:mm tt","datePattern":"yyyy-MM-dd","dateTimePattern":"yyyy-MM-dd h:mm tt","timeFormat":"Clock12Hours","weekStarts":0})),DayPilot.Locale.register(new DayPilot.Locale("en-gb",{"dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Su","Mo","Tu","We","Th","Fr","Sa"],"monthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"timePattern":"HH:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("en-us",{"dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Su","Mo","Tu","We","Th","Fr","Sa"],"monthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"timePattern":"h:mm tt","datePattern":"M/d/yyyy","dateTimePattern":"M/d/yyyy h:mm tt","timeFormat":"Clock12Hours","weekStarts":0})),DayPilot.Locale.register(new DayPilot.Locale("es-es",{"dayNames":["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],"dayNamesShort":["D","L","M","X","J","V","S"],"monthNames":["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""],"monthNamesShort":["ene.","feb.","mar.","abr.","may.","jun.","jul.","ago.","sep.","oct.","nov.","dic.",""],"timePattern":"H:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("es-mx",{"dayNames":["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],"dayNamesShort":["do.","lu.","ma.","mi.","ju.","vi.","sá."],"monthNames":["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre",""],"monthNamesShort":["ene.","feb.","mar.","abr.","may.","jun.","jul.","ago.","sep.","oct.","nov.","dic.",""],"timePattern":"hh:mm tt","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy hh:mm tt","timeFormat":"Clock12Hours","weekStarts":0})),DayPilot.Locale.register(new DayPilot.Locale("eu-es",{"dayNames":["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"],"dayNamesShort":["ig","al","as","az","og","or","lr"],"monthNames":["urtarrila","otsaila","martxoa","apirila","maiatza","ekaina","uztaila","abuztua","iraila","urria","azaroa","abendua",""],"monthNamesShort":["urt.","ots.","mar.","api.","mai.","eka.","uzt.","abu.","ira.","urr.","aza.","abe.",""],"timePattern":"H:mm","datePattern":"yyyy/MM/dd","dateTimePattern":"yyyy/MM/dd H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("fi-fi",{"dayNames":["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],"dayNamesShort":["su","ma","ti","ke","to","pe","la"],"monthNames":["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu",""],"monthNamesShort":["tammi","helmi","maalis","huhti","touko","kesä","heinä","elo","syys","loka","marras","joulu",""],"timePattern":"H:mm","datePattern":"d.M.yyyy","dateTimePattern":"d.M.yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("fr-be",{"dayNames":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"dayNamesShort":["di","lu","ma","me","je","ve","sa"],"monthNames":["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""],"monthNamesShort":["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""],"timePattern":"HH:mm","datePattern":"dd-MM-yy","dateTimePattern":"dd-MM-yy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("fr-ch",{"dayNames":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"dayNamesShort":["di","lu","ma","me","je","ve","sa"],"monthNames":["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""],"monthNamesShort":["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("fr-fr",{"dayNames":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"dayNamesShort":["di","lu","ma","me","je","ve","sa"],"monthNames":["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""],"monthNamesShort":["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""],"timePattern":"HH:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("fr-lu",{"dayNames":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"dayNamesShort":["di","lu","ma","me","je","ve","sa"],"monthNames":["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre",""],"monthNamesShort":["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc.",""],"timePattern":"HH:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("gl-es",{"dayNames":["domingo","luns","martes","mércores","xoves","venres","sábado"],"dayNamesShort":["do","lu","ma","mé","xo","ve","sá"],"monthNames":["xaneiro","febreiro","marzo","abril","maio","xuño","xullo","agosto","setembro","outubro","novembro","decembro",""],"monthNamesShort":["xan","feb","mar","abr","maio","xuño","xul","ago","set","out","nov","dec",""],"timePattern":"H:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("it-it",{"dayNames":["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"],"dayNamesShort":["do","lu","ma","me","gi","ve","sa"],"monthNames":["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre",""],"monthNamesShort":["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic",""],"timePattern":"HH:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("it-ch",{"dayNames":["domenica","lunedì","martedì","mercoledì","giovedì","venerdì","sabato"],"dayNamesShort":["do","lu","ma","me","gi","ve","sa"],"monthNames":["gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre",""],"monthNamesShort":["gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("ja-jp",{"dayNames":["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],"dayNamesShort":["日","月","火","水","木","金","土"],"monthNames":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""],"monthNamesShort":["1","2","3","4","5","6","7","8","9","10","11","12",""],"timePattern":"H:mm","datePattern":"yyyy/MM/dd","dateTimePattern":"yyyy/MM/dd H:mm","timeFormat":"Clock24Hours","weekStarts":0})),DayPilot.Locale.register(new DayPilot.Locale("nb-no",{"dayNames":["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],"dayNamesShort":["sø","ma","ti","on","to","fr","lø"],"monthNames":["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""],"monthNamesShort":["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("nl-nl",{"dayNames":["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],"dayNamesShort":["zo","ma","di","wo","do","vr","za"],"monthNames":["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december",""],"monthNamesShort":["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec",""],"timePattern":"HH:mm","datePattern":"d-M-yyyy","dateTimePattern":"d-M-yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("nl-be",{"dayNames":["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],"dayNamesShort":["zo","ma","di","wo","do","vr","za"],"monthNames":["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december",""],"monthNamesShort":["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec",""],"timePattern":"H:mm","datePattern":"d/MM/yyyy","dateTimePattern":"d/MM/yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("nn-no",{"dayNames":["søndag","måndag","tysdag","onsdag","torsdag","fredag","laurdag"],"dayNamesShort":["sø","må","ty","on","to","fr","la"],"monthNames":["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember",""],"monthNamesShort":["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des",""],"timePattern":"HH:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("pt-br",{"dayNames":["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"],"dayNamesShort":["D","S","T","Q","Q","S","S"],"monthNames":["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro",""],"monthNamesShort":["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez",""],"timePattern":"HH:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":0})),DayPilot.Locale.register(new DayPilot.Locale("pl-pl",{"dayNames":["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"],"dayNamesShort":["N","Pn","Wt","Śr","Cz","Pt","So"],"monthNames":["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień",""],"monthNamesShort":["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru",""],"timePattern":"HH:mm","datePattern":"yyyy-MM-dd","dateTimePattern":"yyyy-MM-dd HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("pt-pt",{"dayNames":["domingo","segunda-feira","terça-feira","quarta-feira","quinta-feira","sexta-feira","sábado"],"dayNamesShort":["D","S","T","Q","Q","S","S"],"monthNames":["janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro",""],"monthNamesShort":["jan","fev","mar","abr","mai","jun","jul","ago","set","out","nov","dez",""],"timePattern":"HH:mm","datePattern":"dd/MM/yyyy","dateTimePattern":"dd/MM/yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":0})),DayPilot.Locale.register(new DayPilot.Locale("ro-ro",{"dayNames":["duminică","luni","marți","miercuri","joi","vineri","sâmbătă"],"dayNamesShort":["D","L","Ma","Mi","J","V","S"],"monthNames":["ianuarie","februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie",""],"monthNamesShort":["ian.","feb.","mar.","apr.","mai.","iun.","iul.","aug.","sep.","oct.","nov.","dec.",""],"timePattern":"H:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("ru-ru",{"dayNames":["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],"dayNamesShort":["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],"monthNames":["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь",""],"monthNamesShort":["янв","фев","мар","апр","май","июн","июл","авг","сен","окт","ноя","дек",""],"timePattern":"H:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("sk-sk",{"dayNames":["nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota"],"dayNamesShort":["ne","po","ut","st","št","pi","so"],"monthNames":["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december",""],"monthNamesShort":["1","2","3","4","5","6","7","8","9","10","11","12",""],"timePattern":"H:mm","datePattern":"d.M.yyyy","dateTimePattern":"d.M.yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("sv-se",{"dayNames":["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],"dayNamesShort":["sö","må","ti","on","to","fr","lö"],"monthNames":["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december",""],"monthNamesShort":["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec",""],"timePattern":"HH:mm","datePattern":"yyyy-MM-dd","dateTimePattern":"yyyy-MM-dd HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("tr-tr",{"dayNames":["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],"dayNamesShort":["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],"monthNames":["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık",""],"monthNamesShort":["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara",""],"timePattern":"HH:mm","datePattern":"d.M.yyyy","dateTimePattern":"d.M.yyyy HH:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("uk-ua",{"dayNames":["неділя","понеділок","вівторок","середа","четвер","п'ятниця","субота"],"dayNamesShort":["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],"monthNames":["січень","лютий","березень","квітень","травень","червень","липень","серпень","вересень","жовтень","листопад","грудень",""],"monthNamesShort":["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру",""],"timePattern":"H:mm","datePattern":"dd.MM.yyyy","dateTimePattern":"dd.MM.yyyy H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("zh-cn",{"dayNames":["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],"dayNamesShort":["日","一","二","三","四","五","六"],"monthNames":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""],"monthNamesShort":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月",""],"timePattern":"H:mm","datePattern":"yyyy/M/d","dateTimePattern":"yyyy/M/d H:mm","timeFormat":"Clock24Hours","weekStarts":1})),DayPilot.Locale.register(new DayPilot.Locale("zh-tw",{"dayNames":["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],"dayNamesShort":["日","一","二","三","四","五","六"],"monthNames":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""],"monthNamesShort":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月",""],"timePattern":"tt hh:mm","datePattern":"yyyy/M/d","dateTimePattern":"yyyy/M/d tt hh:mm","timeFormat":"Clock12Hours","weekStarts":0})),DayPilot.Locale.US=DayPilot.Locale.find("en-us"),DayPilot.Switcher=function(e){function t(e,t,a){var n={};n.start=e,n.end=t,n.day=a,n.target=i.k.control,n.preventDefault=function(){this.preventDefault.value=!0};var o=i.G;o&&o.start===n.start&&o.end===n.end&&o.day===n.day&&o.target===n.target||(i.G=n,"function"==typeof i.onChange&&(i.onChange(n),n.preventDefault.value)||"function"==typeof i.onTimeRangeSelect&&(i.onTimeRangeSelect(n),n.preventDefault.value)||(i.k.q(i.l),"function"==typeof i.onChanged&&i.onChanged(n),"function"==typeof i.onTimeRangeSelected&&i.onTimeRangeSelected(n)))}var i=this;this.f=[],this.i=[],this.j={},this.selectedClass=null,this.k=null,this.l=DayPilot.Date.today(),this.onChange=null,this.onChanged=null,this.onSelect=null,this.j.updateMode=function(e){var t=i.j.control;t&&(t.selectMode=e,t.select(i.l))},this.addView=function(e,t){var a;if("string"==typeof e){if(a=document.getElementById(e),!a)throw"Element not found: "+e}else a=e;var n=a,o={};return o.m=!0,o.n=n.id,o.control=n,o.o=t||{},o.p=function(){n.hide?n.hide():n.nav&&n.nav.top?n.nav.top.style.display="none":n.style.display="none"},o.q=function(e){(function(){return!!n.backendUrl||!("function"!=typeof WebForm_DoCallback||!n.uniqueID)})()?n.commandCallBack&&n.commandCallBack("navigate",{"day":e}):(n.startDate=e,n.update())},o.s=function(){i.t(),n.show?n.show():n.nav&&n.nav.top?n.nav.top.style.display="":n.style.display=""},o.u=function(){if(o.o.navigatorSelectMode)return o.o.navigatorSelectMode;if(n.isCalendar)switch(n.viewType){case"Day":return"day";case"Week":return"week";case"WorkWeek":return"week";default:return"day"}else if(n.isMonth)switch(n.viewType){case"Month":return"month";case"Weeks":return"week";default:return"day"}return"day"},this.f.push(o),o},this.addTrigger=function(e,t){var a;if("string"==typeof e){if(a=document.getElementById(e),!a)throw"Element not found: "+e}else a=e;var n=this.z(t);n||(n=this.addView(t));var o={};return o.A=!0,o.B=a,o.n=a.id,o.C=n,o.D=function(e){i.show(o),i.E(o),e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},DayPilot.re(a,"click",o.D),this.i.push(o),o},this.addButton=this.addTrigger,this.select=function(e){var t=this.F(e);t?t.D():this.i.length>0&&this.i[0].D()},this.F=function(e){for(var t=0;t0){for(;e>=12;)e-=12,i++;e>12-a?(i++,a=e-(12-a)):a+=e}else{for(;e<=-12;)e+=12,i--;a+e<=0?(i--,a=12+a+e):a+=e}var n=new Date(t.getTime());n.setUTCDate(1),n.setUTCFullYear(i),n.setUTCMonth(a-1);var o=new DayPilot.Date(n).daysInMonth();return n.setUTCDate(Math.min(o,t.getUTCDate())),new DayPilot.Date(n)},DayPilot.Date.prototype.addSeconds=function(e){return e?this.addTime(1e3*e):this},DayPilot.Date.prototype.addTime=function(e){return e?(e instanceof DayPilot.Duration&&(e=e.ticks),new DayPilot.Date(this.ticks+e)):this},DayPilot.Date.prototype.addYears=function(e){var t=new Date(this.ticks),i=new Date(this.ticks),a=this.getYear()+e,n=this.getMonth();i.setUTCDate(1),i.setUTCFullYear(a),i.setUTCMonth(n);var o=new DayPilot.Date(i).daysInMonth();return i.setUTCDate(Math.min(o,t.getUTCDate())),new DayPilot.Date(i)},DayPilot.Date.prototype.dayOfWeek=function(){return new Date(this.ticks).getUTCDay()},DayPilot.Date.prototype.getDayOfWeek=function(){return new Date(this.ticks).getUTCDay()},DayPilot.Date.prototype.getDayOfYear=function(){var e=this.firstDayOfYear();return DayPilot.DateUtil.daysDiff(e,this)+1},DayPilot.Date.prototype.daysInMonth=function(){var e=new Date(this.ticks),t=e.getUTCMonth()+1,i=e.getUTCFullYear(),a=[31,28,31,30,31,30,31,31,30,31,30,31];return 2!==t?a[t-1]:i%4!==0?a[1]:i%100===0&&i%400!==0?a[1]:a[1]+1},DayPilot.Date.prototype.daysInYear=function(){var e=this.getYear();return e%4!==0?365:e%100===0&&e%400!==0?365:366},DayPilot.Date.prototype.dayOfYear=function(){return Math.ceil((this.getDatePart().getTime()-this.firstDayOfYear().getTime())/864e5)+1},DayPilot.Date.prototype.equals=function(e){if(null===e)return!1;if(e instanceof DayPilot.Date)return this===e;throw"The parameter must be a DayPilot.Date object (DayPilot.Date.equals())"},DayPilot.Date.prototype.firstDayOfMonth=function(){var e=new Date;return e.setUTCFullYear(this.getYear(),this.getMonth(),1),e.setUTCHours(0),e.setUTCMinutes(0),e.setUTCSeconds(0),e.setUTCMilliseconds(0),new DayPilot.Date(e)},DayPilot.Date.prototype.firstDayOfYear=function(){var e=this.getYear(),t=new Date;return t.setUTCFullYear(e,0,1),t.setUTCHours(0),t.setUTCMinutes(0),t.setUTCSeconds(0),t.setUTCMilliseconds(0),new DayPilot.Date(t)},DayPilot.Date.prototype.firstDayOfWeek=function(e){var t=this;if(e instanceof DayPilot.Locale)e=e.weekStarts;else if("string"==typeof e&&DayPilot.Locale.find(e)){var i=DayPilot.Locale.find(e);e=i.weekStarts}else e=e||0;for(var a=t.dayOfWeek();a!==e;)t=t.addDays(-1),a=t.dayOfWeek();return new DayPilot.Date(t)},DayPilot.Date.prototype.getDay=function(){return new Date(this.ticks).getUTCDate()},DayPilot.Date.prototype.getDatePart=function(){var e=new Date(this.ticks);return e.setUTCHours(0),e.setUTCMinutes(0),e.setUTCSeconds(0),e.setUTCMilliseconds(0),new DayPilot.Date(e)},DayPilot.Date.prototype.getYear=function(){return new Date(this.ticks).getUTCFullYear()},DayPilot.Date.prototype.getHours=function(){return new Date(this.ticks).getUTCHours()},DayPilot.Date.prototype.getMilliseconds=function(){return new Date(this.ticks).getUTCMilliseconds()},DayPilot.Date.prototype.getMinutes=function(){return new Date(this.ticks).getUTCMinutes()},DayPilot.Date.prototype.getMonth=function(){return new Date(this.ticks).getUTCMonth()},DayPilot.Date.prototype.getSeconds=function(){return new Date(this.ticks).getUTCSeconds()},DayPilot.Date.prototype.getTotalTicks=function(){return this.getTime()},DayPilot.Date.prototype.getTime=function(){return this.ticks},DayPilot.Date.prototype.getTimePart=function(){var e=this.getDatePart();return DayPilot.DateUtil.diff(this,e)},DayPilot.Date.prototype.lastDayOfMonth=function(){var e=new Date(this.firstDayOfMonth().getTime()),t=this.daysInMonth();return e.setUTCDate(t),new DayPilot.Date(e)},DayPilot.Date.prototype.weekNumber=function(){var e=this.firstDayOfYear(),t=(this.getTime()-e.getTime())/864e5;return Math.ceil((t+e.dayOfWeek()+1)/7)},DayPilot.Date.prototype.weekNumberISO=function(){var e=!1,t=this.dayOfYear(),i=this.firstDayOfYear().dayOfWeek(),a=this.firstDayOfYear().addYears(1).addDays(-1).dayOfWeek();0===i&&(i=7),0===a&&(a=7);var n=8-i;4!==i&&4!==a||(e=!0);var o=Math.ceil((t-n)/7),r=o;return n>=4&&(r+=1),r>52&&!e&&(r=1),0===r&&(r=this.firstDayOfYear().addDays(-1).weekNumberISO()),r},DayPilot.Date.prototype.toDateLocal=function(){var e=new Date(this.ticks),t=new Date;return t.setFullYear(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()),t.setHours(e.getUTCHours()),t.setMinutes(e.getUTCMinutes()),t.setSeconds(e.getUTCSeconds()),t.setMilliseconds(e.getUTCMilliseconds()),t},DayPilot.Date.prototype.toDate=function(){return new Date(this.ticks)},DayPilot.Date.prototype.toJSON=function(){return this.value},DayPilot.Date.prototype.toString=function(e,t){return e?new n(e,t).print(this):this.toStringSortable()},DayPilot.Date.prototype.toStringSortable=function(){return e(this.ticks)},DayPilot.Date.parse=function(e,t,i){return new n(t,i).parse(e)};DayPilot.Date.today=function(){return new DayPilot.Date(DayPilot.DateUtil.localToday(),!0)},DayPilot.Date.now=function(){return new DayPilot.Date},DayPilot.Date.fromYearMonthDay=function(e,t,i){t=t||1,i=i||1;var a=new Date(0);return a.setUTCFullYear(e),a.setUTCMonth(t-1),a.setUTCDate(i),new DayPilot.Date(a)},DayPilot.DateUtil={},DayPilot.DateUtil.fromStringSortable=function(e,t){if(!e)throw"Can't create DayPilot.Date from an empty string";var i=e.length,a=10===i,n=19===i,o=i>19;if(!a&&!n&&!o)throw"Invalid string format (use '2010-01-01' or '2010-01-01T00:00:00'): "+e;if(DayPilot.Date.Cache.Parsing[e]&&!t)return DayPilot.Stats.cacheHitsParsing+=1,DayPilot.Date.Cache.Parsing[e];var r=e.substring(0,4),s=e.substring(5,7),l=e.substring(8,10),d=new Date(0);if(d.setUTCFullYear(r,s-1,l),a)return DayPilot.Date.Cache.Parsing[e]=d,d;var c=e.substring(11,13),u=e.substring(14,16),h=e.substring(17,19);if(d.setUTCHours(c),d.setUTCMinutes(u),d.setUTCSeconds(h),n)return DayPilot.Date.Cache.Parsing[e]=d,d;var f=e[19],m=0;if("."===f){var p=parseInt(e.substring(20,23));d.setUTCMilliseconds(p),m=DayPilot.DateUtil.getTzOffsetMinutes(e.substring(23))}else m=DayPilot.DateUtil.getTzOffsetMinutes(e.substring(19));var v=new DayPilot.Date(d);return t||(v=v.addMinutes(-m)),d=v.toDate(),DayPilot.Date.Cache.Parsing[e]=d,d},DayPilot.DateUtil.getTzOffsetMinutes=function(e){if(DayPilot.Util.isNullOrUndefined(e)||""===e)return 0;if("Z"===e)return 0;var t=e[0],i=parseInt(e.substring(1,3)),a=parseInt(e.substring(4)),n=60*i+a;if("-"===t)return-n;if("+"===t)return n;throw"Invalid timezone spec: "+e},DayPilot.DateUtil.hasTzSpec=function(e){return!!e.indexOf("+")||!!e.indexOf("-")},DayPilot.DateUtil.daysDiff=function(e,t){if(e&&t||function(){throw"two parameters required"}(),e=new DayPilot.Date(e),t=new DayPilot.Date(t),e.getTime()>t.getTime())return null;for(var i=0,a=e.getDatePart(),n=t.getDatePart();at.getTime()?e:t},DayPilot.DateUtil.min=function(e,t){return e.getTime()0){var d=l[0],c=i(d);c?r.push(c):r.push(d),o+=d.length,n=e.length<=o}else n=!0}for(var u=0;u12||i<1)return null;var a=this.day.findValue(e),n=DayPilot.Date.fromYearMonthDay(t,i).daysInMonth();if(a<1||a>n)return null;var o=this.hours?this.hours.findValue(e):0,r=this.minutes?this.minutes.findValue(e):0,s=this.seconds?this.seconds.findValue(e):0,l=this.ampm?this.ampm.findValue(e):null;if(this.ampm&&this.hours12){var d=this.hours12.findValue(e);if(d<1||d>12)return null;o="PM"===l?12===d?12:d+12:12===d?0:d}if(o<0||o>23)return null;if(r<0||r>59)return null;if(s<0||s>59)return null;var c=new Date;return c.setUTCFullYear(t,i-1,a),c.setUTCHours(o),c.setUTCMinutes(r),c.setUTCSeconds(s),c.setUTCMilliseconds(0),new DayPilot.Date(c)},this.init()};DayPilot.ColorUtil={},DayPilot.ColorUtil.hexToRgb=function(e){if(!/^#[0-9a-f]{6}$/i.test(e))throw new DayPilot.Exception("Invalid color, only full hex color string accepted, eg. '#ffaaff'.");return e=e.replace("#",""),{r:parseInt(e.substring(0,2),16),g:parseInt(e.substring(2,4),16),b:parseInt(e.substring(4,6),16)}},DayPilot.ColorUtil.rgbToHex=function(e){return"#"+i(e.r)+i(e.g)+i(e.b)},DayPilot.ColorUtil.adjustLuminance=function(e,t){return{r:e.r+t,g:e.g+t,b:e.b+t}},DayPilot.ColorUtil.darker=function(e,t){var i=DayPilot.ColorUtil.hexToRgb(e);t=t||1;var a=17,n=t*a,o=DayPilot.ColorUtil.adjustLuminance(i,-n);return DayPilot.ColorUtil.rgbToHex(o)},DayPilot.ColorUtil.lighter=function(e,t){return"number"!=typeof t&&(t=1),DayPilot.ColorUtil.darker(e,-t)},DayPilot.ColorUtil.pl=function(e){var t=DayPilot.ColorUtil.hexToRgb(e),i=t.r/255,a=t.g/255,n=t.b/255;return Math.sqrt(.299*i*i+.587*a*a+.114*n*n)},DayPilot.ColorUtil.contrasting=function(e,t,i){var a=DayPilot.ColorUtil.pl(e);return t=t||"#ffffff",i=i||"#000000",a>.5?i:t},DayPilot.Event=function(e,t,i){var a=this;this.calendar=t,this.data=e?e:{},this.part=i?i:{},"undefined"==typeof this.data.id&&(this.data.id=this.data.value);var n={},o=["id","text","start","end","resource"];this.isEvent=!0,this.temp=function(){if(n.dirty)return n;for(var e=0;ethis.businessEndsHour?24-this.businessBeginsHour+this.businessEndsHour:this.businessEndsHour-this.businessBeginsHour},this.na=function(){return this.la()/18e5},this.la=function(){var e=0;return e="BusinessHoursNoScroll"===this.heightSpec?this.ma():24,60*e*60*1e3},this.oa=function(){return"BusinessHoursNoScroll"===this.heightSpec?this.businessBeginsHour:0},this.pa=function(){return 2===n.api},this.eventClickCallBack=function(e,t){this.R("EventClick",t,e)},this.eventClickPostBack=function(e,t){this.P("EventClick",t,e)},this.qa=function(e){var t=this,i=t.event;if(n.pa()){var a={};if(a.e=i,a.originalEvent=e,a.meta=e.metaKey,a.ctrl=e.ctrlKey,a.control=n,a.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof n.onEventClick&&(n.ra.apply(function(){n.onEventClick(a)}),a.preventDefault.value))return;switch(n.eventClickHandling){case"CallBack":n.eventClickCallBack(i);break;case"PostBack":n.eventClickPostBack(i);break;case"ContextMenu":var o=i.client.contextMenu();o?o.show(i):n.contextMenu&&n.contextMenu.show(i)}"function"==typeof n.onEventClicked&&n.ra.apply(function(){n.onEventClicked(a)})}else switch(n.eventClickHandling){case"PostBack":n.eventClickPostBack(i);break;case"CallBack":n.eventClickCallBack(i);break;case"JavaScript":n.onEventClick(i)}},this.sa=function(e){var t=this.event;if(e.stopPropagation&&e.stopPropagation(),!t.client.rightClickEnabled())return!1;var i={};if(i.e=t,i.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof n.onEventRightClick&&(n.onEventRightClick(i),i.preventDefault.value))return!1;switch(n.eventRightClickHandling){case"ContextMenu":var a=t.client.contextMenu();a?a.show(t):n.contextMenu&&n.contextMenu.show(this.event)}return"function"==typeof n.onEventRightClicked&&n.onEventRightClicked(i),e.preventDefault&&e.preventDefault(),!1},this.eventDeleteCallBack=function(e,t){this.R("EventDelete",t,e)},this.eventDeletePostBack=function(e,t){this.P("EventDelete",t,e)},this.ta=function(e){if(n.pa()){var t={};if(t.e=e,t.control=n,t.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof n.onEventDelete&&(n.ra.apply(function(){n.onEventDelete(t)}),t.preventDefault.value))return;switch(n.eventDeleteHandling){case"CallBack":n.eventDeleteCallBack(e);break;case"PostBack":n.eventDeletePostBack(e);break;case"Update":n.events.remove(e)}"function"==typeof n.onEventDeleted&&n.ra.apply(function(){n.onEventDeleted(t)})}else switch(n.eventDeleteHandling){case"PostBack":n.eventDeletePostBack(e);break;case"CallBack":n.eventDeleteCallBack(e);break;case"JavaScript":n.onEventDelete(e)}},this.eventResizeCallBack=function(e,t,i,a){if(!t)throw"newStart is null";if(!i)throw"newEnd is null";var n={};n.e=e,n.newStart=t,n.newEnd=i,this.R("EventResize",a,n)},this.eventResizePostBack=function(e,t,i,a){if(!t)throw"newStart is null";if(!i)throw"newEnd is null";var n={};n.e=e,n.newStart=t,n.newEnd=i,this.P("EventResize",a,n)},this.I=function(e,t,i,a){var o=1,r=new Date,s=new Date,l=e.start(),d=e.end();if("top"===a){var c=l.getDatePart(),u=Math.floor((i-o)/n.cellHeight),h=30*u,f=60*h*1e3,m=60*n.oa()*60*1e3;r=c.addTime(f+m),s=e.end()}else if("bottom"===a){var c=d.getDatePart(),u=Math.floor((i+t-o)/n.cellHeight),h=30*u,f=60*h*1e3,m=60*n.oa()*60*1e3;r=l,s=c.addTime(f+m)}if(n.pa()){var p={};if(p.e=e,p.control=n,p.newStart=r,p.newEnd=s,p.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof n.onEventResize&&(n.ra.apply(function(){n.onEventResize(p)}),p.preventDefault.value))return;switch(n.eventResizeHandling){case"PostBack":n.eventResizePostBack(e,r,s);break;case"CallBack":n.eventResizeCallBack(e,r,s);break;case"Update":e.start(r),e.end(s),n.events.update(e)}"function"==typeof n.onEventResized&&n.ra.apply(function(){n.onEventResized(p)})}else switch(n.eventResizeHandling){case"PostBack":n.eventResizePostBack(e,r,s);break;case"CallBack":n.eventResizeCallBack(e,r,s);break;case"JavaScript":n.onEventResize(e,r,s)}},this.eventMovePostBack=function(e,t,i,a,n){if(!t)throw"newStart is null";if(!i)throw"newEnd is null";var o={};o.e=e,o.newStart=t,o.newEnd=i,this.P("EventMove",n,o)},this.eventMoveCallBack=function(e,t,i,a,n){if(!t)throw"newStart is null";if(!i)throw"newEnd is null";var o={};o.e=e,o.newStart=t,o.newEnd=i,this.R("EventMove",n,o)},this.K=function(e,t,i,a){var o=1,r=Math.floor((i-o)/n.cellHeight),s=30*r*60*1e3,l=e.start(),d=e.end(),c=new Date;l instanceof DayPilot.Date&&(l=l.toDate()),c.setTime(Date.UTC(l.getUTCFullYear(),l.getUTCMonth(),l.getUTCDate()));var u=l.getTime()-(c.getTime()+3600*l.getUTCHours()*1e3+30*Math.floor(l.getUTCMinutes()/30)*60*1e3),h=d.getTime()-l.getTime(),f=this.ua[t],m=f.id,p=f.start.getTime(),v=new Date;v.setTime(p+s+u);var y=new DayPilot.Date(v),g=y.addTime(h);if(n.pa()){var b={};if(b.e=e,b.newStart=y,b.newEnd=g,b.newResource=m,b.ctrl=a.ctrlKey,b.shift=a.shiftKey,b.control=n,b.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof n.onEventMove&&(n.ra.apply(function(){n.onEventMove(b)}),b.preventDefault.value))return;switch(n.eventMoveHandling){case"PostBack":n.eventMovePostBack(e,y,g,f.id);break;case"CallBack":n.eventMoveCallBack(e,y,g,f.id);break;case"Update":e.start(y),e.end(g),e.resource(m),n.events.update(e)}"function"==typeof n.onEventMoved&&n.ra.apply(function(){n.onEventMoved(b)})}else switch(n.eventMoveHandling){case"PostBack":n.eventMovePostBack(e,y,g,f.id);break;case"CallBack":n.eventMoveCallBack(e,y,g,f.id);break;case"JavaScript":n.onEventMove(e,y,g,f.id,!1)}},this.timeRangeSelectedPostBack=function(e,t,i,a){var n={};n.start=e,n.end=t,this.P("TimeRangeSelected",a,n)},this.timeRangeSelectedCallBack=function(e,t,i,a){var n={};n.start=e,n.end=t,this.R("TimeRangeSelected",a,n)},this.L=function(e,t,i){if(e=new DayPilot.Date(e),t=new DayPilot.Date(t),this.pa()){var a={};if(a.start=e,a.end=t,a.resource=i,a.control=n,a.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof n.onTimeRangeSelect&&(n.ra.apply(function(){n.onTimeRangeSelect(a)}),a.preventDefault.value))return;switch(n.timeRangeSelectedHandling){case"PostBack":n.timeRangeSelectedPostBack(e,t);break;case"CallBack":n.timeRangeSelectedCallBack(e,t)}"function"==typeof n.onTimeRangeSelected&&n.ra.apply(function(){n.onTimeRangeSelected(a)})}else switch(n.timeRangeSelectedHandling){case"PostBack":n.timeRangeSelectedPostBack(e,t);break;case"CallBack":n.timeRangeSelectedCallBack(e,t);break;case"JavaScript":n.onTimeRangeSelected(e,t)}},this.va=function(e){if(!t.selecting&&"Disabled"!==n.timeRangeSelectedHandling){var i=e.which;if(1===i||0===i)return t.firstMousePos=DayPilot.mc(e),t.selecting={},t.selecting.calendar=n,t.selectedCells&&(n.clearSelection(),t.selectedCells=[]),t.column=t.getColumn(this),t.selectedCells.push(this),t.firstSelected=this,t.topSelectedCell=this,t.bottomSelectedCell=this,n.wa(),!1}},this.wa=function(){this.getSelection();!function(){var e=t.topSelectedCell,i=t.bottomSelectedCell,a=function(){if(e.data)return e.data.x;for(var t=e.parentNode.cells,i=0;ithis.max-1)},i.putIntoLine=function(e){for(var t=0;to.part.top+o.part.height-1))return!1}return!0},i.push(e),this.lines.push(i),this.lines.length-1},i.events.push(e),i.min=e.part.top,i.max=e.part.top+e.part.height,this.blocks.push(i),this.blocks.length-1},t.putIntoLine=function(e){for(var t=0;to.part.top+o.part.height-1))return!1}return!0},i.push(e),this.lines.push(i),this.lines.length-1},t},this.Ba=function(){var e=[],t=this.startDate.getDatePart(),i=this.days;switch(this.viewType){case"Day":i=1;break;case"Week":i=7;var a=o.ba();t=t.firstDayOfWeek(a);break;case"WorkWeek":i=5,t=t.firstDayOfWeek(1)}"BusinessHoursNoScroll"===this.heightSpec&&(t=t.addHours(this.businessBeginsHour));for(var r=0;r0;)this.fasterDispose||DayPilot.pu(e.rows[0]),e.deleteRow(0);this.tableCreated=!0;for(var r=o.length,s=this.nav.events;s&&s.rows&&s.rows.length>0;)this.fasterDispose||DayPilot.pu(s.rows[0]),s.deleteRow(0);for(var r=o.length,l=s.insertRow(-1),d=0;dd&&(l=d-t.originalTop),t.resizingShadow.style.height=l+"px"}else if("top"===t.resizing.dpBorder){var c=Math.floor((t.originalTop+s-r+o/2)/o)*o+r;ct.originalTop+t.originalHeight-o&&(c=t.originalTop+t.originalHeight-o);var l=t.originalHeight-(c-t.originalTop);ld&&(c=d-p),DayPilot.Util.addClass(t.moving,n.J("_event_moving_source")),t.movingShadow.parentNode.style.display="none",t.movingShadow.style.top=c+"px",t.movingShadow.parentNode.style.display="";var v=m.clientWidth/m.rows[0].cells.length,y=Math.floor((n.coords.x-45)/v);y<0&&(y=0),y=0&&t.movingShadow.column!==y&&(t.movingShadow.column=y,t.moveShadow(m.rows[0].cells[y]))}else if(t.selecting){var a=DayPilot.mc(e),g=n.za.getCellCoords(),b=t.column,D=n.nav.main.rows[g.y].cells[b];a.y=this.businessEndsHour||6===e.getDayOfWeek()||0===e.getDayOfWeek()):e.getHours()>=this.businessBeginsHour||e.getHours()0;)this.fasterDispose||DayPilot.pu(e.rows[0]),e.deleteRow(0);this.headerCreated=!0;this.Ra(t)},this.loadingStart=function(){this.loadingLabelVisible&&(this.nav.loading.innerHTML=this.loadingLabelText,this.nav.loading.style.top=this.headerHeight+5+"px",this.nav.loading.style.display="")},this.commandCallBack=function(e,t){var i={};i.command=e,this.R("Command",t,i)},this.loadingStop=function(e){this.callbackTimeout&&window.clearTimeout(this.callbackTimeout),this.nav.loading.style.display="none"},this.Va=function(){ +var e=this.nav.scroll;e.onscroll||(e.onscroll=function(){n.Wa()});var t="undefined"!=typeof this.Xa.scrollpos?this.Xa.scrollpos:this.initScrollPos;t&&("Auto"===t&&(t="BusinessHours"===this.heightSpec?2*this.cellHeight*this.businessBeginsHour:0),e.root=this,0===e.scrollTop&&(e.scrollTop=t))},this.callbackError=function(e,t){alert("Error!\r\nResult: "+e+"\r\nContext:"+t)},this.Ya=function(){var e=DayPilot.sw(this.nav.scroll),t=this.nav.cornerRight;t&&(t.style.width=e+"px")},this.Za=function(){t.globalHandlers||(t.globalHandlers=!0,DayPilot.re(document,"mouseup",t.gMouseUp),DayPilot.re(window,"unload",t.gUnload))},this.events={},this.events.add=function(e){var t=null;if(e instanceof DayPilot.Event)t=e.data;else{if("object"!=typeof e)throw"DayPilot.Calendar.events.add() expects an object or DayPilot.Event instance.";t=e}n.events.list||(n.events.list=[]),n.events.list.push(t),n.$a({"eventsOnly":!0}),n.ra.notify()},this.events.find=function(e){if(!n.events.list)return null;if("function"==typeof e){for(var t=e,i=0;i-1?"&"+s:"?"+s,DayPilot.Http.ajax({"method":"GET","url":r,"success":o,"error":a})}},this._a=function(){if(n.nav.top.className!==n.J("_main")){n.nav.top.className=n.J("_main");var e=n.nav.corner;e.className=n.J("_corner"),e.firstChild.className=n.J("_corner_inner");var t=n.nav.cornerRight;t&&(t.className=n.J("_cornerright"),t.firstChild.className=n.J("_cornerright_inner"))}},this.update=function(e){if(n.N)throw new DayPilot.Exception("You are trying to update a DayPilot.Calendar instance that has been disposed.");n.ab(e),n.$a()},this.$a=function(e){if(this.Aa){var e=e||{},t=!e.eventsOnly;n.bb(),n.V(),n.nav.top.style.cursor="auto",t&&(n.ca(),n.fa(),n.ga(),n.ha(),n.ia(),n.Oa(),n.Ya(),n._a(),n.cb()),n.da(),n.ea(),n.ja(),n.clearSelection(),this.visible?this.show():this.hide()}},this.db=null,this.ab=function(e){if(e){var t={"events":{"preInit":function(){var e=this.data||[];DayPilot.isArray(e.list)?n.events.list=e.list:n.events.list=e}},"columns":{"preInit":function(){n.columns.list=this.data}}};this.db=t;for(var i in e)if(t[i]){var a=t[i];a.data=e[i],a.preInit&&a.preInit()}else n[i]=e[i]}},this.eb=function(){var e=this.db;for(var t in e){var i=e[t];i.postInit&&i.postInit()}},this.fb=function(){if(this.id&&this.id.tagName)this.nav.top=this.id;else{if("string"!=typeof this.id)throw"DayPilot.Calendar() constructor requires the target element or its ID as a parameter";if(this.nav.top=document.getElementById(this.id),!this.nav.top)throw"DayPilot.Calendar: The placeholder element not found: '"+e+"'."}},this.gb={},this.gb.events=[],this.hb=function(e){var t=this.gb.events,i=this.events.list[e],a={};for(var o in i)a[o]=i[o];if("function"==typeof this.onBeforeEventRender){var r={};r.control=n,r.data=a,this.onBeforeEventRender(r)}t[e]=a},this.da=function(){var e=this.events.list;if(n.gb.events=[],e){if(!DayPilot.isArray(e))throw new DayPilot.Exception("DayPilot.Calendar.events.list expects an array object. You supplied: "+typeof e);var t=e.length,i=864e5;this.cache.pixels={};var a=[];this.scrollLabels=[],this.minStart=1e4,this.maxEnd=0;for(var o=0;o=f);if("Resources"===n.viewType&&(b=b&&d.id===r.resource),b){var D=new DayPilot.Event(r,n);D.part.dayIndex=o,D.part.start=ug?r.end:h;var x=this.getPixels(D.part.start,d.start),w=this.getPixels(D.part.end,d.start),C=x.top,P=w.top;if(C===P&&(x.cut||w.cut))continue;var k=w.boxBottom;D.part.top=Math.floor(C/this.cellHeight)*this.cellHeight+1,D.part.height=Math.max(Math.ceil(k/this.cellHeight)*this.cellHeight-D.part.top,this.cellHeight-1)+1,D.part.barTop=Math.max(C-D.part.top-1,0),D.part.barHeight=Math.max(P-C-2,1);var p=D.part.top,v=D.part.top+D.part.height;p>l.maxStart&&(l.maxStart=p),vthis.maxEnd&&(this.maxEnd=v),d.events.push(D),"function"==typeof this.onBeforeEventRender&&(D.cache=this.gb.events[m]),D.part.start.getTime()===y&&D.part.end.getTime()===g&&(a[m]=!0)}}}}for(var o=0;o0&&(this.nav.scroll.style.height=e+"px")},this.ra={},this.ra.scope=null,this.ra.notify=function(){n.ra.scope&&n.ra.scope["$apply"]()},this.ra.apply=function(e){e()},this.Wa=function(){if(n.nav.scroll){var e=n.nav.scroll.scrollTop,t=e/(2*n.cellHeight);n.Xa.scrollHour=t}},this.cb=function(){var e=0;"number"==typeof n.Xa.scrollHour?e=2*n.cellHeight*n.Xa.scrollHour:"Auto"===n.initScrollPos&&(e="BusinessHours"===this.heightSpec?2*this.cellHeight*this.businessBeginsHour:0),n.nav.scroll.scrollTop=e},this.kb=function(){return!(!this.backendUrl&&"function"!=typeof WebForm_DoCallback)&&("undefined"==typeof n.events.list||!n.events.list)},this.s=function(){"hidden"===this.nav.top.style.visibility&&(this.nav.top.style.visibility="visible")},this.show=function(){n.visible=!0,n.nav.top.style.display="",this.Ya()},this.hide=function(){n.visible=!1,n.nav.top.style.display="none"},this.lb=function(){this.bb(),this.ca(),this.Fa(),this.fa(),this.ga(),this.Ya(),this.Va(),this.Za(),t.register(this),this.mb(),this.R("Init")},this.Xa={},this.nb=function(){this.Xa.themes=[],this.Xa.themes.push(this.theme||this.cssClassPrefix)},this.ob=function(){for(var e=this.Xa.themes,t=0;t0&&e.offsetHeight>0)},this.mb=function(){var e=n.sb;e()||(n.U=setInterval(function(){e()&&(n.Va(),n.Ya(),clearInterval(n.U))},100))},this.Ja=function(e,t){return n._.aa()?DayPilot.Util.escapeTextHtml(e,t):DayPilot.Util.isNullOrUndefined(t)?DayPilot.Util.isNullOrUndefined(e)?"":e:t},this.internal={},this.internal.loadOptions=n.ab,this.internal.xssTextHtml=n.Ja,this.init=function(){this.fb();var e=this.kb();return this.nb(),e?void this.lb():(this.bb(),this.ca(),this.da(),this.Fa(),this.fa(),this.ga(),this.s(),this.Ya(),this.Va(),this.Za(),t.register(this),this.events&&(this.ea(),this.ja()),this.pb(),this.qb(),this.mb(),this.Aa=!0,this)},this.Init=this.init,this.ab(i)},DayPilot.CalendarColumn=function(e,t){var i=this;i.id=e.id,i.name=e.name,i.data=e.data,i.start=new DayPilot.Date(e.start),i.calendar=t,i.toJSON=function(){var e={};return e.id=this.id,this.start&&(e.start=this.start.toString()),e.name=this.name,e}},DayPilot.Calendar=t.Calendar,"undefined"!=typeof jQuery&&!function(e){e.fn.daypilotCalendar=function(e){var t=null,i=this.each(function(){if(!this.daypilot){var i=new DayPilot.Calendar(this.id);this.daypilot=i;for(name in e)i[name]=e[name];i.init(),t||(t=i)}});return 1===this.length?t:i}}(jQuery),function(){var e=DayPilot.am();e&&e.directive("daypilotCalendar",["$parse",function(e){return{"restrict":"E","template":"
","replace":!0,"link":function(t,i,a){var n=new DayPilot.Calendar(i[0]);n.ra.scope=t,n.init();var o=a["id"];o&&(t[o]=n);var r=a["publishAs"];if(r){(0,e(r).assign)(t,n)}for(var s in a)0===s.indexOf("on")&&!function(i){n[i]=function(n){var o=e(a[i]);t["$apply"](function(){o(t,{"args":n})})}}(s);var l=t["$watch"],d=a["config"]||a["daypilotConfig"],c=a["events"]||a["daypilotEvents"];l.call(t,d,function(e){for(var t in e)n[t]=e[t];n.update(),n.qb()},!0),l.call(t,c,function(e){n.events.list=e,n.update()},!0)}}}])}()}}(),"undefined"==typeof DayPilot)var DayPilot={};if(function(){"undefined"!=typeof DayPilot.DatePicker&&DayPilot.DatePicker.close||(DayPilot.DatePicker=function(e){this.v="2024.3.539-lite";var t="navigator_"+(new Date).getTime(),i=this;this.onShow=null,this.onTimeRangeSelect=null,this.onTimeRangeSelected=null,this.prepare=function(){if(this.locale="en-us",this.target=null,this.targetAlignment="left",this.resetTarget=!0,this.pattern=this._.locale().datePattern,this.theme="navigator_default",this.patterns=[],this.zIndex=null,e)for(var t in e)this[t]=e[t]},this.init=function(){this.date=new DayPilot.Date(this.date);var e=this.tb();this.resetTarget&&!e?this.ub(this.date):this.resetTarget||(i.date=e);var t=this.B();return t&&t.addEventListener("input",function(){i.date=i.tb(),i.date&&i.navigator.select(i.date,{dontNotify:!0})}),document.addEventListener("mousedown",function(){i.close()}),this},this.close=function(){this.sb&&(this.sb=!1,this.navigator&&this.navigator.dispose(),this.div.innerHTML="",this.div&&this.div.parentNode===document.body&&document.body.removeChild(this.div))},this.setDate=function(e){this.date=new DayPilot.Date(e),this.ub(this.date)},this.tb=function(){var e=this.B();if(!e)return this.date;var t=null;if(t="INPUT"===e.tagName?e.value:e.innerText,!t)return null;for(var a=DayPilot.Date.parse(t,i.pattern),n=0;nA-M&&0!==A){var r=i-a-(A-M)+E;d.style.top=i-r+"px"}else d.style.top=i+"px";if("right"===o.align&&(e-=T),e-n>H-T&&0!==H){var s=e-n-(H-T)+E;d.style.left=e-s+"px"}else d.style.left=e+"px"}(),o.parentLink){var N=o.parentLink,I=parseInt(new DayPilot.StyleReader(d).get("border-top-width")),R=DayPilot.abs(o.parentLink.parentNode),O=R.x+N.offsetWidth,z=R.y-I;O+T>H&&(O=Math.max(0,R.x-T));var U=document.body.scrollTop+document.documentElement.scrollTop;z+M-U>A&&(z=Math.max(0,A-M+U)),d.style.left=O+"px",d.style.top=z+"px"}d.style.display="",this.addShadow(d),this.wb.div=d,o.submenu||(DayPilot.Menu.active=this)}},this.yb=function(e,t){var i=e,n=t.source;if((!a.wb.submenu||a.wb.submenu.item!==e)&&(a.wb.submenu&&a.wb.submenu.item!==e&&(DayPilot.Util.removeClass(a.wb.submenu.link.parentNode,a.xb("item_haschildren_active")),a.wb.submenu.menu.hide(),a.wb.submenu=null),e.items)){var o=a.cloneOptions();o.items=e.items,a.wb.submenu={},a.wb.submenu.menu=new DayPilot.Menu(o),a.wb.submenu.menu.zb=a,a.wb.submenu.menu.show(n,{"submenu":!0,"parentLink":t,"parentItem":i}),a.wb.submenu.item=e,a.wb.submenu.link=t,DayPilot.Util.addClass(t.parentNode,a.xb("item_haschildren_active"))}},this.xb=function(e){var t=this.theme||this.cssClassPrefix,i=this.cssOnly?"_":"";return t?t+i+e:""},this.cloneOptions=function(){return DayPilot.Util.copyProps(o,{},["cssClassPrefix","theme","hideAfter","hideOnMouseOut","zIndex"])},this.hide=function(e){e=e||{},this.wb.submenu&&this.wb.submenu.menu.hide();var i=t.waitingSubmenu;if(i&&(t.waitingSubmenu=null,clearTimeout(i.timeout)),this.removeShadow(),this.wb.div&&this.wb.div.parentNode===document.body&&document.body.removeChild(this.wb.div),n&&(DayPilot.de(n),n=null),a.wb.visible=!1,a.wb.source=null,a.zb&&e.hideParent&&a.zb.hide(e),DayPilot.Menu.active===a&&(DayPilot.Menu.active=null),"function"==typeof this.onHide){var o={};this.onHide(o)}},this.delayedHide=function(e){t.hideTimeout=setTimeout(function(){a.hide(e)},a.hideAfter)},this.cancelHideTimeout=function(){clearTimeout(t.hideTimeout)},this.init=function(e){return t.mouseMove(e),this},this.addShadow=function(e){},this.removeShadow=function(){};var o=DayPilot.isArray(i)?null:i;if(o)for(var r in o)this[r]=o[r]},DayPilot.MenuBar=function(e,t){var i=this;t=t||{},this.items=[],this.theme="menubar_default",this.windowMargin=0,this.nav={},this.elements={},this.elements.items=DayPilot.list(),this.k=null,this.Aa=!1;for(var a in t)this[a]=t[a];this.Ab=function(e){return this.theme+"_"+e},this.s=function(){this.nav.top=document.getElementById(e);var t=this.nav.top;t.className=this.Ab("main"),DayPilot.list(i.items).forEach(function(e){var a=document.createElement("span");a.innerHTML=DayPilot.Util.escapeTextHtml(e.text,e.html),a.className=i.Ab("item"),e.cssClass&&a.classList.add(e.cssClass),a.data=e,a.onclick=function(t){if(i.active&&i.active.item===e)i.Bb();else if(e.children)return void i.Cb(a);if("function"==typeof e.onClick){var n={};n.item=e,n.originalEvent=t,e.onClick(n)}},a.onmousedown=function(e){e.stopPropagation()},a.onmouseover=function(){i.active&&i.active.item!==e&&i.Cb(a)},t.appendChild(a),i.elements.items.push(a)})},this.Bb=function(){var e=i.Ab("item_active");i.elements.items.forEach(function(t){DayPilot.Util.removeClass(t,e)}),i.active&&i.active.menu&&i.active.menu.hide(),i.active=null},this.Db=function(e){return!!i.active&&i.active.item===e.data},this.Cb=function(e){if(!i.Db(e)){i.Bb();var t=e.data,a=i.active={};a.item=t,a.div=e;var n=i.Ab("item_active");DayPilot.Util.addClass(e,n);var o=DayPilot.abs(e);if(t.children){a.menu=new DayPilot.Menu({"items":t.children});var r=o.x;"right"===t.align&&(r+=o.w),a.menu.show(null,{"x":r,"y":o.y+o.h,"align":t.align,"windowMargin":i.windowMargin})}DayPilot.MenuBar.active=i}},this.init=function(){return this.s(),this.Aa=!0,this},this.dispose=function(){this.Aa&&(this.nav.top.innerHTML="",this.elements.items=[])}},DayPilot.MenuBar.deactivate=function(){DayPilot.MenuBar.active&&(DayPilot.MenuBar.active.Bb(),DayPilot.MenuBar.active=null)},t.menuClean=function(){"undefined"!=typeof DayPilot.Menu.active&&DayPilot.Menu.active&&(DayPilot.Menu.active.hide(),DayPilot.Menu.active=null)},t.mouseDown=function(e){"undefined"!=typeof t&&(t.menuClean(),DayPilot.MenuBar.deactivate())},t.mouseMove=function(e){"undefined"!=typeof t&&(t.mouse=t.mousePosition(e))},t.touchMove=function(e){"undefined"!=typeof t&&(t.mouse=t.touchPosition(e))},t.touchStart=function(e){"undefined"!=typeof t&&(t.mouse=t.touchPosition(e))},t.touchEnd=function(e){},t.touchPosition=function(e){if(!e||!e.touches)return null;var t=e.touches[0],i={};return i.x=t.pageX,i.y=t.pageY,i},t.mousePosition=function(e){return DayPilot.mo3(null,e)},DayPilot.Menu.touchPosition=function(e){e.touches&&(t.mouse=t.touchPosition(e))},DayPilot.Menu.hide=function(e){if(e=e||{},e.calendar){var i=DayPilot.Menu.active;if(i){var a=i.wb.source;a&&a.calendar===e.calendar&&t.menuClean()}}else t.menuClean()},t.handlersRegistered||"undefined"==typeof document||(DayPilot.re(document,"mousemove",t.mouseMove),DayPilot.re(document,"mousedown",t.mouseDown),DayPilot.re(document,"touchmove",t.touchMove),DayPilot.re(document,"touchstart",t.touchStart),DayPilot.re(document,"touchend",t.touchEnd),t.handlersRegistered=!0),DayPilot.Menu.def={}}}(DayPilot),"undefined"==typeof DayPilot&&(DayPilot={}),function(DayPilot){"use strict";function e(t,i,a){var n=i.indexOf(".");if(n===-1)return void("__proto__"!==i&&"constructor"!==i&&(t[i]=a));var o=i.substring(0,n);if("__proto__"!==o&&"constructor"!==o){var r=i.substring(n+1),s=t[o];"object"==typeof s&&null!==s||(t[o]={},s=t[o]),e(s,r,a)}}function t(e,i,a){i=i||{},a=a||"";for(var n in e){var o=e[n];"object"==typeof o?"[object Array]"===Object.prototype.toString.call(o)?i[a+n]=o:o&&o.toJSON?i[a+n]=o.toJSON():t(o,i,a+n+"."):i[a+n]=o}return i}if(!DayPilot.ModalStatic){DayPilot.ModalStatic={},DayPilot.ModalStatic.list=[],DayPilot.ModalStatic.hide=function(){if(this.list.length>0){var e=this.list.pop();e&&e.hide()}},DayPilot.ModalStatic.remove=function(e){for(var t=DayPilot.ModalStatic.list,i=0;i0&&(t[t.length-1].result=e)},DayPilot.ModalStatic.displayed=function(e){for(var t=DayPilot.ModalStatic.list,i=0;i0){var e=this.list[this.list.length-1];e&&e.stretch()}},DayPilot.ModalStatic.last=function(){var e=DayPilot.ModalStatic.list;return e.length>0?e[e.length-1]:null};var i=function(){if("undefined"==typeof window){var e={};return e.add=function(){},e.commit=function(){},e}var t=document.createElement("style");t.setAttribute("type","text/css"),t.styleSheet||t.appendChild(document.createTextNode("")),(document.head||document.getElementsByTagName("head")[0]).appendChild(t);var i=!!t.styleSheet,e={};return e.rules=[],e.commit=function(){try{i&&(t.styleSheet.cssText=this.rules.join("\n"))}catch(e){}},e.add=function(e,a,n){if(i)return void this.rules.push(e+"{"+a+"}");if(t.sheet.insertRule)"undefined"==typeof n&&(n=t.sheet.cssRules.length),t.sheet.insertRule(e+"{"+a+"}",n);else{if(!t.sheet.addRule)throw"No CSS registration method found";t.sheet.addRule(e,a,n)}},e},a="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB3aWR0aD0iMTAiCiAgIGhlaWdodD0iMTUiCj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDUpIj4KICAgIDxwYXRoCiAgICAgICBpZD0icGF0aDMxNzMiCiAgICAgICBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojOTk5OTk5O3N0cm9rZS13aWR0aDoxLjg1MTk2ODUzO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIKICAgICAgIGQ9Ik0gMC45NTQxNDgzOCwwLjY4MTYwMzEgNS4wMzkwNjI1LDUuNDExNTM4NiA5LjEyMzk3NjYsMC42ODE2MDMxIgogICAgICAgIC8+CiAgPC9nPgo8L3N2Zz4K",n=new i;n.add(".modal_default_main","border: 10px solid #ccc; max-width: 90%;"),n.add(".modal_default_main:focus","outline: none;"),n.add(".modal_default_content","padding: 10px 0px;"),n.add(".modal_default_inner","padding: 20px;"),n.add(".modal_default_input","padding: 10px 0px;"),n.add(".modal_default_buttons","margin-top: 10px;"),n.add(".modal_default_buttons","padding: 10px 0px;"),n.add(".modal_default_form_item","padding: 10px 0px; position: relative;"),n.add(".modal_default_form_item_level1","border-left: 2px solid #ccc; margin-left: 10px; padding-left: 20px;"),n.add(".modal_default_form_item.modal_default_form_title","font-size: 1.5rem; font-weight: bold;"),n.add(".modal_default_form_item input[type=text]","width: 100%; box-sizing: border-box;"),n.add(".modal_default_form_item textarea","width: 100%; height: 200px; box-sizing: border-box;"),n.add(".modal_default_form_item input[type=select]","width: 100%; box-sizing: border-box;"),n.add(".modal_default_form_item label","display: block;"),n.add(".modal_default_form_item select","width: 100%; box-sizing: border-box;"),n.add(".modal_default_form_item_label","margin: 2px 0px;"),n.add(".modal_default_form_item_image img","max-width: 100%; height: auto;"),n.add(".modal_default_form_item_invalid",""),n.add(".modal_default_form_item_invalid_message","position: absolute; right: 0px; top: 9px; background-color: red; color: #ffffff; padding: 2px; border-radius: 2px;"),n.add(".modal_default_background","opacity: 0.5; background-color: #000;"),n.add(".modal_default_ok","padding: 3px; width: 80px;"),n.add(".modal_default_cancel","padding: 3px; width: 80px;"),n.add(".modal_default_form_item_date","position: relative;"),n.add(".modal_default_form_item_date:after","content: ''; position: absolute; right: 7px; top: 50%; margin-top: 3px; width: 10px; height: 15px; background-image:url("+"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB3aWR0aD0iMTAiCiAgIGhlaWdodD0iMTUiCj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDUpIj4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojY2NjY2NjO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjM4MDM3MzM2O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDE5MjgiCiAgICAgICB3aWR0aD0iOS45MTUzMDYxIgogICAgICAgaGVpZ2h0PSIxMS4zNjkzNyIKICAgICAgIHg9IjAuMTE3MTg3NSIKICAgICAgIHk9Ii0zLjAwOTk5NTciCiAgICAgICByeT0iMS4zMTE4NTA1IiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNjY2NjY2M7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNTk4MTQwMTI7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MTkzMCIKICAgICAgIHdpZHRoPSIxLjUzNDQxMzYiCiAgICAgICBoZWlnaHQ9IjIuMjE5ODI1IgogICAgICAgeD0iMi4xNTU4NDgzIgogICAgICAgeT0iLTQuMzkzNzAwMSIKICAgICAgIHJ5PSIwLjY3MTc4OTE3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSItMS4xNjU4NDY2IgogICAgICAgeD0iMS41MjM5NTA2IgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QxOTQ4IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjY3MTc4OTE3IgogICAgICAgeT0iLTQuMzkzNzAwMSIKICAgICAgIHg9IjYuNDUyNzIzNSIKICAgICAgIGhlaWdodD0iMi4yMTk4MjUiCiAgICAgICB3aWR0aD0iMS41MzQ0MTM2IgogICAgICAgaWQ9InJlY3QyMDAzIgogICAgICAgc3R5bGU9ImZpbGw6I2NjY2NjYztmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS41OTgxNDAxMjtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MjAwNSIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHg9IjQuMjE5MjYzMSIKICAgICAgIHk9Ii0xLjE2NTg0NjYiCiAgICAgICByeT0iMC4yOTYwMTQ3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSItMS4xNjU4NDY2IgogICAgICAgeD0iNi45OTI3MDA2IgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QyMDA3IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MjAxMyIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHg9IjEuNTIzOTUwNiIKICAgICAgIHk9IjEuODAyOTAzNCIKICAgICAgIHJ5PSIwLjI5NjAxNDciIC8+CiAgICA8cmVjdAogICAgICAgcnk9IjAuMjk2MDE0NyIKICAgICAgIHk9IjEuODAyOTAzNCIKICAgICAgIHg9IjQuMjE5MjYzMSIKICAgICAgIGhlaWdodD0iMS44Mjk5MDkxIgogICAgICAgd2lkdGg9IjEuODM0MjI1MSIKICAgICAgIGlkPSJyZWN0MjAxNSIKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgLz4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjQyMTg5MTkzO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDIwMTciCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB4PSI2Ljk5MjcwMDYiCiAgICAgICB5PSIxLjgwMjkwMzQiCiAgICAgICByeT0iMC4yOTYwMTQ3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSI0LjczMjU5MDciCiAgICAgICB4PSIxLjU2MzAxMzEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBpZD0icmVjdDIwMTkiCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjQyMTg5MTkzO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiIC8+CiAgICA8cmVjdAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgaWQ9InJlY3QyMDIxIgogICAgICAgd2lkdGg9IjEuODM0MjI1MSIKICAgICAgIGhlaWdodD0iMS44Mjk5MDkxIgogICAgICAgeD0iNC4yNTgzMjU2IgogICAgICAgeT0iNC43MzI1OTA3IgogICAgICAgcnk9IjAuMjk2MDE0NyIgLz4KICAgIDxyZWN0CiAgICAgICByeT0iMC4yOTYwMTQ3IgogICAgICAgeT0iNC43MzI1OTA3IgogICAgICAgeD0iNy4wMzE3NjMxIgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QyMDIzIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogIDwvZz4KPC9zdmc+Cg=="+")"), +"undefined"!=typeof navigator&&navigator.userAgent.indexOf("Edge")!==-1&&n.add(".modal_default_form_item_date input::-ms-clear","display: none;"),n.add(".modal_default_form_item_scrollable_scroll","width: 100%; height: 200px; box-sizing: border-box; border: 1px solid #ccc; overflow-y: auto;"),n.add(".modal_default_form_item_scrollable_scroll_content","padding: 5px;"),n.add(".modal_default_form_item_searchable","position: relative;"),n.add(".modal_default_form_item_searchable_icon",""),n.add(".modal_default_form_item_searchable_icon:after","content:''; position: absolute; right: 5px; top: 50%; margin-top: -8px; width: 10px; height: 15px; background-image:url("+a+");"),n.add(".modal_default_form_item_searchable_list","box-sizing: border-box; border: 1px solid #999; max-height: 150px; overflow-y: auto;"),n.add(".modal_default_form_item_searchable_list_item","background: white; padding: 2px; cursor: default;"),n.add(".modal_default_form_item_searchable_list_item_highlight","background: #ccc;"),n.add(".modal_default_form_item_time","position: relative;"),n.add(".modal_default_form_item_time_icon",""),n.add(".modal_default_form_item_time_icon:after","content:''; position: absolute; right: 5px; top: 50%; margin-top: -8px; width: 10px; height: 15px; background-image:url("+a+");"),n.add(".modal_default_form_item_time_list","box-sizing: border-box; border: 1px solid #999; max-height: 150px; overflow-y: auto;"),n.add(".modal_default_form_item_time_list_item","background: white; padding: 2px; cursor: default;"),n.add(".modal_default_form_item_time_list_item_highlight","background: #ccc;"),n.add(".modal_default_form_item_datetime_parent","display: flex;"),n.add(".modal_default_form_item_datetime .modal_default_form_item_time_main","margin-left: 5px;"),n.add(".modal_default_form_item_datetime input[type='text'].modal_default_input_date ",""),n.add(".modal_default_form_item_tabular_main","margin-top: 10px;"),n.add(".modal_default_form_item_tabular_table","display: table; width: 100%; xbackground-color: #fff; border-collapse: collapse;"),n.add(".modal_default_form_item_tabular_tbody","display: table-row-group;"),n.add(".modal_default_form_item_tabular_row","display: table-row;"),n.add(".modal_default_form_item_tabular_row.modal_default_form_item_tabular_header",""),n.add(".modal_default_form_item_tabular_cell.modal_default_form_item_tabular_rowaction","padding: 0px; width: 23px;"),n.add(".modal_default_form_item_tabular_cell","display: table-cell; border: 0px; padding: 2px 2px 2px 0px; cursor: default; vertical-align: bottom;"),n.add(".modal_default_form_item_tabular_header .modal_default_form_item_tabular_cell","padding-left: 0px; padding-bottom: 0px;"),n.add(".modal_default_form_item_tabular_table input[type=text], .modal_default_form_item_tabular_table input[type=number]","width:100%; box-sizing: border-box;"),n.add(".modal_default_form_item_tabular_table select","width:100%; height:100%; box-sizing: border-box;"),n.add(".modal_default_form_item_tabular_plus","display: inline-block; background-color: #ccc; color: white; width: 20px; height: 20px; border-radius: 10px; box-sizing: border-box; position: relative; margin-left: 3px; margin-top: 3px; cursor: pointer;"),n.add(".modal_default_form_item_tabular_plus:after","content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTAnIGhlaWdodD0nMTAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTSA1LjAgMC41IEwgNS4wIDkuNSBNIDAuNSA1LjAgTCA5LjUgNS4wJyBzdHlsZT0nZmlsbDpub25lO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpidXR0JyAvPjwvc3ZnPg==\")"),n.add(".modal_default_form_item_tabular_delete","display: inline-block; background-color: #ccc; color: white; width: 20px; height: 20px; border-radius: 10px; box-sizing: border-box; position: relative; margin-left: 3px; margin-top: 3px; cursor: pointer;"),n.add(".modal_default_form_item_tabular_delete:after","content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTAnIGhlaWdodD0nMTAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTSAwLjUgMC41IEwgOS41IDkuNSBNIDAuNSA5LjUgTCA5LjUgMC41JyBzdHlsZT0nZmlsbDpub25lO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpidXR0JyAvPjwvc3ZnPg==\")"),n.add(".modal_default_form_item_tabular_disabled .modal_default_form_item_tabular_plus","display: none;"),n.add(".modal_default_form_item_tabular_plus_max.modal_default_form_item_tabular_plus","display: none;"),n.add(".modal_default_form_item_tabular_disabled .modal_default_form_item_tabular_delete","visibility: hidden;"),n.add(".modal_default_form_item_tabular_empty","height: 1px; margin: 5px 23px 5px 0px; background-color: #ccc;"),n.add(".modal_default_form_item_tabular_spacer .modal_default_form_item_tabular_cell","padding: 0px;"),n.add(".modal_min_main","border: 1px solid #ccc; max-width: 90%;"),n.add(".modal_min_background","opacity: 0.5; background-color: #000;"),n.add(".modal_min_ok","padding: 3px 10px;"),n.add(".modal_min_cancel","padding: 3px 10px;"),n.add(".navigator_modal_main","border-left: 1px solid #c0c0c0;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;background-color: white;color: #000000; box-sizing: content-box;"),n.add(".navigator_modal_main *, .navigator_modal_main *:before, .navigator_modal_main *:after","box-sizing: content-box;"),n.add(".navigator_modal_month","font-size: 11px;"),n.add(".navigator_modal_day","color: black;"),n.add(".navigator_modal_weekend","background-color: #f0f0f0;"),n.add(".navigator_modal_dayheader","color: black;"),n.add(".navigator_modal_line","border-bottom: 1px solid #c0c0c0;"),n.add(".navigator_modal_dayother","color: gray;"),n.add(".navigator_modal_todaybox","border: 1px solid red;"),n.add(".navigator_modal_title, .navigator_modal_titleleft, .navigator_modal_titleright","border-top: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;color: #333;background: #f3f3f3;"),n.add(".navigator_modal_busy","font-weight: bold;"),n.add(".navigator_modal_cell","text-align: center;"),n.add(".navigator_modal_select .navigator_modal_cell_box","background-color: #FFE794; opacity: 0.5;"),n.add(".navigator_modal_title","text-align: center;"),n.add(".navigator_modal_titleleft, .navigator_modal_titleright","text-align: center;"),n.add(".navigator_modal_dayheader","text-align: center;"),n.add(".navigator_modal_weeknumber","text-align: center;"),n.add(".navigator_modal_cell_text","cursor: pointer;"),n.commit(),DayPilot.Modal=function(e){this.autoFocus=!0,this.focus=null,this.autoStretch=!0,this.autoStretchFirstLoadOnly=!1,this.className=null,this.theme="modal_default",this.disposeOnClose=!0,this.dragDrop=!0,this.loadingHtml=null,this.maxHeight=null,this.scrollWithPage=!0,this.useIframe=!0,this.zIndex=99999,this.left=null,this.width=600,this.top=20,this.height=200,this.locale=null,this.closed=null,this.onClose=null,this.onClosed=null,this.onShow=null;var t=this;this.id="_"+(new Date).getTime()+"n"+10*Math.random(),this.Eb=!1,this.Fb=null,this.Gb=null,this.showHtml=function(e){if(DayPilot.ModalStatic.displayed(this))throw"This modal dialog is already displayed.";if(this.div||this.Hb(),this.$a(),this.useIframe){var t=function(e,t){return function(){e.setInnerHTML(e.id+"iframe",t)}};window.setTimeout(t(this,e),0)}else e.nodeType?this.div.appendChild(e):this.div.innerHTML=e;this.$a(),this.Ib(),this.Jb()},this.showUrl=function(e){if(DayPilot.ModalStatic.displayed(this))throw"This modal dialog is already displayed.";if(this.useIframe){this.div||this.Hb();var i=this.loadingHtml;i&&(this.iframe.src="about:blank",this.setInnerHTML(this.id+"iframe",i)),this.re(this.iframe,"load",this.Kb),this.iframe.src=e,this.$a(),this.Ib(),this.Jb()}else t.Lb({"url":e,"success":function(e){var i=e.request.responseText;t.showHtml(i)},"error":function(e){t.showHtml("Error loading the modal dialog")}})},this.Jb=function(){if("function"==typeof t.onShow){var e={};e.root=t.Mb(),e.modal=t,t.onShow(e)}},this.Mb=function(){return t.iframe?t.iframe.contentWindow.document:t.div},this.Lb=function(e){var t=new XMLHttpRequest;if(t){var i=e.method||"GET",a=e.success||function(){},n=e.error||function(){},o=e.data,r=e.url;t.open(i,r,!0),t.setRequestHeader("Content-type","text/plain"),t.onreadystatechange=function(){if(4===t.readyState)if(200===t.status||304===t.status){var e={};e.request=t,a(e)}else if(n){var e={};e.request=t,n(e)}else window.console&&console.log("HTTP error "+t.status)},4!==t.readyState&&("object"==typeof o&&(o=JSON.stringify(o)),t.send(o))}},this.$a=function(){delete this.result;var e=window,i=document,a=e.pageYOffset?e.pageYOffset:i.documentElement&&i.documentElement.scrollTop?i.documentElement.scrollTop:i.body.scrollTop;this.theme&&(this.hideDiv.className=this.theme+"_background"),this.zIndex&&(this.hideDiv.style.zIndex=this.zIndex),this.hideDiv.style.display="",window.setTimeout(function(){t.hideDiv&&(t.hideDiv.onclick=function(){t.hide({"backgroundClick":!0})})},500),this.theme?this.div.className=this.theme+"_main":this.div.className="",this.className&&(this.div.className+=" "+this.className),this.left?this.div.style.left=this.left+"px":this.div.style.marginLeft="-"+Math.floor(this.width/2)+"px",this.div.style.position="absolute",this.div.style.boxSizing="content-box",this.div.style.top=a+this.top+"px",this.div.style.width=this.width+"px",this.zIndex&&(this.div.style.zIndex=this.zIndex),this.height&&(this.useIframe||!this.autoStretch?this.div.style.height=this.height+"px":this.div.style.height=""),this.useIframe&&this.height&&(this.iframe.style.height=this.height+"px"),this.div.style.display="",this.Ob(),DayPilot.ModalStatic.remove(this),DayPilot.ModalStatic.list.push(this)},this.Kb=function(){t.iframe.contentWindow.modal=t,t.autoStretch&&t.stretch()},this.stretch=function(){var e=function(){return t.Nb().y},i=function(){return t.Nb().x};if(this.useIframe){for(var a=i()-40,n=this.width;nt.clientWidth},this.Qb=function(){for(var e=this.iframe.contentWindow.document,t="BackCompat"===e.compatMode?e.body:e.documentElement,i=t.scrollHeight,a=e.body.children,n=0;nt.clientHeight},this.Nb=function(){var e=document;if("CSS1Compat"===e.compatMode&&e.documentElement&&e.documentElement.clientWidth){var t=e.documentElement.clientWidth,i=e.documentElement.clientHeight;return{x:t,y:i}}var t=e.body.clientWidth,i=e.body.clientHeight;return{x:t,y:i}},this.Ib=function(){this.Eb||(this.re(window,"resize",this.Rb),this.re(window,"scroll",this.Sb),this.dragDrop&&(this.re(document,"mousemove",this.Tb),this.re(document,"mouseup",this.Ub)),this.Eb=!0)},this.Vb=function(){this.ue(window,"resize",this.Rb),this.ue(window,"scroll",this.Sb),this.dragDrop&&(this.ue(document,"mousemove",this.Tb),this.ue(document,"mouseup",this.Ub)),this.Eb=!1},this.Wb=function(e){e.target===t.div&&(e.preventDefault(),t.div.style.cursor="move",t.Xb(),t.Gb=t.mc(e||window.event),t.Fb={x:t.div.offsetLeft,y:t.div.offsetTop})},this.Tb=function(e){if(t.Gb){var e=e||window.event,i=t.mc(e),a=i.x-t.Gb.x,n=i.y-t.Gb.y;t.div.style.marginLeft="0px",t.div.style.top=t.Fb.y+n+"px",t.div.style.left=t.Fb.x+a+"px"}},this.Ub=function(e){t.Gb&&(t.Yb(),t.div.style.cursor=null,t.Gb=null)},this.Xb=function(){if(this.useIframe){var e=document.createElement("div");e.style.backgroundColor="#ffffff",e.style.filter="alpha(opacity=80)",e.style.opacity="0.80",e.style.width="100%",e.style.height=this.height+"px",e.style.position="absolute",e.style.left="0px",e.style.top="0px",this.div.appendChild(e),this.mask=e}},this.Yb=function(){this.useIframe&&(this.div.removeChild(this.mask),this.mask=null)},this.Rb=function(){t.Zb(),t.Ob()},this.Sb=function(){t.Zb()},this.Ob=function(){if(!t.left&&t.div){var e=t.div.offsetWidth;t.div.style.marginLeft="-"+Math.floor(e/2)+"px"}},this.Zb=function(){if(t.hideDiv&&t.div&&"none"!==t.hideDiv.style.display&&"none"!==t.div.style.display){var e=t.$b.scrollY();t.scrollWithPage||(t.div.style.top=e+t.top+"px")}},this.$b={},this.$b.container=function(){return t.container||document.body},this.$b.scrollY=function(){var e=t.$b.container();return e===document.body?window.pageYOffset?window.pageYOffset:document.documentElement&&document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop:e.scrollTop},this.re=function(e,t,i){e.addEventListener?e.addEventListener(t,i,!1):e.attachEvent&&e.attachEvent("on"+t,i)},this.ue=function(e,t,i){e.removeEventListener?e.removeEventListener(t,i,!1):e.detachEvent&&e.detachEvent("on"+t,i)},this.mc=function(e){return e.pageX||e.pageY?{x:e.pageX,y:e.pageY}:{x:e.clientX+document.documentElement.scrollLeft,y:e.clientY+document.documentElement.scrollTop}},this.abs=function(e){for(var t={x:e.offsetLeft,y:e.offsetTop};e.offsetParent;)e=e.offsetParent,t.x+=e.offsetLeft,t.y+=e.offsetTop;return t},this.Hb=function(){var e=t.$b.container(),i=e===document.body,a=i?"fixed":"absolute",n=document.createElement("div");n.id=this.id+"hide",n.style.position=a,n.style.left="0px",n.style.top="0px",n.style.right="0px",n.style.bottom="0px",n.oncontextmenu=function(){return!1},n.onmousedown=function(){return!1},e.appendChild(n);var o=document.createElement("div");o.id=this.id+"popup",o.style.position=a,o.style.left="50%",o.style.top="0px",o.style.backgroundColor="white",o.style.width="50px",o.style.height="50px",this.dragDrop&&(o.onmousedown=this.Wb),o.addEventListener("keydown",function(e){e.stopPropagation()});var r=null;this.useIframe&&(r=document.createElement("iframe"),r.id=this.id+"iframe",r.name=this.id+"iframe",r.frameBorder="0",r.style.width="100%",r.style.height="50px",o.appendChild(r)),e.appendChild(o),this.div=o,this.iframe=r,this.hideDiv=n},this.setInnerHTML=function(e,i){var a=window.frames[e],n=a.contentWindow||a.document||a.contentDocument;n.document&&(n=n.document),null==n.body&&n.write(""),i.nodeType?n.body.appendChild(i):n.body.innerHTML=i,t.autoStretch&&(t.autoStretchFirstLoadOnly&&t._b||(t.stretch(),t._b=!0))},this.close=function(e){this.result=e,this.hide()},this.closeSerialized=function(){for(var e=t.Mb(),i=e.querySelectorAll("input, textarea, select"),a={},n=0;n0?DayPilot.ModalStatic.list[DayPilot.ModalStatic.list.length-1]:parent&&parent.DayPilot&&parent.DayPilot.ModalStatic&&parent.DayPilot.ModalStatic.list[parent.DayPilot.ModalStatic.list.length-1]},DayPilot.Modal.Experimental={},DayPilot.Modal.Experimental.Form=r,"undefined"==typeof DayPilot.getPromise&&(DayPilot.getPromise=function(e){return"undefined"!=typeof Promise?new Promise(e):(DayPilot.Promise=function(e){var t=this;this.then=function(t,i){return t=t||function(){},i=i||function(){},e(t,i),DayPilot.getPromise(e)},this["catch"]=function(i){return t.then(null,i),DayPilot.getPromise(e)}},new DayPilot.Promise(e))});var r=function(e){this.form=[],this.data={},this.theme="form_default",this.zIndex=99999,this.locale="en-us",this.plugins={},this.onKey=null,this.dc=[],this.ec=null,this.canceling=!1,this.fc=[],this.f=[],this.gc=null,e=e||{};for(var t in e)this[t]=e[t]};r.prototype.create=function(){return this.load(),this.render(),this.gc},r.prototype.render=function(){var e=this;this.gc=document.createElement("div"),this.dc.forEach(function(t){e.createView(t)}),this.applyState()},r.prototype.createView=function(e){var t=this.theme,i=this,a=document.createElement("div");if(a.className=t+"_form_item "+t+"_form_item_level"+e.level,e.interactive||"title"!==e.type?a.className+=" "+t+"_form_item_"+e.type:a.className+=" "+t+"_form_title",e.data.cssClass&&(a.className+=" "+e.data.cssClass),!e.isValue){var n=document.createElement("div");n.className=t+"_form_item_label",n.innerText=e.text,a.appendChild(n)}var o=this.createInteractive(e);o.onInput=function(e){if(e=e||{},i.hc(o,{"debounce":!e.immediate}),"function"==typeof i.onChange){var t={};t.result=i.serialize(),i.onChange(t)}},o.onBlur=function(){i.canceling||i.hc(o)},o.apply(e),o.gc=a,o.row=e,o.element&&a.appendChild(o.element),this.f.push(o),this.gc.appendChild(a)},r.prototype.validate=function(){var e=this,t=!0;return this.f.forEach(function(i){var a=e.hc(i);t=t&&a}),t},r.prototype.hc=function(e,t){function i(){e.ic&&(e.ic.remove(),e.ic=null),e.gc.classList.add(u);var t=document.createElement("div");t.classList.add(h),t.innerText=c.message,e.ic=t,e.gc.appendChild(t)}t=t||{};var a=t.debounce,n=t.silent,o=e.row,r=!0,s="function"==typeof o.data.onValidate?o.data.onValidate:null,l="function"==typeof o.data.validate?o.data.validate:null,d=s||l;if(d){var c={};c.valid=!0,c.value=e.save()[o.field],c.message="Error",c.values=this.serialize(),c.result=this.serialize(),d(c);var u=this.theme+"_form_item_invalid",h=this.theme+"_form_item_invalid_message";if(c.valid)clearTimeout(this.fc[o.field]),e.ic&&(e.ic.remove(),e.ic=null),e.gc.classList.remove(u);else if(!n)if(a){var f=1e3;clearTimeout(this.fc[o.field]),this.fc[o.field]=setTimeout(function(){i()},f)}else i();r=c.valid}return r},r.prototype.load=function(){var e=this;this.form.forEach(function(t){e.processFormItem(t,0)});var i;try{var a=JSON.stringify(this.data);i=t(JSON.parse(a))}catch(e){throw new Error("The 'data' object is not serializable (it may contain circular dependencies): "+e)}for(var n in i)this.setValue(n,i[n])},r.prototype.setValue=function(e,t){this.dc.forEach(function(i){i.applyValue(e,t)})},r.prototype.updateDependentState=function(){var e=this,t=[!0];(this.ec?this.ec:this.dc).forEach(function(i){var a=e.updateState(i,{enabled:t[i.level]&&!i.data.disabled});a.isValue&&(t[a.level+1]=a.enabled&&a.checked)})},r.prototype.processFormItem=function(e,t){var i=this,a=this.getFieldType(e),n=[];if("radio"===a){if(e.name){var o=new s;o.field=e.id,o.data=e,o.level=t,o.type="label",o.interactive=!1,o.text=e.name,i.dc.push(o),n.push(o)}e.options.forEach(function(o){var r=new s;r.field=e.id,r.data=o,r.level=t,r.type=a,r.isValue=!0,r.text=o.name,r.resolved=o.id,i.dc.push(r),n.push(r),o.children&&o.children.forEach(function(e){var a=i.processFormItem(e,t+1);n=n.concat(a)})})}else if("title"===a){var o=new s;o.field=e.id,o.data=e,o.level=t,o.type=a,o.interactive=!1,o.text=e.name,i.dc.push(o),n.push(o)}else if("image"===a){var o=new s;o.isValue=!0,o.field=e.id,o.data=e,o.level=t,o.type=a,o.interactive=!1,o.text=null,i.dc.push(o),n.push(o)}else if("html"===a){var o=new s;o.isValue=!0,o.field=e.id,o.data=e,o.level=t,o.type=a,o.interactive=!1,o.text=null,i.dc.push(o),n.push(o)}else if("scrollable"===a){var o=new s;o.isValue=!0,o.field=e.id,o.data=e,o.level=t,o.type=a,o.interactive=!1,o.text=null,i.dc.push(o),n.push(o)}else{var o=new s;o.field=e.id,o.data=e,o.level=t,o.type=a,o.text=e.name,o.children=[],i.dc.push(o),n.push(o)}return"checkbox"===a&&(o.isValue=!0,o.resolved=!0,e.children&&e.children.forEach(function(e){var a=i.processFormItem(e,t+1);n=n.concat(a)})),n},r.prototype.doOnKey=function(e){if("function"==typeof this.onKey){var t={key:e};this.onKey(t)}},r.prototype.createInteractive=function(e){var t=this,i={"label":function(){return new l},"title":function(){return new l},"image":function(){var t=new l,i=document.createElement("img");return i.src=e.data.image,t.element=i,t},"html":function(){var t=new l,i=document.createElement("div");return"string"==typeof e.data.text?i.innerText=e.data.text:"string"==typeof e.data.html&&(i.innerHTML=e.data.html),t.element=i,t},"scrollable":function(){var i=new l,a=document.createElement("div");a.className=t.theme+"_form_item_scrollable_scroll",e.data.height&&(a.style.height=e.data.height+"px");var n=document.createElement("div");return n.className=t.theme+"_form_item_scrollable_scroll_content","string"==typeof e.data.text?n.innerText=e.data.text:"string"==typeof e.data.html&&(n.innerHTML=e.data.html),a.appendChild(n),i.element=a,i},"text":function(){var i=new l;i.apply=function(e){i.row=e;var t=i.element;t.value=e.value,t.disabled=!e.enabled};var a=document.createElement("input");return a.name=e.field,a.type="text",a.autocomplete="off",a.onkeydown=function(e){var i=!1;switch(e.keyCode){case 13:t.doOnKey("Enter");break;case 27:t.doOnKey("Escape");break;default:i=!0}i||(e.preventDefault(),e.stopPropagation())},a.oninput=function(e){i.onInput()},a.onblur=function(e){i.onBlur()},i.element=a,i.canFocus=function(){return!i.element.disabled},i.focus=function(){i.element.focus(),i.element.setSelectionRange(0,i.element.value.length)},i.save=function(){var t={};return t[e.field]=a.value,t},i},"textarea":function(){var i=new l;i.apply=function(e){i.row=e;var t=i.element;t.value=e.value,t.disabled=!e.enabled};var a=document.createElement("textarea");return a.name=e.field,e.data.height&&(a.style.height=e.data.height+"px"),a.onkeydown=function(e){var i=!1;switch(e.keyCode){case 13:(e.ctrlKey||e.metaKey)&&t.doOnKey("Enter"),i=!1;break;case 27:t.doOnKey("Escape");break;default:i=!0}i||e.stopPropagation()},a.oninput=function(e){i.onInput()},a.onblur=function(e){i.onBlur()},i.element=a,i.canFocus=function(){return!i.element.disabled},i.focus=function(){i.element.focus(),i.element.setSelectionRange(0,0)},i.save=function(){var t={};return t[e.field]=a.value,t},i},"date":function(){var i=new l;i.apply=function(e){i.row=e;var a=i.element,n=i.picker;e.data.dateFormat&&(n.pattern=e.data.dateFormat);var o=e.data.locale||t.locale;o&&(n.locale=o),a.disabled=!e.enabled,n.date=new DayPilot.Date(e.value);var r=new DayPilot.Date(e.value).toString(e.data.dateFormat||n.pattern,n.locale);a.value=r};var a=document.createElement("input");a.name=e.field;var n=new DayPilot.DatePicker({target:a,theme:"navigator_modal",zIndex:t.zIndex+1,resetTarget:!1,targetAlignment:"left",onTimeRangeSelect:function(e){i.onInput({"immediate":!0})}});return a.picker=n,a.className=t.theme+"_input_date",a.type="text",a.onkeydown=function(e){var i=!1;switch(e.keyCode){case 13:n.visible?n.close():t.doOnKey("Enter");break;case 27:n.visible?n.close():t.doOnKey("Escape");break;case 9:n.close(),i=!0;break;default:i=!0}i||(e.preventDefault(),e.stopPropagation())},a.onfocus=function(){n.show()},a.onclick=function(){n.show()},a.oninput=function(e){i.onInput()},a.onblur=function(e){i.onBlur()},i.element=a,i.picker=n,i.canFocus=function(){return!i.element.disabled},i.focus=function(){i.element.focus()},i.save=function(){var t=n.date?n.date.toString():null,i={};return i[e.field]=t,i},i},"time":function(){return t.jc(e)},"datetime":function(){return t.kc(e)},"select":function(){var t=new l;t.apply=function(e){t.row=e;var i=t.element;i.value=e.value,i.disabled=!e.enabled};var i=document.createElement("select");return i.name=e.field,e.data.options&&e.data.options.forEach&&e.data.options.forEach(function(e){var t=document.createElement("option");t.innerText=e.name||e.id,t.value=e.id,t.lc=e.id,i.appendChild(t)}),i.onchange=function(e){t.onInput({"immediate":!0})},i.onblur=function(e){t.onBlur()},t.element=i,t.canFocus=function(){return!t.element.disabled},t.focus=function(){t.element.focus()},t.save=function(){var t=null,a=i.options[i.selectedIndex];a&&"undefined"!=typeof a.lc&&(t=a.lc);var n={};return n[e.field]=t,n},t},"searchable":function(){var i=new l;i.apply=function(e){i.row=e;var t=i.searchable;t.disabled=!e.enabled,t.select(e.value)};var a=new d({data:e.data.options||[],name:e.field,theme:t.theme+"_form_item_searchable",listZIndex:t.zIndex+1,onSelect:function(e){e.ui&&i.onInput({"immediate":!0})}}),n=a.create();return i.element=n,i.searchable=a,i.canFocus=function(){return!i.searchable.disabled},i.focus=function(){i.searchable.focus()},i.save=function(){var t=a.selected&&a.selected.id,i={};return i[e.field]=t,i},i},"radio":function(){var i=new l;i.apply=function(e){i.row=e;var t=i.radio;t.checked=e.checked,t.disabled=!e.enabled};var a=document.createElement("label"),n=document.createElement("input");n.type="radio",n.name=e.field,n.lc=e.resolved,n.onchange=function(e){var a=i.row;t.findRowsByField(a.field).forEach(function(e){t.updateState(e,{checked:!1})}),t.updateState(a,{checked:!0}),t.applyState(),i.onInput({"immediate":!0})},n.onblur=function(e){i.onBlur()},a.appendChild(n);var o=document.createTextNode(e.text);return a.append(o),i.element=a,i.radio=n,i.canFocus=function(){return!1},i.focus=function(){i.radio.focus()},i.save=function(){if(!n.checked)return{};var t=n.lc,i={};return i[e.field]=t,i},i},"checkbox":function(){var i=new l;i.apply=function(e){i.row=e;var t=i.checkbox;t.checked=e.checked,t.disabled=!e.enabled};var a=document.createElement("label"),n=document.createElement("input");n.type="checkbox",n.name=e.field,n.lc=e.resolved,n.onchange=function(e){var a=i.row;t.updateState(a,{checked:this.checked}),t.applyState(),i.onInput({"immediate":!0})},n.onblur=function(e){i.onBlur()},a.appendChild(n);var o=document.createTextNode(e.text);return a.append(o),i.element=a,i.checkbox=n,i.canFocus=function(){return!1},i.focus=function(){i.checkbox.focus()},i.save=function(){var t=n.checked,i={};return i[e.field]=t,i},i},"table":function(){var i=new l;i.apply=function(e){i.row=e;var t=i.table;t.disabled=!e.enabled,t.load(e.value||[])};var a=new c({name:e.field,form:t,theme:t.theme+"_form_item_tabular",item:e.data,onInput:function(e){i.onInput()}}),n=a.create();return i.element=n,i.table=a,i.canFocus=function(){return!1},i.focus=function(){i.table.focus()},i.save=function(){var t=a.save(),i={};return i[e.field]=t,i},i}};return t.plugins&&t.plugins[e.type]?t.plugins[e.type](e):i[e.type](); +},r.prototype.jc=function(e){var t=this,i=new l;i.apply=function(e){i.row=e;var t=i.searchable;t.disabled=!e.enabled,t.select(e.value)};var a=[],n=e.data.timeInterval||15;[1,5,10,15,20,30,60].includes(n)||(n=15);for(var o=60/n,r=e.data.locale||t.locale,s=DayPilot.Locale.find(r)||DayPilot.Locale.US,c=DayPilot.Date.today(),u=0;u<24*o;u++){var h=c.addMinutes(n*u),f={};f.name=h.toString(e.data.timeFormat||s.timePattern,s),f.id=h.toString("HH:mm"),a.push(f)}var m=new d({data:a,name:e.field,theme:t.theme+"_form_item_time",listZIndex:t.zIndex+1,strategy:"startsWith",onSelect:function(e){e.ui&&i.onInput({"immediate":!0})}}),p=m.create();return i.element=p,i.searchable=m,i.canFocus=function(){return!i.searchable.disabled},i.focus=function(){i.searchable.focus()},i.save=function(){var t=m.selected&&m.selected.id,i={};return i[e.field]=t,i},i},r.prototype.kc=function(e){var t=this,i=new l;i.apply=function(e){i.row=e;var a=i.searchable;a.disabled=!e.enabled;var n=new DayPilot.Date(e.value).toString("HH:mm");a.select(n);var o=i.dateInput,r=i.picker;e.data.dateFormat&&(r.pattern=e.data.dateFormat);var s=e.data.locale||t.locale;if(s){var l=DayPilot.Locale.find(s)||DayPilot.Locale.US;r.locale=s,r.pattern=l.datePattern}o.disabled=!e.enabled,r.date=new DayPilot.Date(e.value);var d=new DayPilot.Date(e.value).toString(e.data.dateFormat||r.pattern,r.locale);o.value=d};var a=function(){var a=document.createElement("input");a.name=e.field;var n=new DayPilot.DatePicker({target:a,theme:"navigator_modal",zIndex:t.zIndex+1,resetTarget:!1,targetAlignment:"left",onTimeRangeSelect:function(e){i.onInput({"immediate":!0})}});return a.picker=n,a.className=t.theme+"_input_date",a.type="text",a.onkeydown=function(e){var i=!1;switch(e.keyCode){case 13:n.visible?n.close():t.doOnKey("Enter");break;case 27:n.visible?n.close():t.doOnKey("Escape");break;case 9:n.close(),i=!0;break;default:i=!0}i||(e.preventDefault(),e.stopPropagation())},a.onfocus=function(){n.show()},a.onclick=function(){n.show()},a.oninput=function(e){i.onInput()},a.onblur=function(e){i.onBlur()},i.dateInput=a,i.picker=n,a}(),n=function(){var a=[],n=e.data.timeInterval||15;[1,5,10,15,20,30,60].includes(n)||(n=15);for(var o=60/n,r=e.data.locale||t.locale,s=DayPilot.Locale.find(r)||DayPilot.Locale.US,l=DayPilot.Date.today(),c=0;c<24*o;c++){var u=l.addMinutes(n*c),h={};h.name=u.toString(e.data.timeFormat||s.timePattern,s),h.id=u.toString("HH:mm"),a.push(h)}var f=new d({data:a,name:e.field,theme:t.theme+"_form_item_time",listZIndex:t.zIndex+1,strategy:"startsWith",onSelect:function(e){e.ui&&i.onInput({"immediate":!0})}});return i.searchable=f,f.create()}(),o=document.createElement("div");return o.className=t.theme+"_form_item_datetime_parent",o.appendChild(a),o.appendChild(n),i.element=o,i.canFocus=function(){return!i.searchable.disabled},i.focus=function(){i.dateInput.focus()},i.save=function(){var t=i.searchable.selected&&i.searchable.selected.id,a=i.picker.date?i.picker.date.toString():null,n=new DayPilot.Date(a).getDatePart(),o=DayPilot.Date.parse(n.toString("yyyy-dd-MM ")+t,"yyyy-dd-MM HH:mm"),r={};return r[e.field]=o,r},i},r.prototype.findRowsByField=function(e){return this.dc.filter(function(t){return t.field===e})},r.prototype.findViewById=function(e,t){return this.f.find(function(i){return i.row.field===e&&("radio"!==i.row.type||i.row.resolved===t)})},r.prototype.firstFocusable=function(){return this.f.find(function(e){return e.canFocus&&e.canFocus()})},r.prototype.updateState=function(e,t){var i=this.ec?this.ec:this.dc,a=i.indexOf(e);return this.ec=i.map(function(i){if(i!==e)return i;if(e.propsEqual(t))return e;var a=e.clone();for(var n in t)a[n]=t[n];return a}),this.ec[a]},r.prototype.updateInteractive=function(e){var t=this.ec.indexOf(e);this.f[t].apply(e)},r.prototype.applyState=function(){var e=this;if(this.updateDependentState(),this.ec){this.ec.filter(function(t,i){return e.dc[i]!==t}).forEach(function(t){e.updateInteractive(t)}),this.dc=this.ec,this.ec=null}},r.prototype.getFieldType=function(e){return["text","date","select","searchable","radio","checkbox","table","title","image","html","textarea","scrollable","time","datetime"].indexOf(e.type)!==-1?e.type:e.type&&this.plugins&&this.plugins[e.type]?e.type:e.image?"image":e.html||e.text?"html":e.id?e.options?"searchable":e.dateFormat?"date":e.columns?"table":"text":"title"},r.prototype.serialize=function(){var e={};return this.f.forEach(function(t){var i=t.save();for(var a in i)e[a]=i[a]}),e};var s=function(){this.id=this.guid(),this.field=null,this.data=null,this.type=null,this.level=0,this.enabled=!0,this.value=null,this.text=null,this.interactive=!0,this.isValue=!1,this.checked=!1,this.resolved=null};s.prototype.clone=function(){var e=new s;for(var t in this)"id"!==t&&(e[t]=this[t]);return e},s.prototype.propsEqual=function(e){for(var t in e)if(this[t]!==e[t])return!1;return!0},s.prototype.guid=function(){var e=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)};return""+e()+e()+"-"+e()+"-"+e()+"-"+e()+"-"+e()+e()+e()},s.prototype.applyValue=function(e,t){this.field===e&&(this.value=t,this.isValue&&t===this.resolved&&(this.checked=!0))};var l=function(){this.element=null,this.canFocus=function(){return!1},this.apply=function(e){},this.focus=function(){},this.save=function(){return{}}},d=function(e){this.data=[],this.name=null,this.theme="searchable_default",this.nc=!1,this.listZIndex=1e5,this.onSelect=null,this.oc=null,this.pc=null,this.qc=!1,this.rc=null,this.sc=null,this.o=[],this.tc=null,e=e||{};var t=this,i={"selected":{post:function(e){"object"==typeof e&&e.id?t.oc=e:"string"!=typeof e&&"number"!=typeof e||t.select(e)}}};Object.defineProperty(this,"selected",{get:function(){return this.oc}}),Object.defineProperty(this,"disabled",{get:function(){return this.nc},set:function(e){this.nc=e,this.rc&&(this.rc.disabled=e,e&&this.uc())}});for(var a in e)i[a]||(this[a]=e[a]);for(var a in e)i[a]&&i[a].post(e[a])};d.prototype.select=function(e){return this.oc=this.data.find(function(t){return t.id===e}),this.vc(!1),this},d.prototype.create=function(){function e(e){var i=l.strategy;"includes"!==l.strategy&&"startsWith"!==l.strategy&&(i="includes"),e=e||i||"includes",h.style.display="",h.style.top=m.offsetHeight+"px",h.style.left="0px",h.style.width=m.offsetWidth+"px",h.innerHTML="",h.addEventListener("mousedown",function(e){e.preventDefault()}),l.pc=null,l.o=[];var n=null;l.data.forEach(function(i){var o=i.name||i.id;if("includes"===e){if(o.toLowerCase().indexOf(m.value.toLowerCase())===-1)return}else if("startsWith"===e&&0!==o.toLowerCase().indexOf(m.value.toLowerCase()))return;var r=document.createElement("div");r.className=l.theme+"_list_item",r.innerText=o,r.item=i,i===l.oc&&(l.pc=r),n||(n=r),r.addEventListener("mousedown",function(e){a(r),e.preventDefault()}),r.addEventListener("mousemove",function(e){l.pc!==r&&(l.pc=r,t({dontScroll:!0}))}),h.appendChild(r),l.o.push(r)}),l.pc||(l.pc=n),t()}function t(e){e=e||{};var t=!e.dontScroll;document.querySelectorAll("."+l.theme+"_list_item_highlight").forEach(function(e){e.className=e.className.replace(l.theme+"_list_item_highlight","")}),l.pc&&(l.pc.className+=" "+l.theme+"_list_item_highlight",t&&!i(l.pc,h)&&l.pc.scrollIntoView())}function i(e,t){var i=e.getBoundingClientRect(),a=t.getBoundingClientRect();return i.top>=a.top&&i.bottom<=a.bottom}function a(e){var t=e.item;l.oc=t,l.vc(!0),o(),r()}function n(){l.uc()}function o(){l.p()}function r(){l.qc=!0,m.setAttribute("readonly","readonly"),m.focus()}function s(){l.qc=!1,m.removeAttribute("readonly"),m.select(),e("all")}var l=this,d=this,c=document.createElement("div");c.className=this.theme+"_main",c.style.position="relative";var u=document.createElement("div");u.className=this.theme+"_icon",u.style.position="absolute",u.style.right="0",u.style.top="0",u.style.bottom="0",u.style.width="20px",u.addEventListener("mousedown",function(e){e.preventDefault(),l.qc?(l.focus(),s()):(n(),r())});var h=document.createElement("div");h.className=this.theme+"_list",h.style.display="none",h.style.position="absolute",h.style.zIndex=this.listZIndex;var f=document.createElement("input");f.type="hidden",f.name=this.name,f.searchable=d,this.tc=f;var m=document.createElement("input");return m.type="text",m.className=this.theme+"_input",m.disabled=this.nc,m.addEventListener("click",function(e){s()}),m.addEventListener("focus",function(t){e("all")}),m.addEventListener("input",function(t){e()}),m.addEventListener("blur",function(e){m.removeAttribute("readonly"),n()}),m.addEventListener("keydown",function(e){if(l.qc){if("Enter"===e.key)return;if("Esc"===e.key||"Escape"===e.key)return;s()}if("ArrowDown"===e.key){var i=d.o.indexOf(d.pc);i+1=0&&(d.pc=d.o[i-1]),t()}else"Enter"===e.key?l.pc?(e.stopPropagation(),a(l.pc)):(e.stopPropagation(),n(),r()):"Esc"!==e.key&&"Escape"!==e.key||(e.stopPropagation(),n(),r())}),this.rc=m,this.sc=h,this.oc||(this.oc=this.data[0],this.oc&&(m.value=this.oc.name)),c.appendChild(m),c.appendChild(u),c.appendChild(f),c.appendChild(h),c},d.prototype.uc=function(){this.p(),this.oc?this.rc.value=this.oc.name:(this.rc.value="",this.vc(!0))},d.prototype.focus=function(){this.qc=!0,this.rc.setAttribute("readonly","readonly"),this.rc.focus(),this.uc()},d.prototype.p=function(){this.sc.style.display="none"},d.prototype.vc=function(e){if(this.tc.value=this.selected?this.selected.id:null,this.oc?this.rc.value=this.oc.name:this.rc.value="","function"==typeof this.onSelect){var t={control:this,ui:e};this.onSelect(t)}};var c=function(e){this.form=null,this.item=null,this.data=null,this.name=null,this.theme="edit_table_default",this.onInput=null,this.nav={},this.wc=null,this.dc=[],e=e||{};for(var t in e)this[t]=e[t]};c.prototype.create=function(){var e=this,t=document.createElement("div");t.className=this.theme+"_main",t.style.position="relative";var i=document.createElement("input");i.type="hidden",i.name=e.name,i.table=this,t.appendChild(i);var a=document.createElement("div");a.className=this.theme+"_table";var n=this.xc();a.appendChild(n);var o=e.yc({});o.spacer=!0;var r=this.zc(o);r.classList.add(e.theme+"_spacer"),a.appendChild(r);var s=document.createElement("div");s.className=e.theme+"_tbody",a.appendChild(s),t.appendChild(a);var l=document.createElement("div");t.appendChild(l),this.nav.body=s,this.nav.table=a,this.nav.main=t,this.nav.after=l;var d=document.createElement("div"),c=document.createElement("span");return c.className=this.theme+"_plus",c.addEventListener("click",function(t){if(!e.disabled){var i=e.item.onNewRow,a={};if("function"==typeof i){var n={};n.result=e.form.serialize(),n.value={},i(n),a=n.value}var o=e.yc(a);e.dc.push(o),e.Ac(),e.Bc()}}),this.nav.plus=c,d.appendChild(c),t.appendChild(d),t},c.prototype.xc=function(){var e=this,t=document.createElement("div");return t.classList.add(this.theme+"_row"),t.classList.add(this.theme+"_header"),this.item.columns.forEach(function(i){var a=document.createElement("div");a.classList.add(e.theme+"_cell"),a.innerText=i.name,t.appendChild(a)}),t},c.prototype.Cc=function(){var e=this.item.max||0;return!!(e&&this.dc.length>=e)},c.prototype.save=function(){var e=this,t=[];return e.dc.forEach(function(e){var i={};e.cells.forEach(function(e){i[e.id]=e.value}),t.push(i)}),t},c.prototype.load=function(e){if("[object Array]"!==Object.prototype.toString.call(e))throw new Error("Array expected");this.data=e,this.Dc(),this.Ac()},c.prototype.Ec=function(){this.disabled?this.nav.main.classList.add(this.theme+"_disabled"):this.nav.main.classList.remove(this.theme+"_disabled"),this.Cc()?this.nav.plus.classList.add(this.theme+"_plus_max"):this.nav.plus.classList.remove(this.theme+"_plus_max")},c.prototype.Dc=function(){var e=this;this.dc=[],this.data.forEach(function(t){var i=e.yc(t);e.dc.push(i)})},c.prototype.Fc=function(e){var t=this,i=t.dc.indexOf(e);t.dc.splice(i,1)},c.prototype.yc=function(e){var t=this,i={};return i.data=e,i.cells=[],t.item.columns.forEach(function(a){var n=a.id,o=e[n],r=t.Gc(a);if("undefined"==typeof o)if("text"===r)o="";else if("number"===r)o=0;else if("select"===r){var s=a.options;o=s&&s[0].id}var l={};l.id=n,l.value=o,l.type=r,l.data=a,i.cells.push(l)}),i},c.prototype.Gc=function(e){var t=e.type;return t||(t=e.options?"select":"text"),t},c.prototype.Ac=function(){var e=this;if(this.nav.body.innerHTML="",this.nav.after.innerHTML="",this.dc.forEach(function(t){var i=e.zc(t);e.nav.body.appendChild(i)}),0===this.dc.length){var t=e.Hc();e.nav.after.appendChild(t)}this.Ec()},c.prototype.Hc=function(){var e=document.createElement("div");return e.className=this.theme+"_empty",e},c.prototype.zc=function(e){var t=this,i=document.createElement("div");i.className=t.theme+"_row",e.cells.forEach(function(a){var n=document.createElement("div");n.className=t.theme+"_cell";var o=t.Ic(a);if(e.spacer){var r=document.createElement("div");r.style.height="0px",r.style.overflow="hidden",r.appendChild(o),n.appendChild(r)}else n.appendChild(o);i.appendChild(n)});var a=document.createElement("div");a.classList.add(t.theme+"_cell"),a.classList.add(t.theme+"_rowaction");var n=document.createElement("span");return n.className=this.theme+"_delete",n.addEventListener("click",function(i){t.disabled||(t.Fc(e),t.Ac(),t.Bc())}),e.spacer||a.appendChild(n),i.appendChild(a),i},c.prototype.Bc=function(){var e=this;if("function"==typeof e.onInput){var t={};e.onInput(t)}},c.prototype.Ic=function(e){var t=this,i=e.type;if("text"===i||"number"===i){var a=document.createElement("input");return a.type=i,t.disabled&&(a.disabled=!0),e.value&&(a.value=e.value),a.addEventListener("keyup",function(a){"number"===i?e.value=Number(this.value):e.value=this.value,t.Bc()}),a}if("select"===i){var n=document.createElement("select");return t.disabled&&(n.disabled=!0),e.data.options.forEach(function(t){var i=document.createElement("option");i.innerText=t.name,i.value=t.id,i.lc=t.id,n.appendChild(i),e.value===t.id&&i.setAttribute("selected",!0)}),n.addEventListener("change",function(i){var a=n.options[n.selectedIndex];a&&"undefined"!=typeof a.lc&&(e.value=a.lc),t.Bc()}),n}throw new Error("Unsupported item type: "+i)},c.prototype.focus=function(){}}}(DayPilot),"undefined"==typeof DayPilot)var DayPilot={};if("undefined"==typeof DayPilot.Global&&(DayPilot.Global={}),function(){if("undefined"==typeof DayPilot.Month||!DayPilot.Month.events){var e={};e.Month=function(t,i){this.v="2024.3.539-lite",this.nav={};var a=this;this.id=t,this.isMonth=!0,this.api=2,this.backendUrl=null,this.cellHeaderHeight=24,this.cellHeight=100,this.cellMarginBottom=0,this.contextMenu=null,this.cssClassPrefix="month_default",this.eventBarVisible=!0,this.eventHeight=25,this.eventsLoadMethod="GET",this.headerHeight=30,this.hideUntilInit=!0,this.lineSpace=1,this.locale="en-us",this.showToolTip=!0,this.startDate=new DayPilot.Date,this.theme=null,this.visible=!0,this.weekStarts="Auto",this.width="100%",this.xssProtection="Enabled",this.afterRender=function(){},this.cellHeaderClickHandling="Enabled",this.eventClickHandling="Enabled",this.eventDeleteHandling="Disabled",this.eventMoveHandling="Update",this.eventResizeHandling="Update",this.eventRightClickHandling="ContextMenu",this.headerClickHandling="Enabled",this.timeRangeSelectedHandling="Enabled",this.onCellHeaderClick=null,this.onCellHeaderClicked=null,this.onEventClick=null,this.onEventClicked=null,this.onEventDelete=null,this.onEventDeleted=null,this.onEventMove=null,this.onEventMoved=null,this.onEventResize=null,this.onEventResized=null,this.onEventRightClick=null,this.onEventRightClicked=null,this.onTimeRangeSelect=null,this.onTimeRangeSelected=null,this.onBeforeEventRender=null,this.onBeforeCellRender=null,this.cellEvents=[],this.elements={},this.elements.events=[],this.cache={},this.N=!1,this.T=function(e,t){var e=JSON.parse(e);return e.CallBackRedirect?void(document.location.href=e.CallBackRedirect):"None"===e.UpdateType?void a.fireAfterRenderDetached(e.CallBackData,!0):(a.events.list=e.Events,"Full"===e.UpdateType&&(a.startDate=e.StartDate,a.timeFormat=e.TimeFormat?e.TimeFormat:a.timeFormat,"undefined"!=typeof e.WeekStarts&&(a.weekStarts=e.WeekStarts),a.hashes=e.Hashes),a.V(),a.Jc(),a.da(),"Full"===e.UpdateType&&(a.Kc(),a.Lc()),a.ia(),a.show(),a.ja(),void a.fireAfterRenderDetached(e.CallBackData,!0))},this.fireAfterRenderDetached=function(e,t){var i=function(e,t){return function(){a.afterRender&&a.afterRender(e,t)}};window.setTimeout(i(e,t),0)},this.lineHeight=function(){return this.eventHeight+this.lineSpace},this.events={},this.events.add=function(e){var t=null;if(e instanceof DayPilot.Event)t=e.data;else{if("object"!=typeof e)throw"DayPilot.Month.events.add() expects an object or DayPilot.Event instance.";t=e}a.events.list||(a.events.list=[]),a.events.list.push(t),a.update(),a.ra.notify()},this.events.find=function(e){if(!a.events.list)return null;if("function"==typeof e){for(var t=e,i=0;i-1?"&"+s:"?"+s,DayPilot.Http.ajax({"method":"GET","url":r,"success":o,"error":n})}},this.update=function(e){if(a.ab(e),this.Aa){if(a.N)throw new DayPilot.Exception("You are trying to update a DayPilot.Month instance that has been disposed.");if(this.cells){a.V(),a.Jc(),a.da(),a.Kc(),a.Lc(),a.ia(),a.s(),a.ja(),this.visible?this.show():this.hide()}}},this.db=null,this.ab=function(e){if(e){var t={"events":{"preInit":function(){var e=this.data||[];DayPilot.isArray(e.list)?a.events.list=e.list:a.events.list=e}}};this.db=t;for(var i in e)if(t[i]){var n=t[i];n.data=e[i],n.preInit&&n.preInit()}else a[i]=e[i]}},this.eb=function(){var e=this.db;for(var t in e){var i=e[t];i.postInit&&i.postInit()}},this.gb={},this.gb.events=[],this.hb=function(e){var t=this.gb.events,i=this.events.list[e],n={};for(var o in i)n[o]=i[o];if("function"==typeof this.onBeforeEventRender){var r={};r.control=a,r.data=n,this.onBeforeEventRender(r)}t[e]=n},this.da=function(){var e=this.events.list;if(e){if(!DayPilot.isArray(e))throw new DayPilot.Exception("DayPilot.Month.events.list expects an array object. You supplied: "+typeof e);if("function"==typeof this.onBeforeEventRender)for(var t=0;to.getTime()))for(var t=0;t=7;)i--,c-=7;if(c>t){c>t+(7-this.getColCount())?(i--,t=t+7-c):(l=l-c+t,t=0)}else t-=c;i<0&&(i=0,t=0);var u=null;for(e.resizingEvent?u="w-resize":e.movingEvent&&(u="move"),this.nav.top.style.cursor=u;l>0&&i=this.end.getTime())},o.getPartStart=function(e){return DayPilot.DateUtil.max(this.start,e.start())},o.getPartEnd=function(e){return DayPilot.DateUtil.min(this.end,e.end())},o.getStartColumn=function(e){var t=this.getPartStart(e);return DayPilot.DateUtil.daysDiff(this.start,t)},o.getWidth=function(e){return DayPilot.DateUtil.daysSpan(this.getPartStart(e),this.getPartEnd(e))+1},o.putIntoLine=function(e,t,i,a){for(var n=this,o=0;othis[a].part.colStart+this[a].part.colWidth-1||(i=!1);return i},r.addEvent=function(e,t,i,a,o){e.part.colStart=t,e.part.colWidth=i,e.part.row=a,e.part.line=o,e.part.startsHere=n.start.getTime()<=e.start().getTime(),e.part.endsHere=n.end.getTime()>=e.end().getTime(),this.push(e)},r.addEvent(e,t,i,a,this.lines.length),this.lines.push(r),this.lines.length-1},o.getStart=function(){for(var e=0,t=0;t=7;)i.y++,t-=7;return i.x=t,i},this.Lc=function(){var e=document.createElement("div");e.oncontextmenu=function(){return!1},this.nav.cells.appendChild(e),this.cells=[];for(var t=0;t6&&(a-=7),i.className=this.J("_header");var o=document.createElement("div");o.setAttribute("unselectable","on"),o.innerHTML=n.locale().dayNames[a],i.appendChild(o),o.style.position="absolute",o.style.top="0px",o.style.bottom="0px", +o.style.left="0px",o.style.right="0px",o.className=this.J("_header_inner"),o.innerHTML=n.locale().dayNames[a],e.appendChild(i);for(var r=0;r","replace":!0,"link":function(t,i,a){var n=new DayPilot.Month(i[0]);n.ra.scope=t,n.init();var o=a["id"];o&&(t[o]=n);var r=a["publishAs"];if(r){(0,e(r).assign)(t,n)}for(var s in a)0===s.indexOf("on")&&!function(i){n[i]=function(n){var o=e(a[i]);t["$apply"](function(){o(t,{"args":n})})}}(s);var l=t["$watch"],d=a["config"]||a["daypilotConfig"],c=a["events"]||a["daypilotEvents"];l.call(t,d,function(e){for(var t in e)n[t]=e[t];n.update()},!0),l.call(t,c,function(e){n.events.list=e,n.update()},!0)}}}])}(),"undefined"!=typeof Sys&&Sys.Application&&Sys.Application.notifyScriptLoaded&&Sys.Application.notifyScriptLoaded()}}(),"undefined"==typeof DayPilot)var DayPilot={};"undefined"==typeof DayPilot.Global&&(DayPilot.Global={}),function(){if("undefined"==typeof DayPilot.Navigator||!DayPilot.Navigator.nav){DayPilot.Navigator=function(e,t){this.v="2024.3.539-lite";var i=this;this.id=e,this.api=2,this.isNavigator=!0,this.autoFocusOnClick=!0,this.weekStarts="Auto",this.selectMode="Day",this.titleHeight=30,this.dayHeaderHeight=30,this.bound=null,this.cellWidth=30,this.cellHeight=30,this.cssClassPrefix="navigator_default",this.freeHandSelectionEnabled=!1,this.selectionStart=(new DayPilot.Date).getDatePart(),this.selectionEnd=null,this.selectionDay=null,this.showMonths=1,this.skipMonths=1,this.command="navigate",this.year=(new DayPilot.Date).getYear(),this.month=(new DayPilot.Date).getMonth()+1,this.showWeekNumbers=!1,this.weekNumberAlgorithm="Auto",this.rowsPerMonth="Six",this.orientation="Vertical",this.locale="en-us",this.rtl=!1,this.visible=!0,this.timeRangeSelectedHandling="Bind",this.visibleRangeChangedHandling="Enabled",this.onVisibleRangeChange=null,this.onVisibleRangeChanged=null,this.onTimeRangeSelect=null,this.onTimeRangeSelected=null,this.nav={},this.gb={},this.Pc=function(){this.root.dp=this,this.root.className=this.J("_main"),"Horizontal"===this.orientation?(this.root.style.width=this.showMonths*(7*o.cellWidth()+this.Qc())+"px",this.root.style.height=6*this.cellHeight+this.titleHeight+this.dayHeaderHeight+"px"):this.root.style.width=7*o.cellWidth()+this.Qc()+"px",this.rtl&&(this.root.style.direction="rtl"),this.root.style.position="relative",this.visible||(this.root.style.display="none");var e=document.createElement("input");e.type="hidden",e.name=i.id+"_state",e.id=e.name,this.root.appendChild(e),this.state=e,this.startDate?this.startDate=new DayPilot.Date(this.startDate).firstDayOfMonth():this.startDate=DayPilot.Date.fromYearMonthDay(this.year,this.month),this.calendars=[],this.selected=[],this.months=[]},this.pa=function(){return 2===i.api},this.Kc=function(){this.root.innerHTML=""},this.J=function(e){var t=this.theme||this.cssClassPrefix;return t?t+e:""},this.Rc=function(e,t){var i=this.J("_"+t);DayPilot.Util.addClass(e,i)},this.Sc=function(e,t){var i=this.J("_"+t);DayPilot.Util.removeClass(e,i)},this.Lc=function(e,t){var a={};a.cells=[],a.days=[],a.weeks=[];var n=this.startDate.addMonths(e),r=t.before,s=t.after,l=n.firstDayOfMonth(),d=l.firstDayOfWeek(o.weekStarts()),c=l.addMonths(1),u=DayPilot.DateUtil.daysDiff(d,c),h="Auto"===this.rowsPerMonth?Math.ceil(u/7):6;a.rowCount=h;var f=(new DayPilot.Date).getDatePart(),m=7*o.cellWidth()+this.Qc();a.width=m;var p=this.cellHeight*h+this.titleHeight+this.dayHeaderHeight;a.height=p;var v=document.createElement("div");if(v.style.width=m+"px",v.style.height=p+"px","Horizontal"===this.orientation)v.style.position="absolute",v.style.left=m*e+"px",v.style.top="0px",a.top=0,a.left=m*e;else{v.style.position="relative";var y=e>0?i.months[e-1].top+i.months[e-1].height:0;a.top=y,a.left=0}v.className=this.J("_month"),v.style.cursor="default",v.style.MozUserSelect="none",v.style.KhtmlUserSelect="none",v.style.WebkitUserSelect="none",v.month=a,this.root.appendChild(v);var g=this.titleHeight+this.dayHeaderHeight,b=document.createElement("div");b.style.position="absolute",b.style.left="0px",b.style.right="0px",b.style.top="0px",b.style.width=o.cellWidth()+"px",b.style.height=this.titleHeight+"px",b.style.lineHeight=this.titleHeight+"px",b.setAttribute("unselectable","on"),b.className=this.J("_titleleft"),t.left&&(b.style.cursor="pointer",b.innerHTML="<",b.onclick=this.Tc),v.appendChild(b),this.tl=b;var D=document.createElement("div");D.style.position="absolute",D.style.left=o.cellWidth()+"px",D.style.top="0px",D.style.width=5*o.cellWidth()+this.Qc()+"px",D.style.height=this.titleHeight+"px",D.style.lineHeight=this.titleHeight+"px",D.setAttribute("unselectable","on"),D.className=this.J("_title"),D.innerHTML=o.locale().monthNames[n.getMonth()]+" "+n.getYear(),v.appendChild(D),this.ti=D;var x=document.createElement("div");x.style.position="absolute",x.style.left=6*o.cellWidth()+this.Qc()+"px",x.style.right=6*o.cellWidth()+this.Qc()+"px",x.style.top="0px",x.style.width=o.cellWidth()+"px",x.style.height=this.titleHeight+"px",x.style.lineHeight=this.titleHeight+"px",x.setAttribute("unselectable","on"),x.className=this.J("_titleright"),t.right&&(x.style.cursor="pointer",x.innerHTML=">",x.onclick=this.Uc),v.appendChild(x),this.tr=x;var w=this.Qc();if(this.showWeekNumbers)for(var C=0;C"+k+"",v.appendChild(_),a.weeks.push(_)}for(var S=0;S<7;S++){a.cells[S]=[];var _=document.createElement("div");_.style.position="absolute",_.style.left=S*o.cellWidth()+w+"px",_.style.right=S*o.cellWidth()+w+"px",_.style.top=this.titleHeight+"px",_.style.width=o.cellWidth()+"px",_.style.height=this.dayHeaderHeight+"px",_.style.lineHeight=this.dayHeaderHeight+"px",_.setAttribute("unselectable","on"),_.className=this.J("_dayheader"),_.innerHTML=""+this.Vc(S)+"",v.appendChild(_),a.days.push(_);for(var C=0;C=n.addMonths(1);if("month"===this.Xc())M=M&&T;else if("day"===this.Xc())M=M&&(T||r&&A||s&&H);else if("week"===this.Xc()){var E=P.firstDayOfMonth()===n;M=M&&(E||r&&A||s&&H)}var N=document.createElement("div");a.cells[S][C]=N;var I=i.Yc(S,C),R=I.x,O=I.y;N.day=P,N.x=S,N.y=C,N.left=R,N.top=O,N.isCurrentMonth=T,N.isNextMonth=H,N.isPrevMonth=A,N.showBefore=r,N.showAfter=s,N.className=this.J(T?"_day":"_dayother"),i.Rc(N,"cell"),P.getTime()===f.getTime()&&T&&this.Rc(N,"today"),0!==P.dayOfWeek()&&6!==P.dayOfWeek()||this.Rc(N,"weekend"),N.style.position="absolute",N.style.left=R+"px",N.style.right=R+"px",N.style.top=O+"px",N.style.width=o.cellWidth()+"px",N.style.height=this.cellHeight+"px",N.style.lineHeight=this.cellHeight+"px";var z=document.createElement("div");z.style.position="absolute",z.className=P.getTime()===f.getTime()&&T?this.J("_todaybox"):this.J("_daybox"),i.Rc(z,"cell_box"),z.style.left="0px",z.style.top="0px",z.style.right="0px",z.style.bottom="0px",N.appendChild(z);var U=null;if(this.cells&&this.cells[P.toStringSortable()]&&(U=this.cells[P.toStringSortable()]),"function"==typeof i.onBeforeCellRender){var B={};B.cell=U||{},B.cell.day=P,B.cell.isCurrentMonth=T,B.cell.isToday=P.getTime()===f.getTime()&&T,B.cell.isWeekend=0===P.dayOfWeek()||6===P.dayOfWeek(),U?(B.cell.html=U.html||P.getDay(),B.cell.cssClass=U.css):(B.cell.html=P.getDay(),B.cell.cssClass=null),i.onBeforeCellRender(B),U=B.cell}if(U&&DayPilot.Util.addClass(N,U.cssClass||U.css),T||r&&A||s&&H){var L=document.createElement("div");L.innerHTML=P.getDay(),L.style.position="absolute",L.style.left="0px",L.style.top="0px",L.style.right="0px",L.style.bottom="0px",i.Rc(L,"cell_text"),N.isClickable=!0,U&&U.html&&(L.innerHTML=U.html),N.appendChild(L)}N.setAttribute("unselectable","on"),N.onclick=this.Zc,v.appendChild(N),M&&(i.$c(v,S,C),this.selected.push(N))}}var j=document.createElement("div");j.style.position="absolute",j.style.left="0px",j.style.top=g-2+"px",j.style.width=7*o.cellWidth()+this.Qc()+"px",j.style.height="1px",j.style.fontSize="1px",j.style.lineHeight="1px",j.className=this.J("_line"),v.appendChild(j),this.months.push(a)},this.Yc=function(e,t){var i=this.titleHeight+this.dayHeaderHeight,a=this.Qc();return{"x":e*o.cellWidth()+a,"y":t*this.cellHeight+i}},this.$c=function(e,t,a){var n=e.month.cells[t][a];i.Rc(n,"select")},this._c=function(e,t,a){var n=e.month.cells[t][a];i.Sc(n,"select")},this.Qc=function(){return this.showWeekNumbers?o.cellWidth():0},this.ad=function(){if(this.items)for(var e=0;e=this.fd())&&(m=this.selectionStart.firstDayOfMonth()),m.toStringSortable()!==this.startDate.toStringSortable()&&(f=!0),this.startDate=m}s&&i.freeHandSelectionEnabled?i.selectionEnd=new DayPilot.Date(s):this.cd(),this.Kc(),this.Pc(),this.gd(),this.ad(),this.bd(),!c||u.equals(this.selectionStart)&&h.equals(this.selectionEnd)||this.L(),f&&this.hd()},this.update=function(e){if(i.ab(e),this.Aa){if(i.N)throw new DayPilot.Exception("You are trying to update a DayPilot.Navigator instance that has been disposed.");i.jd();var t={"day":i.selectionDay,"start":i.selectionStart,"end":i.selectionEnd};i.$a(),t.start===i.selectionStart&&t.end==i.selectionEnd&&t.day===i.selectionDay||i.L()}},this.$a=function(){this.Kc(),this.Pc(),this.cd(),this.gd(),this.da(),this.ad(),this.bd(),this.visible?this.show():this.hide()},this.jd=function(){i.gb={}},this.db=null,this.ab=function(e){if(e){var t={"events":{"preInit":function(){var e=this.data||[];DayPilot.isArray(e.list)?i.events.list=e.list:i.events.list=e}}};this.db=t;for(var a in e)if(t[a]){var n=t[a];n.data=e[a],n.preInit&&n.preInit()}else i[a]=e[a]}},this.eb=function(){var e=this.db;for(var t in e){var i=e[t];i.postInit&&i.postInit()}},this.R=function(e,t,i){var a={};a.action=e,a.parameters=i,a.data=t,a.header=this.Q();var n="JSON"+JSON.stringify(a);this.backendUrl?DayPilot.request(this.backendUrl,this.S,n,this.kd):WebForm_DoCallback(this.uniqueID,n,this.T,null,this.callbackError,!0)},this.kd=function(e){if("function"==typeof i.onAjaxError){var t={};t.request=e,i.onAjaxError(t)}else"function"==typeof i.ajaxError&&i.ajaxError(e)},this.S=function(e){i.T(e.responseText)},this.P=function(e,t,a){var n={};n.action=e,n.parameters=a,n.data=t,n.header=this.Q();var o="JSON"+JSON.stringify(n);__doPostBack(i.uniqueID,o)},this.Q=function(){var e={};return e.v=this.v,e.startDate=this.startDate,e.selectionStart=this.selectionStart,e.showMonths=this.showMonths,e},this.ld=function(e,t){"refresh"===e&&this.hd()},this.Vc=function(e){var t=e+o.weekStarts();return t>6&&(t-=7),o.locale().dayNamesShort[t]},this.Wc=function(e){return null!==this.selectionStart&&null!==this.selectionEnd&&(this.selectionStart.getTime()<=e.getTime()&&e.getTime()<=this.selectionEnd.getTime())},this.md=function(e){for(var t=0;tn&&(a.end=t)}a.end&&(a.clear(),a.draw())}},this.qd={};var a=this.qd;a.start=null,a.drawCell=function(e){var t=i.months[e.month],n=i.Yc(e.x,e.y),o=t.top+n.y,r=t.left+n.x,s=document.createElement("div");s.style.position="absolute",s.style.left=r+"px",s.style.top=o+"px",s.style.height=i.cellHeight+"px",s.style.width=i.cellWidth+"px",s.style.backgroundColor="#ccc",s.style.opacity=.5,s.style.cursor="default",i.nav.preselection.appendChild(s),a.cells.push(s)},a.clear=function(){if(a.cells){for(var e=0;e0){o.month-=1;var r=i.months[o.month];o.x=6,o.y=r.rowCount-1}for(a.cells=[];!t.is(o);){a.drawCell(t);var s=new n(t).next();if(!s)return;t.month=s.month,t.x=s.x,t.y=s.y}a.drawCell(t)}},a.ordered=function(){var e=a.start,t=a.end,i={};return!t||new n(e).before(t)?(i.start=e,i.end=t):(i.start=t,i.end=e),i};var n=function(e,t,a){if(e instanceof n)return e;if("object"==typeof e){var o=e;this.month=o.month,this.x=o.x,this.y=o.y}else this.month=e,this.x=t,this.y=a;this.is=function(e){return this.month===e.month&&this.x===e.x&&this.y===e.y},this.next=function(){var e=this;if(e.x<6)return{"month":e.month,"x":e.x+1,"y":e.y};var t=i.months[e.month];return e.y0)return{"month":e.month,"x":e.x-1,"y":e.y};i.months[e.month];if(e.y>0)return{"month":e.month,"x":6,"y":e.y-1};if(e.month>0){var t=i.months[e.month-1];return{"month":e.month-1,"x":6,"y":t.rowCount-1}}return null},this.previousVisible=function(){for(var e=this;!e.visible();){var t=e.previous();if(!t)return null;e=new n(t)}return e},this.cell=function(){return i.months[this.month].cells[this.x][this.y]},this.date=function(){return this.cell().day},this.before=function(e){return this.date()=i.fd())return void i.select(r)}var l=a.cells[n][o];i.$c(t,n,o),i.selected.push(l),i.selectionStart=l.day,i.selectionEnd=l.day;break;case"week":if(i.autoFocusOnClick){var s=a.cells[0][o].day,d=a.cells[6][o].day;if(s.firstDayOfMonth()===d.firstDayOfMonth()&&(s=i.fd()))return void i.select(r)}for(var c=0;c<7;c++)i.$c(t,c,o),i.selected.push(a.cells[c][o]);i.selectionStart=a.cells[0][o].day,i.selectionEnd=a.cells[6][o].day;break;case"month":if(i.autoFocusOnClick){var s=r;if(r=i.fd())return void i.select(r)}for(var s=null,d=null,o=0;o<6;o++)for(var n=0;n<7;n++){var l=a.cells[n][o];l&&l.day.getYear()===r.getYear()&&l.day.getMonth()===r.getMonth()&&(i.$c(t,n,o),i.selected.push(l),null===s&&(s=l.day),d=l.day)}i.selectionStart=s,i.selectionEnd=d;break;default:throw"unknown selectMode"}i.bd(),i.L()}},this.L=function(e){var t=i.selectionStart,a=i.selectionEnd.addDays(1),n=DayPilot.DateUtil.daysDiff(t,a),o=i.selectionDay;if(e=e||{},i.pa()){var r={};if(r.start=t,r.end=a,r.day=o,r.days=n,r.mode=e.mode||i.selectMode,r.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof i.onTimeRangeSelect&&(i.onTimeRangeSelect(r),r.preventDefault.value))return;switch(i.timeRangeSelectedHandling){case"Bind":if("object"==typeof bound){var s={};s.start=t,s.end=a,s.days=n,s.day=o,bound.commandCallBack(i.command,s)}break;case"None":break;case"PostBack":i.timeRangeSelectedPostBack(t,a,o)}"function"==typeof i.onTimeRangeSelected&&i.onTimeRangeSelected(r)}else switch(i.timeRangeSelectedHandling){case"Bind":if("object"==typeof bound){var s={};s.start=t,s.end=a,s.days=n,s.day=o,bound.commandCallBack(i.command,s)}break;case"JavaScript":i.onTimeRangeSelected(t,a,o);break;case"None":break;case"PostBack":i.timeRangeSelectedPostBack(t,a,o)}},this.timeRangeSelectedPostBack=function(e,t,i,a){var n={};n.start=e,n.end=t,n.day=a,this.P("TimeRangeSelected",i,n)},this.Uc=function(e){i.rd(i.skipMonths)},this.Tc=function(e){i.rd(-i.skipMonths)},this.rd=function(e){this.startDate=this.startDate.addMonths(e),this.Kc(),this.Pc(),this.gd(),this.bd(),this.hd(),this.ad()},this.ed=function(){return i.startDate.firstDayOfMonth()},this.fd=function(){return i.startDate.firstDayOfMonth().addMonths(this.showMonths)},this.visibleStart=function(){return i.startDate.firstDayOfMonth().firstDayOfWeek(o.weekStarts())},this.visibleEnd=function(){return i.startDate.firstDayOfMonth().addMonths(this.showMonths-1).firstDayOfWeek(o.weekStarts()).addDays(42)},this.hd=function(){var e=this.visibleStart(),t=this.visibleEnd();if(i.pa()){var a={};if(a.start=e,a.end=t,a.preventDefault=function(){this.preventDefault.value=!0},"function"==typeof i.onVisibleRangeChange&&(i.onVisibleRangeChange(a),a.preventDefault.value))return;switch(this.visibleRangeChangedHandling){case"CallBack":this.visibleRangeChangedCallBack(null);break;case"PostBack":this.visibleRangeChangedPostBack(null);break;case"Disabled":}"function"==typeof i.onVisibleRangeChanged&&i.onVisibleRangeChanged(a)}else switch(this.visibleRangeChangedHandling){case"CallBack":this.visibleRangeChangedCallBack(null);break;case"PostBack":this.visibleRangeChangedPostBack(null);break;case"JavaScript":this.onVisibleRangeChanged(e,t);break;case"Disabled":}},this.visibleRangeChangedCallBack=function(e){var t={};this.R("Visible",e,t)},this.visibleRangeChangedPostBack=function(e){var t={};this.P("Visible",e,t)},this.T=function(e,t){var e=JSON.parse(e);i.items=e.Items,i.cells=e.Cells,i.cells?i.update():i.ad()},this.gd=function(){for(var e=0;ee&&(e=i.height)}return e}for(var a=0,t=0;t","compile":function(t,i){return t.replaceWith(this["template"].replace("{{id}}",i["id"])),function(t,i,a){var n=new DayPilot.Navigator(i[0]);n.ra.scope=t,n.init();var o=a["id"];o&&(t[o]=n);var r=a["publishAs"];if(r){(0,e(r).assign)(t,n)}for(var s in a)if(0===s.indexOf("on")){var l=DayPilot.Util.shouldApply(s);l?!function(i){n[i]=function(n){var o=e(a[i]);t["$apply"](function(){o(t,{"args":n})})}}(s):!function(i){n[i]=function(n){e(a[i])(t,{"args":n})}}(s)}var d=t["$watch"],c=a["config"]||a["daypilotConfig"],u=a["events"]||a["daypilotEvents"];d.call(t,c,function(e,t){for(var i in e)n[i]=e[i];n.update()},!0),d.call(t,u,function(e){n.events.list=e,n.da(),n.ad()},!0)}}}}])}(),"undefined"!=typeof Sys&&Sys.Application&&Sys.Application.notifyScriptLoaded&&Sys.Application.notifyScriptLoaded()}}(); \ No newline at end of file diff --git a/static/src/js/daypilot-all.src.js b/static/src/js/daypilot-all.src.js new file mode 100644 index 0000000..2a19a54 --- /dev/null +++ b/static/src/js/daypilot-all.src.js @@ -0,0 +1,17290 @@ +var DayPilot = {};/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +(function() { + + if (typeof DayPilot.$ !== 'undefined') { + return; + } + + if (typeof DayPilot.Global === "undefined") { + DayPilot.Global = {}; + } + + DayPilot.$ = function(id) { + return document.getElementById(id); + }; + + Object.defineProperty(DayPilot, 'isKhtml', { + get: function() { return typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.indexOf("KHTML") !== -1; } + }); + + DayPilot.mo2 = function (target, ev){ + ev = ev || window.event; + + // IE + if (typeof(ev.offsetX) !== 'undefined') { + + var coords = {x: ev.offsetX + 1, y:ev.offsetY + 1}; + //document.title = "ie/doc:" + document.documentElement.scrollTop; + + if (!target) { + return coords; + } + + var current = ev.srcElement; + while (current && current !== target) { + if (current.tagName !== 'SPAN') { // hack for DayPilotMonth/IE, hour info on the right side of an event + coords.x += current.offsetLeft; + if (current.offsetTop > 0) { // hack for http://forums.daypilot.org/Topic.aspx/879/move_event_bug + coords.y += current.offsetTop - current.scrollTop; + } + } + + current = current.offsetParent; + } + + if (current) { + return coords; + } + return null; + } + + // FF + if (typeof(ev.layerX) !== 'undefined') { + + var coords = {x:ev.layerX, y:ev.layerY, src: ev.target}; + + if (!target) { + return coords; + } + var current = ev.target; + + // find the positioned offsetParent, the layerX reference + while (current && current.style.position !== 'absolute' && current.style.position !== 'relative') { + current = current.parentNode; + if (DayPilot.isKhtml) { // hack for KHTML (Safari and Google Chrome), used in DPC/event moving + coords.y += current.scrollTop; + } + } + + while (current && current !== target) { + coords.x += current.offsetLeft; + coords.y += current.offsetTop - current.scrollTop; + current = current.offsetParent; + } + if (current) { + return coords; + } + + return null; + } + + return null; + }; + + // mouse offset relative to the specified target + DayPilot.mo3 = function(target, ev) { + var coords; + var page = DayPilot.page(ev); + if (page) { + if (target) { + var abs = DayPilot.abs(target); + if (!abs) { + throw new Error("no abs"); + return null; + } + coords = {x: page.x - abs.x, y: page.y - abs.y}; + } + else { + coords = {x: page.x, y: page.y}; + } + } + else { + coords = DayPilot.mo2(target, ev); + if (!coords) { + // throw new Error("no coords"); + return null; + } + } + + coords.shift = ev.shiftKey; + coords.meta = ev.metaKey; + coords.ctrl = ev.ctrlKey; + coords.alt = ev.altKey; + + return coords; + }; + + DayPilot.browser = {}; + + Object.defineProperty(DayPilot.browser, 'hover', { + get: function() { return !window.matchMedia("(any-hover: none)").matches; } + }); + + DayPilot.touch = {}; + + // returns pageX, pageY (calculated from clientX if pageX is not available) + DayPilot.page = function(ev) { + // required for chrome/android + var target = ev.changedTouches && ev.changedTouches[0] ? ev.changedTouches[0] : ev; + + if (typeof target.pageX !== 'undefined') { + return {x: target.pageX, y: target.pageY}; + } + if (typeof ev.clientX !== 'undefined' && document.body && document.documentElement) { + return { + x: ev.clientX + document.body.scrollLeft + document.documentElement.scrollLeft, + y: ev.clientY + document.body.scrollTop + document.documentElement.scrollTop + }; + } + // shouldn't happen + return null; + }; + + // absolute element position on page + DayPilot.abs = function(element, visible) { + if (!element) { + return null; + } + + if (element.getBoundingClientRect) { + var r = DayPilot.absBoundingClientBased(element); + + if (visible) { + // use diff, absOffsetBased is not as accurate + var full = DayPilot.absOffsetBased(element, false); + var visible = DayPilot.absOffsetBased(element, true); + + r.x += visible.x - full.x; + r.y += visible.y - full.y; + r.w = visible.w; + r.h = visible.h; + } + + return r; + } + else { + return DayPilot.absOffsetBased(element, visible); + } + + }; + + DayPilot.absBoundingClientBased = function(element) { + var elemRect = element.getBoundingClientRect(); + + return { + // x: elemRect.left + window.scrollX, // IE11 doesn't support this + x: elemRect.left + window.pageXOffset, + // y: elemRect.top + window.scrollY, // IE11 doesn't support this + y: elemRect.top + window.pageYOffset, + w: element.clientWidth, + h: element.clientHeight, + toString: function() { + return "x:" + this.x + " y:" + this.y + " w:" + this.w + " h:" + this.h; + } + }; + }; + + + // old implementation of absolute position + // problems with adjacent float and margin-left in IE7 + // still the best way to calculate the visible part of the element + DayPilot.absOffsetBased = function(element, visible) { + var r = { + x: element.offsetLeft, + y: element.offsetTop, + w: element.clientWidth, + h: element.clientHeight, + toString: function() { + return "x:" + this.x + " y:" + this.y + " w:" + this.w + " h:" + this.h; + } + }; + + while (element.offsetParent) { + element = element.offsetParent; + + r.x -= element.scrollLeft; + r.y -= element.scrollTop; + + if (visible) { // calculates the visible part + if (r.x < 0) { + r.w += r.x; // decrease width + r.x = 0; + } + + if (r.y < 0) { + r.h += r.y; // decrease height + r.y = 0; + } + + if (element.scrollLeft > 0 && r.x + r.w > element.clientWidth) { + r.w -= r.x + r.w - element.clientWidth; + } + + if (element.scrollTop && r.y + r.h > element.clientHeight) { + r.h -= r.y + r.h - element.clientHeight; + } + } + + r.x += element.offsetLeft; + r.y += element.offsetTop; + + } + + var pageOffset = DayPilot.pageOffset(); + r.x += pageOffset.x; + r.y += pageOffset.y; + + return r; + }; + + DayPilot.isArray = function(o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }; + + // distance of two points, works with x and y + DayPilot.distance = function(point1, point2) { + return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2)); + }; + + DayPilot.sheet = function() { + + if (typeof window === "undefined") { + // next.js server-side rendering + var sheet = {}; + sheet.add = function() {}; + sheet.commit = function() {}; + return sheet; + } + + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + if (!style.styleSheet) { // ie + style.appendChild(document.createTextNode("")); + } + + var h = document.head || document.getElementsByTagName('head')[0]; + h.appendChild(style); + + var oldStyle = !! style.styleSheet; // old ie + + var sheet = {}; + sheet.rules = []; + sheet.commit = function() { + if (oldStyle) { + style.styleSheet.cssText = this.rules.join("\n"); + } + }; + + sheet.add = function(selector, rules, index) { + if (oldStyle) { + this.rules.push(selector + "{" + rules + "\u007d"); + return; + } + if(style.sheet.insertRule) { + if (typeof index === "undefined") { + index = style.sheet.cssRules.length; + } + style.sheet.insertRule(selector + "{" + rules + "\u007d", index); + } + else if (style.sheet.addRule) { + style.sheet.addRule(selector, rules, index); + } + }; + return sheet; + }; + + DayPilot.gs = function(el, styleProp) { + return window.getComputedStyle(el, null).getPropertyValue(styleProp) || ""; + }; + + DayPilot.StyleReader = function(element) { + + this.get = function(property) { + if (!element) { + return null; + } + return DayPilot.gs(element, property); + }; + + this.getPx = function(property) { + var val = this.get(property); + if (val.indexOf("px") === -1) { + return undefined; + } + else { + return parseInt(val, 10); + } + }; + + }; + + // register the default themes + (function() { + if (DayPilot.Global.defaultCss) { + return; + } + + var sheet = DayPilot.sheet(); + + sheet.add(".calendar_default_main", "border: 1px solid #c0c0c0; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;"); + sheet.add(".calendar_default_main *, .calendar_default_main *:before, .calendar_default_main *:after", "box-sizing: content-box;"); // bootstrap + sheet.add(".calendar_default_rowheader_inner,.calendar_default_cornerright_inner,.calendar_default_corner_inner,.calendar_default_colheader_inner,.calendar_default_alldayheader_inner", "color: #333;background: #f3f3f3;"); + sheet.add(".calendar_default_cornerright_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px; border-bottom: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_direction_rtl .calendar_default_cornerright_inner", "border-right: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_rowheader_inner", "font-size: 16pt;text-align: right; position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0; padding: 3px;"); + sheet.add(".calendar_default_direction_rtl .calendar_default_rowheader_inner", "border-right: none;"); + sheet.add(".calendar_default_corner_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_direction_rtl .calendar_default_corner_inner", "border-right: none;"); + sheet.add(".calendar_default_rowheader_minutes", "font-size:10px;vertical-align: super;padding-left: 2px;padding-right: 2px;"); + sheet.add(".calendar_default_colheader_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0; display: flex; align-items: center; justify-content: center; font-size: 13px;"); + sheet.add(".calendar_default_cell_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #ddd;border-bottom: 1px solid #ddd; background: #f9f9f9;"); + sheet.add(".calendar_default_cell_business .calendar_default_cell_inner", "background: #fff"); + sheet.add(".calendar_default_alldayheader_inner", "text-align: center;position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_message", "opacity: 0.9; padding: 10px; color: #ffffff;background: #ffa216;"); + sheet.add(".calendar_default_alldayevent_inner,.calendar_default_event_inner", 'color: #333; border: 1px solid #999;'); // border-top: 4px solid #1066a8; + sheet.add(".calendar_default_event_bar", "top: 0px;bottom: 0px;left: 0px;width: 6px;background-color: #9dc8e8;"); + sheet.add(".calendar_default_event_bar_inner", "position: absolute;width: 6px;background-color: #1066a8;"); + sheet.add(".calendar_default_alldayevent_inner,.calendar_default_event_inner", 'background: #fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".calendar_default_selected .calendar_default_event_inner", "background: #ddd;"); + sheet.add(".calendar_default_alldayevent_inner", "position: absolute;top: 2px;bottom: 2px;left: 2px;right: 2px;overflow:hidden;padding: 2px;margin-right: 1px; font-size: 13px;"); + sheet.add(".calendar_default_event_withheader .calendar_default_event_inner", "padding-top: 15px;"); + sheet.add(".calendar_default_event", "cursor: default;"); + sheet.add(".calendar_default_event_inner", "position: absolute;overflow: hidden;top: 0px;bottom: 0px;left: 0px;right: 0px;padding: 2px 2px 2px 8px; font-size: 13px;"); + sheet.add(".calendar_default_event_delete", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat; opacity: 0.6; cursor: pointer;"); + sheet.add(".calendar_default_event_delete:hover", "opacity: 1;-ms-filter: none;"); + sheet.add(".calendar_default_scroll_up", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAB3RJTUUH2wESDiYcrhwCiQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAARnQU1BAACxjwv8YQUAAACcSURBVHjaY2AgF9wWsTW6yGMlhi7OhC7AyMDQzMnBXIpFHAFuCtuaMTP+P8nA8P/b1x//FfW/HHuF1UQmxv+NUP1c3OxMVVhNvCVi683E8H8LXOY/w9+fTH81tF8fv4NiIpBRj+YoZtZ/LDUoJmKYhsVUpv0MDiyMDP96sIYV0FS2/8z9ICaLlOhvS4b/jC//MzC8xBG0vJeF7GQBlK0xdiUzCtsAAAAASUVORK5CYII=);"); + sheet.add(".calendar_default_scroll_down", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAALiMAAC4jAXilP3YAAACqSURBVChTY7wpam3L9J+xmQEP+PGPKZZxP4MDi4zI78uMDIwa2NT+Z2DYovrmiC+TI8OBP/8ZmEqwGvif4e8vxr+FIDkmEKH25vBWBgbG0+iK/zEwLtF+ffwOXCGI8Y+BoRFFIdC030x/WmBiYBNhpgLdswNJ8RSYaSgmgk39z1gPUfj/29ef/9rwhQTDHRHbrbdEbLvRFcGthkkAra/9/uMvhkK8piNLAgCRpTnNn4AEmAAAAABJRU5ErkJggg==);"); + sheet.add(".calendar_default_now", "background-color: red;"); + sheet.add(".calendar_default_now:before", "content: ''; top: -5px; border-width: 5px; border-color: transparent transparent transparent red; border-style: solid; width: 0px; height:0px; position: absolute; -moz-transform: scale(.9999);"); + sheet.add(".calendar_default_shadow_top", 'box-sizing: border-box; padding:2px;border:1px solid #ccc;background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".calendar_default_shadow_bottom", 'box-sizing: border-box; padding:2px;border:1px solid #ccc;background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".calendar_default_crosshair_vertical, .calendar_default_crosshair_horizontal, .calendar_default_crosshair_left, .calendar_default_crosshair_top", "background-color: gray; opacity: 0.2;"); + sheet.add(".calendar_default_loading", "background-color: orange; color: white; padding: 2px;"); + sheet.add(".calendar_default_scroll", "background-color: #f3f3f3;"); + sheet.add(".calendar_default_event_moving_source", "opacity: 0.5;"); + sheet.add(".calendar_default_shadow_inner", "box-sizing: border-box; background-color: #bbbbbb;border: 1px solid #888888;opacity: 0.5;height: 100%;"); + sheet.add(".calendar_default_shadow", "box-shadow: 0 2px 5px rgba(0,0,0,.2);"); + + + // menu + sheet.add(".menu_default_main", "user-select:none; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size: 13px;border: 1px solid #dddddd;background-color: white;padding: 0px;cursor: default;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAABCAIAAABG0om7AAAAKXRFWHRDcmVhdGlvbiBUaW1lAHBvIDEwIDUgMjAxMCAyMjozMzo1OSArMDEwMGzy7+IAAAAHdElNRQfaBQoUJAesj4VUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAABGdBTUEAALGPC/xhBQAAABVJREFUeNpj/P//PwO1weMnT2RlZAAYuwX/4oA3BgAAAABJRU5ErkJggg==);background-repeat: repeat-y;xborder-radius: 5px;-moz-box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);-webkit-box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);"); + sheet.add(".menu_default_main, .menu_default_main *, .menu_default_main *:before, .menu_default_main *:after", "box-sizing: content-box;"); + sheet.add(".menu_default_title", "background-color: #f2f2f2;border-bottom: 1px solid gray;padding: 4px 4px 4px 37px;"); + sheet.add(".menu_default_main a", "padding: 2px 2px 2px 35px;color: black;text-decoration: none;cursor: default;"); + sheet.add(".menu_default_main.menu_default_withchildren a", "padding: 2px 35px 2px 35px;"); + sheet.add(".menu_default_main a img", "margin-left: 6px;margin-top: 2px;"); + sheet.add(".menu_default_item_text", "display: block;height: 20px;line-height: 20px; overflow:hidden;padding-left: 2px;padding-right: 20px; white-space: nowrap;"); + sheet.add(".menu_default_main a:hover", "background-color: #f3f3f3;"); + sheet.add(".menu_default_main div div", "border-top: 1px solid #dddddd;margin-top: 2px;margin-bottom: 2px;margin-left: 28px;"); + sheet.add(".menu_default_main a.menu_default_item_disabled", "color: #ccc"); + sheet.add(".menu_default_item_haschildren.menu_default_item_haschildren_active", 'background-color: #f3f3f3;'); + sheet.add(".menu_default_item_haschildren a:before", "content: ''; border-width: 5px; border-color: transparent transparent transparent #666; border-style: solid; width: 0px; height:0px; position: absolute; right: 5px; margin-top: 5px;"); + sheet.add(".menu_default_item_icon", "position: absolute; top:0px; left: 0px; padding: 2px 2px 2px 8px;"); + sheet.add(".menu_default_item a i", "height: 20px;line-height: 20px;"); + sheet.add(".menu_default_item .menu_default_item_symbol", "width: 18px; height: 18px; color: #999; margin-left: 6px;margin-top: 2px;"); + + + // menubar + sheet.add(".menubar_default_main", "border-bottom: 1px solid #ccc; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px; user-select:none;"); + sheet.add(".menubar_default_item", "display: inline-block; padding: 6px 10px; cursor: default;"); + sheet.add(".menubar_default_item:hover", "background-color: #f2f2f2;"); + sheet.add(".menubar_default_item_active", "background-color: #f2f2f2;"); + + + sheet.add(".scheduler_default_selected .scheduler_default_event_inner", "background: #ddd;"); + sheet.add(".scheduler_default_main", "border: 1px solid #c0c0c0;font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;"); + sheet.add(".scheduler_default_timeheader", "cursor: default;color: #333;"); + sheet.add(".scheduler_default_message", "opacity: 0.9;filter: alpha(opacity=90);padding: 10px; color: #ffffff;background: #ffa216;"); + sheet.add(".scheduler_default_timeheadergroup,.scheduler_default_timeheadercol", "color: #333;background: #f3f3f3;"); + sheet.add(".scheduler_default_rowheader,.scheduler_default_corner", "color: #333;background: #f3f3f3;"); + sheet.add(".scheduler_default_rowheader_inner", "position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #eee;padding: 2px;"); + sheet.add(".scheduler_default_timeheadergroup, .scheduler_default_timeheadercol", "text-align: center;"); + sheet.add(".scheduler_default_timeheadergroup_inner", "position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"); + sheet.add(".scheduler_default_timeheadercol_inner", "position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #c0c0c0;"); + sheet.add(".scheduler_default_divider", "background-color: #c0c0c0;"); + sheet.add(".scheduler_default_divider_horizontal", "background-color: #c0c0c0;"); + sheet.add(".scheduler_default_matrix_vertical_line", "background-color: #eee;"); + sheet.add(".scheduler_default_matrix_vertical_break", "background-color: #000;"); + sheet.add(".scheduler_default_matrix_horizontal_line", "background-color: #eee;"); + sheet.add(".scheduler_default_resourcedivider", "background-color: #c0c0c0;"); + sheet.add(".scheduler_default_shadow_inner", "background-color: #666666;opacity: 0.5;filter: alpha(opacity=50);height: 100%;xborder-radius: 5px;"); + sheet.add(".scheduler_default_event", "color:#333; font-size: 13px;"); + sheet.add(".scheduler_default_event_inner", "position:absolute;top:0px;left:0px;right:0px;bottom:0px;padding:5px 2px 2px 2px;overflow:hidden;border:1px solid #ccc;"); + sheet.add(".scheduler_default_event_bar", "top:0px;left:0px;right:0px;height:4px;background-color:#9dc8e8;"); + sheet.add(".scheduler_default_event_bar_inner", "position:absolute;height:4px;background-color:#1066a8;"); + sheet.add(".scheduler_default_event_inner", 'background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".scheduler_default_event_float_inner", "padding:6px 2px 2px 8px;"); // space for arrow + sheet.add(".scheduler_default_event_float_inner:after", 'content:"";border-color: transparent #666 transparent transparent;border-style:solid;border-width:5px;width:0;height:0;position:absolute;top:8px;left:-4px;'); + sheet.add(".scheduler_default_columnheader_inner", "font-weight: bold;"); + sheet.add(".scheduler_default_columnheader_splitter", "background-color: #666;opacity: 0.5;filter: alpha(opacity=50);"); + sheet.add(".scheduler_default_columnheader_cell_inner", "padding: 2px;"); + sheet.add(".scheduler_default_cell", "background-color: #f9f9f9;"); + sheet.add(".scheduler_default_cell.scheduler_default_cell_business", "background-color: #fff;"); + + sheet.add(".navigator_default_main", "border-left: 1px solid #c0c0c0;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;background-color: white;color: #000000; box-sizing: content-box;"); + sheet.add(".navigator_default_main *, .navigator_default_main *:before, .navigator_default_main *:after", "box-sizing: content-box;"); + sheet.add(".navigator_default_month", "font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 12px;"); + sheet.add(".navigator_default_day", "color: black;"); + sheet.add(".navigator_default_weekend", "background-color: #f0f0f0;"); + sheet.add(".navigator_default_dayheader", "color: black;"); + sheet.add(".navigator_default_line", "border-bottom: 1px solid #c0c0c0;"); + sheet.add(".navigator_default_dayother", "color: gray;"); + sheet.add(".navigator_default_todaybox", "border: 1px solid red;"); + sheet.add(".navigator_default_title, .navigator_default_titleleft, .navigator_default_titleright", "border-top: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;color: #333;background: #f3f3f3;"); + sheet.add(".navigator_default_busy", "font-weight: bold;"); + sheet.add(".navigator_default_cell", "text-align: center;"); + sheet.add(".navigator_default_select .navigator_default_cell_box", "background-color: #FFE794; opacity: 0.5;"); + sheet.add(".navigator_default_title", "text-align: center;"); + sheet.add(".navigator_default_titleleft, .navigator_default_titleright", "text-align: center;"); + sheet.add(".navigator_default_dayheader", "text-align: center;"); + sheet.add(".navigator_default_weeknumber", "text-align: center; color: #999;"); + sheet.add(".navigator_default_cell_text", "cursor: pointer;"); + + sheet.add(".month_default_main", "border: 1px solid #c0c0c0;font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;color: #333;"); + sheet.add(".month_default_main *, .month_default_main *:before, .month_default_main *:after", "box-sizing: content-box;"); + sheet.add(".month_default_cell_inner", "border-right: 1px solid #ddd;border-bottom: 1px solid #ddd;position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;background-color: #f9f9f9;"); + sheet.add(".month_default_cell_business .month_default_cell_inner", "background-color: #fff;"); + sheet.add(".month_default_cell_header", "text-align: right; padding: 4px; box-sizing: border-box;"); + sheet.add(".month_default_header_inner", 'position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;cursor: default;color: #333;background: #f3f3f3; overflow:hidden; display: flex; align-items: center; justify-content: center;'); + sheet.add(".month_default_message", 'padding: 10px;opacity: 0.9; color: #ffffff;background: #ffa216;'); + sheet.add(".month_default_event_inner", 'position: absolute;top: 0px;bottom: 0px;left: 1px;right: 1px;overflow:hidden;padding: 2px;padding-left: 10px;color: #333;background: #fff;background: linear-gradient(to bottom, #ffffff 0%, #eeeeee);border: 1px solid #999;border-radius: 0px;display: flex; align-items: center; font-size: 13px;'); + sheet.add(".month_default_event_continueright .month_default_event_inner", "border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-right-style: dotted;"); + sheet.add(".month_default_event_continueleft .month_default_event_inner", "border-top-left-radius: 0px;border-bottom-left-radius: 0px;border-left-style: dotted;"); + + sheet.add(".month_default_event_bar", "top: 0px;bottom: 0px;left: 0px;width: 6px;"); + sheet.add(".month_default_event_bar_inner", "position: absolute;width: 6px;background-color: #1066a8;"); + sheet.add(".month_default_event_continueleft .month_default_event_bar", "display: none;"); + + sheet.add(".month_default_selected .month_default_event_inner", "background: #ddd;"); + // sheet.add(".month_default_shadow_inner", "background-color: #666666;opacity: 0.5;height: 100%;"); + sheet.add(".month_default_event_delete", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat; opacity: 0.6; cursor: pointer;"); + sheet.add(".month_default_event_delete:hover", "opacity: 1;-ms-filter: none;"); + sheet.add(".month_default_event_timeleft", "color: #ccc; font-size: 8pt"); + sheet.add(".month_default_event_timeright", "color: #ccc; font-size: 8pt; text-align: right;"); + sheet.add(".month_default_loading", "background-color: orange; color: white; padding: 2px;"); + sheet.add(".month_default_shadow_inner", "box-sizing: border-box; background-color: #bbbbbb;border: 1px solid #888888;opacity: 0.5;height: 100%;"); + sheet.add(".month_default_shadow", "box-shadow: 0 2px 5px rgba(0,0,0,.2);"); + + sheet.commit(); + + DayPilot.Global.defaultCss = true; + })(); + + // document element + DayPilot.doc = function() { + var de = document.documentElement; + return (de && de.clientHeight) ? de : document.body; + }; + + DayPilot.guid = function() { + var S4 = function() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + }; + return ("" + S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); + }; + + DayPilot.pageOffset = function() { + if (typeof pageXOffset !== 'undefined') { + return { x: pageXOffset, y: pageYOffset }; + } + var d = DayPilot.doc(); + return { x: d.scrollLeft, y: d.scrollTop }; + }; + + DayPilot.indexOf = function(array, object) { + if (!array || !array.length) { + return -1; + } + for (var i = 0; i < array.length; i++) { + if (array[i] === object) { + return i; + } + } + return -1; + }; + + // all children + DayPilot.ac = function(e, children) { + if (!children) { + var children = []; + } + for (var i = 0; e.children && i < e.children.length; i++) { + children.push(e.children[i]); + DayPilot.ac(e.children[i], children); + } + + return children; + }; + + // remove from array + DayPilot.rfa = function(array, object) { + var i = DayPilot.indexOf(array, object); + if (i === -1) { + return; + } + array.splice(i, 1); + }; + + // mouse coords + DayPilot.mc = function(ev){ + if(ev.pageX || ev.pageY){ + return {x:ev.pageX, y:ev.pageY}; + } + return { + x:ev.clientX + document.documentElement.scrollLeft, + y:ev.clientY + document.documentElement.scrollTop + }; + }; + + DayPilot.Stats = {}; + DayPilot.Stats.eventObjects = 0; + DayPilot.Stats.dateObjects = 0; + DayPilot.Stats.cacheHitsCtor = 0; + DayPilot.Stats.cacheHitsParsing = 0; + DayPilot.Stats.cacheHitsTicks = 0; + + DayPilot.re = function(el, ev, func) { + if (!func) { + return; + } + if (!ev) { + return; + } + if (!el) { + return; + } + el.addEventListener(ev, func, false); + }; + + DayPilot.rePassive = function(el, ev, func) { + if (!func) { + return; + } + if (!ev) { + return; + } + if (!el) { + return; + } + el.addEventListener(ev, func, {"passive": true}); + }; + + DayPilot.reNonPassive = function(el, ev, func) { + if (!func) { + return; + } + if (!ev) { + return; + } + if (!el) { + return; + } + el.addEventListener(ev, func, {"passive": false}); + }; + + // purge + // thanks to http://javascript.crockford.com/memory/leak.html + DayPilot.pu = function(d) { + //var removed = []; + //var start = new Date(); + var a = d.attributes, i, l, n; + if (a) { + l = a.length; + for (i = 0; i < l; i += 1) { + if (!a[i]) { + continue; + } + n = a[i].name; + if (typeof d[n] === 'function') { + d[n] = null; + } + } + } + a = d.childNodes; + if (a) { + l = a.length; + for (i = 0; i < l; i += 1) { + var children = DayPilot.pu(d.childNodes[i]); + } + } + }; + + // delete element + DayPilot.de = function(e) { + if (!e) { + return; + } + if (DayPilot.isArray(e)) { + for (var i = 0; i < e.length; i++) { + DayPilot.de(e[i]); + } + return; + } + e.parentNode && e.parentNode.removeChild(e); + }; + + // vertical scrollbar width + DayPilot.sw = function(element) { + if (!element) { + return 0; + } + return element.offsetWidth - element.clientWidth; + }; + + // angular module + DayPilot.am = function() { + if (typeof angular === "undefined") { + return null; + } + if (!DayPilot.am.cached) { + DayPilot.am.cached = angular.module("daypilot", []); + } + return DayPilot.am.cached; + }; + + DayPilot.Selection = function (start, end, resource, root) { + this.type = 'selection'; + this.start = start.isDayPilotDate ? start : new DayPilot.Date(start); + this.end = end.isDayPilotDate ? end : new DayPilot.Date(end); + this.resource = resource; + this.root = root; + + this.toJSON = function(key) { + var json = {}; + json.start = this.start; + json.end = this.end; + json.resource = this.resource; + + return json; + }; + }; + + /* XMLHttpRequest */ + + DayPilot.request = function(url, callback, postData, errorCallback) { + var req = DayPilot.createXmlHttp(); + if (!req) { + return; + } + + req.open("POST", url, true); + req.setRequestHeader('Content-type', 'text/plain'); + req.onreadystatechange = function() { + if (req.readyState !== 4) + return; + if (req.status !== 200 && req.status !== 304) { + if (errorCallback) { + errorCallback(req); + } + else { + if (window.console) { console.log('HTTP error ' + req.status); } + } + return; + } + callback(req); + }; + if (req.readyState === 4) { + return; + } + if (typeof postData === 'object') { + postData = JSON.stringify(postData); + } + req.send(postData); + }; + + DayPilot.ajax = function(params) { + if (!params) { + throw new DayPilot.Exception("Parameter object required."); + } + + if (typeof params.url !== "string") { + throw new DayPilot.Exception("The parameter object must have 'url' property.") + } + + var req = DayPilot.createXmlHttp(); + if (!req) { + throw new DayPilot.Exception("Unable to create XMLHttpRequest object"); + } + + var dataIsObject = typeof params.data === "object"; + + var data = params.data; + var method = params.method || (params.data ? "POST" : "GET"); + var success = params.success || function() {}; + var error = params.error || function() {}; + var url = params.url; + var contentType = params.contentType || (dataIsObject ? "application/json" : "text/plain"); + var headers = params.headers || {}; + + req.open(method, url, true); + req.setRequestHeader('Content-type', contentType); + + // overriding the content-type is allowed + DayPilot.Util.ownPropsAsArray(headers).forEach(function(item) { + req.setRequestHeader(item.key, item.val); + }); + + req.onreadystatechange = function() { + if (req.readyState !== 4) { + return; + } + if (req.status !== 200 && req.status !== 201 && req.status !== 204 && req.status !== 304) { + if (error) { + var args = {}; + args.request = req; + error(args); + } + else { + if (window.console) { console.log('HTTP error ' + req.status); } + } + return; + } + var args = {}; + args.request = req; + if (req.responseText) { + args.data = JSON.parse(req.responseText); + } + success(args); + }; + if (req.readyState === 4) { + return; + } + if (dataIsObject) { + data = JSON.stringify(data); + } + req.send(data); + }; + + DayPilot.createXmlHttp = function() { + return new XMLHttpRequest(); + }; + + DayPilot.Http = {}; + + DayPilot.Http.ajax = function(params) { + DayPilot.ajax(params); + }; + + /* +allowed params: +- headers +- contentType + */ + DayPilot.Http.get = function(url, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "GET"; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Http.post = function(url, data, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "POST"; + aparams.data = data; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Http.put = function(url, data, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "PUT"; + aparams.data = data; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Http.delete = function(url, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "DELETE"; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Util = {}; + DayPilot.Util.addClass = function(object, name) { + if (!object) { + return; + } + if (!object.className) { + object.className = name; + return; + } + var already = new RegExp("(^|\\s)" + name + "($|\\s)"); + if (!already.test(object.className)) { + object.className = object.className + ' ' + name; + } + }; + + DayPilot.Util.removeClass = function(object, name) { + if (!object) { + return; + } + var already = new RegExp("(^|\\s)" + name + "($|\\s)"); + object.className = object.className.replace(already, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // trim spaces + }; + + DayPilot.Util.copyProps = function(source, target, props) { + if (!target) { + target = {}; + } + if (!source) { + return target; + } + if (typeof props === 'undefined') { + for (var name in source) { + if (source.hasOwnProperty(name) && typeof source[name] !== 'undefined') { + target[name] = source[name]; + } + } + } + else { + for (var i = 0; i < props.length; i++) { + var name = props[i]; + if (typeof source[name] !== 'undefined') { + target[name] = source[name]; + } + } + } + return target; + }; + + DayPilot.Util.ownPropsAsArray = function(object) { + var result = []; + + if (!object) { + return result; + } + + for (var name in object) { + if (object.hasOwnProperty(name)) { + var item = {}; + item.key = name; + item.val = object[name]; + result.push(item); + } + } + + return result; + }; + + DayPilot.Util.replaceCharAt = function(str, index, character) { + return str.substr(0, index) + character + str.substr(index + character.length); + }; + + DayPilot.Util.isNullOrUndefined = function(val) { + return val === null || typeof val === "undefined"; + }; + + DayPilot.Util.escapeHtml = function(html) { + var div = document.createElement("div"); + div.innerText = html; + return div.innerHTML; + }; + + DayPilot.Util.escapeTextHtml = function(text, html) { + if (!DayPilot.Util.isNullOrUndefined(html)) { + return html; + } + if (DayPilot.Util.isNullOrUndefined(text)) { + return ""; + } + return DayPilot.Util.escapeHtml(text); + }; + + /* areas */ + + DayPilot.Areas = {}; + + /** + * Attach active areas to a target div. + * Works with "Visible", "TouchVisible" and "Hover" visibility + */ + DayPilot.Areas.attach = function (div, e, options) { + var options = options || {}; + var areas = options.areas; + var allowed = options.allowed || function() { return true; }; + var offsetX = options.offsetX || 0; + + // permanently visible active areas + areas = areasExtract(e, areas); + + if (!areas) { + return; + } + + if (!DayPilot.isArray(areas)) { + return; + } + + if (areas.length === 0) { + return; + } + + DayPilot.re(div, "mousemove", function(ev) { + if (!div.active && !div.areasDisabled && allowed()) { + DayPilot.Areas.showAreas(div, e, ev, areas, { "offsetX": offsetX, "eventDiv": options.eventDiv}); + } + }); + DayPilot.re(div, "mouseleave", function(ev) { + DayPilot.Areas.hideAreas(div, ev); + }); + + areas.forEach(function(area) { + if (!DayPilot.Areas.isVisible(area)) { + return; + } + var a = DayPilot.Areas.createArea(div, e, area, { "offsetX": offsetX, "eventDiv": options.eventDiv}); + div.appendChild(a); + }); + }; + + DayPilot.Areas.disable = function(div) { + div.areasDisabled = true; + Array.from(div.childNodes).filter(function(item) { return item.isActiveArea && !item.area.start; }).forEach(function(item) { + item._originalDisplay = item.style.display; + item.style.display = "none"; + }); + }; + + DayPilot.Areas.enable = function(div) { + div.areasDisabled = false; + Array.from(div.childNodes).filter(function(item) { return item.isActiveArea && !item.area.start; }).forEach(function(item) { + if (item._originalDisplay) { + item.style.display = item._originalDisplay; + } + else { + item.style.display = ""; + } + }); + }; + + DayPilot.Areas.remove = function(div) { + var divs = Array.from(div.childNodes).filter(function(item) { return item.isActiveArea; }); + + DayPilot.de(divs); + }; + + DayPilot.Areas.isVisible = function(area) { + var v = area.visibility || area.v || "Visible"; + if (v === "Visible") { + return true; + } + if (v === "TouchVisible") { + if (!DayPilot.browser.hover) { + return true; + } + } + return false; + }; + + DayPilot.Areas.copy = function(areas) { + if (!DayPilot.isArray(areas)) { + return []; + } + + return areas.map(function(area) { + return DayPilot.Util.copyProps(area, {}); + }); + }; + + /** + * Extracts areas array from the source object, giving priority to a standalone areas object. + * @param e + * @param areas + */ + var areasExtract = function(e, areas) { + if (!DayPilot.isArray(areas)) { + areas = e.areas; + if (!areas) { + if (e.cache) { + areas = e.cache.areas; + } + else if (e.data) { + areas = e.data.areas; + } + } + } + return areas; + }; + + + DayPilot.Areas.showAreas = function(div, e, ev, areas, options) { + if (DayPilot.Global.resizing) { + return; + } + + if (DayPilot.Global.moving) { + return; + } + + if (DayPilot.Global.selecting) { + return; + } + + if (div.active) { + return; + } + + if (!DayPilot.browser.hover) { + return; + } + + if (DayPilot.Areas.all && DayPilot.Areas.all.length > 0) { + for (var i = 0; i < DayPilot.Areas.all.length; i++) { + var d = DayPilot.Areas.all[i]; + if (d !== div) { + DayPilot.Areas.hideAreas(d, ev); + } + } + } + + div.active = {}; + + //var areas; + if (!DayPilot.isArray(areas)) { + areas = e.areas; + if (!areas) { + if (e.cache) { + areas = e.cache.areas; + } + else if (e.data) { + areas = e.data.areas; + } + } + } + + if (!areas || areas.length === 0) { + return; + } + + if (div.areas && div.areas.length > 0) { + return; + } + div.areas = []; + + for (var i = 0; i < areas.length; i++) { + var area = areas[i]; + + if (DayPilot.Areas.isVisible(area)) { + continue; + } + + var a = DayPilot.Areas.createArea(div, e, area, options); + + div.areas.push(a); + div.appendChild(a); + + DayPilot.Areas.all.push(div); + } + div.active.children = DayPilot.ac(div); + }; + + /** + * + * @param div Target div element + * @param e Source data object + * @param area Area definition + * @returns {Element} + */ + DayPilot.Areas.createArea = function(div, e, area, options) { + + /* + actions: + - Default (equals not specified) + - None (cancels bubbling to parent element) + - ContextMenu + - HoverMenu + - ResizeStart + - ResizeEnd + - Move + - excluded: JavaScript, Bubble + */ + + var options = options || {}; + var offsetX = options.offsetX || 0; + var ediv = options.eventDiv || div; + + var a = document.createElement("div"); + a.isActiveArea = true; + a.area = area; + a.setAttribute("unselectable", "on"); + var w = area.w || area.width; + var h = area.h || area.height; + var css = area.cssClass || area.css || area.className; + if (typeof area.style !== "undefined") { + a.setAttribute("style", area.style); + } + a.style.position = "absolute"; + + a.style.width = resolvePosVal(w); + a.style.height = resolvePosVal(h); + a.style.right = resolvePosVal(area.right); + a.style.top = resolvePosVal(area.top); + a.style.left = resolvePosVal(area.left); + a.style.bottom = resolvePosVal(area.bottom); + + if (typeof area.html !== 'undefined' || typeof area.text !== "undefined") { + // a.innerHTML = area.html || area.text; + a.innerHTML = DayPilot.Util.escapeTextHtml(area.text, area.html); + } + else if (area.icon) { + var iel = document.createElement("i"); + iel.className = area.icon; + a.appendChild(iel); + } + else if (area.image) { + var img = document.createElement("img"); + img.src = area.image; + a.appendChild(img); + } + else if (area.symbol) { + var ns = "http://www.w3.org/2000/svg"; + var svg = document.createElementNS(ns,"svg"); + svg.setAttribute("width", "100%"); + svg.setAttribute("height", "100%"); + var use = document.createElementNS(ns,"use"); + use.setAttribute("href", area.symbol); + svg.appendChild(use); + a.appendChild(svg); + } + + if (css) { + a.className = css; + } + if (area.toolTip) { + a.setAttribute("title", area.toolTip); + } + if (area.backColor) { + a.style.background = area.backColor; + } + if (area.background) { // alias + a.style.background = area.background; + } + if (area.fontColor) { + a.style.color = area.fontColor; + } + if (area.padding) { + a.style.padding = area.padding + "px"; + a.style.boxSizing = "border-box"; + } + if (area.verticalAlignment) { + a.style.display = "flex"; + switch (area.verticalAlignment) { + case "center": + a.style.alignItems = "center"; + break; + case "top": + a.style.alignItems = "flex-start"; + break; + case "bottom": + a.style.alignItems = "flex-end"; + break; + } + } + if (area.horizontalAlignment) { + a.style.display = "flex"; + switch (area.horizontalAlignment) { + case "right": + a.style.justifyContent = "flex-end"; + break; + case "left": + a.style.justifyContent = "flex-start"; + break; + case "center": + a.style.justifyContent = "center"; + break; + } + } + + if (area.action === "ResizeEnd" || area.action === "ResizeStart" || area.action === "Move") { + if (e.calendar.isCalendar) { + switch (area.action) { + case "ResizeEnd": + area.cursor = "s-resize"; + area.dpBorder = "bottom"; + break; + case "ResizeStart": + area.cursor = "n-resize"; + area.dpBorder = "top"; + break; + case "Move": + area.cursor = "move"; + break; + } + } + if (e.calendar.isScheduler || e.calendar.isMonth) { + switch (area.action) { + case "ResizeEnd": + area.cursor = "e-resize"; + area.dpBorder = "right"; + break; + case "ResizeStart": + area.cursor = "w-resize"; + area.dpBorder = "left"; + break; + case "Move": + area.cursor = "move"; + break; + } + } + a.onmousemove = (function(div, e, area) { + return function(ev) { + + if (e.calendar.internal && e.calendar.internal.dragInProgress && e.calendar.internal.dragInProgress()) { // resizing in progress + return; + } + ev.cancelBubble = true; + + div.style.cursor = area.cursor; + if (area.dpBorder) { + div.dpBorder = area.dpBorder; + } + }; + })(ediv, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + div.style.cursor = ''; + }; + })(ediv, e, area); + } + if ((area.action === "ResizeEnd" || area.action === "ResizeStart") && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + var touch = e.calendar.internal.touch; + var t = ev.touches ? ev.touches[0] : ev; + var coords = {x: t.pageX, y: t.pageY }; + // immediately + e.calendar.coords = touch.relativeCoords(ev); + touch.preventEventTap = true; + if (e.calendar.isScheduler) { + touch.startResizing(div, area.action === "ResizeEnd" ? "right" : "left"); + } + else if (e.calendar.isCalendar) { + touch.startResizing(div, area.action === "ResizeEnd" ? "bottom" : "top", coords); + } + + }; + })(ediv, e, area); + DayPilot.rePassive(a, DayPilot.touch.start, touchstart); + // a.addEventListener(DayPilot.touch.start, touchstart, {"passive": true}); + } + } + if (area.action === "ContextMenu" && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + + showContextMenu(div, e, area, ev); + var touch = e.calendar.internal.touch; + touch.preventEventTap = true; + }; + })(ediv, e, area); + var touchend = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + }; + })(ediv, e, area); + DayPilot.reNonPassive(a, DayPilot.touch.start, touchstart); + DayPilot.reNonPassive(a, DayPilot.touch.end, touchend); + } + } + if (area.action === "Bubble" && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + + var args = doOnClick(area, e, ev); + if (args.preventDefault.value) { + return; + } + showBubble(e, area, ev); + var touch = e.calendar.internal.touch; + touch.preventEventTap = true; + + if (typeof area.onClicked === "function") { + area.onClicked(args); + } + }; + })(ediv, e, area); + var touchend = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + }; + })(ediv, e, area); + DayPilot.reNonPassive(a, DayPilot.touch.start, touchstart); + DayPilot.reNonPassive(a, DayPilot.touch.end, touchend); + } + } + if (area.action === "Move" && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + var touch = e.calendar.internal.touch; + var t = ev.touches ? ev.touches[0] : ev; + var coords = {x: t.pageX, y: t.pageY }; + // immediately + e.calendar.coords = touch.relativeCoords(ev); + + // DayPilot.Global.movingAreaData = area.data; + if (DayPilot.Global && DayPilot.Global.touch) { + DayPilot.Global.touch.active = true; + } + + touch.preventEventTap = true; + touch.startMoving(div, coords); + }; + })(ediv, e, area); + DayPilot.rePassive(a, DayPilot.touch.start, touchstart); + // a.addEventListener(DayPilot.touch.start, touchstart, {"passive": true}); + } + } + if (area.action === "Bubble" && e.isEvent) { + a.onmousemove = (function(div, e, area) { + return function(ev) { + if (area.bubble) { + area.bubble.showEvent(e, true); + } + else if (e.calendar.bubble) { + e.calendar.bubble.showEvent(e, true); + } + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + if (typeof DayPilot.Bubble !== "undefined") { + //DayPilot.Bubble.hideActive(); + if (area.bubble) { + area.bubble.hideOnMouseOut(); + } + else if (e.calendar.bubble) { + e.calendar.bubble.hideOnMouseOut(); + } + } + + }; + })(div, e, area); + } + else if (area.action === "Bubble" && e.isRow) { + a.onmousemove = (function(div, e, area) { + return function(ev) { + if (area.bubble) { + area.bubble.showResource(e, true); + } + else if (e.calendar.resourceBubble) { + e.calendar.resourceBubble.showResource(e, true); + } + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + if (typeof DayPilot.Bubble !== "undefined") { + //DayPilot.Bubble.hideActive(); + if (area.bubble) { + area.bubble.hideOnMouseOut(); + } + else if (e.calendar.resourceBubble) { + e.calendar.resourceBubble.hideOnMouseOut(); + } + } + + }; + })(div, e, area); + } + else if (area.action === "Bubble" && typeof DayPilot.Bubble !== "undefined" && area.bubble instanceof DayPilot.Bubble) { + a.onmousemove = (function(div, e, area) { + return function(ev) { + area.bubble.showHtml(null, null); + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + if (typeof DayPilot.Bubble !== "undefined") { + if (area.bubble) { + area.bubble.hideOnMouseOut(); + } + } + + }; + })(div, e, area); + } + if (area.action === "HoverMenu") { + a.onmousemove = (function(div, e, area) { + return function(ev) { + var m = area.menu; + if (m && m.show) { + if (!m.visible) { + m.show(e); + } + else if (m.source && typeof m.source.id !== 'undefined' && m.source.id !== e.id) { + m.show(e); + } + m.cancelHideTimeout(); + } + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + var m = area.menu; + if (!m) { + return; + } + if (m.hideOnMouseOver) { + m.delayedHide(); + } + }; + })(div, e, area); + } + if (area.action === "None") { + var touchstart = (function(div, e, area) { + return function(ev) { + var args = doOnClick(area, e, ev); + + if (typeof area.onClicked === "function") { + area.onClicked(args); + } + + ev.preventDefault(); + ev.stopPropagation(); + }; + })(ediv, e, area); + DayPilot.reNonPassive(a, DayPilot.touch.start, touchstart); + } + + // prevent event moving + a.onmousedown = (function(div, e, area) { + return function(ev) { + if (typeof area.onmousedown === 'function') { // obsolete, remove + area.onmousedown(ev); + } + + if (typeof area.mousedown === 'function') { // internal + var args = {}; + args.area = area; + args.div = div; + args.originalEvent = ev; + args.source = e; + area.mousedown(args); + } + + if (area.action === "Move" && e.isRow) { + var row = e.$.row; + var startMoving = e.calendar.internal.rowStartMoving; + + startMoving(row); + } + + // cancel any bubble + if (typeof DayPilot.Bubble !== "undefined") { + DayPilot.Bubble.hideActive(); + } + + if (area.action === "Move") { + DayPilot.Global.movingAreaData = area.data; + } + + if (area.action === "Move" && e.isEvent) { + if (e.calendar.internal && e.calendar.internal.startMoving) { + e.calendar.internal.startMoving(div, ev); + } + } + + var cancel = true; + + if (cancel) { + if (area.action === "Move" || area.action === "ResizeEnd" || area.action === "ResizeStart" || !area.action || area.action === "Default") { + return; + } + ev.preventDefault(); // prevents text selection on dragging + ev.cancelBubble = true; + } + }; + })(div, e, area); + a.onclick = (function(div, e, area) { + return function(ev) { + var args = doOnClick(area, e, ev); + + if (args.preventDefault.value) { + return; + } + + switch (area.action) { + case "ContextMenu": + showContextMenu(div, e, area, ev); + ev.cancelBubble = true; + break; + case "None": + ev.cancelBubble = true; + break; + } + + if (typeof area.onClicked === "function") { + area.onClicked(args); + } + }; + })(div, e, area); + + if (typeof area.onMouseEnter === "function") { + a.addEventListener("mouseenter", (function(div, e, area) { + return function(ev) { + var args = {}; + args.area = area; + args.source = e; + args.originalEvent = ev; + area.onMouseEnter(args); + }; + })(div, e, area)); + } + if (typeof area.onMouseLeave === "function") { + a.addEventListener("mouseleave", (function(div, e, area) { + return function(ev) { + var args = {}; + args.area = area; + args.source = e; + args.originalEvent = ev; + area.onMouseLeave(args); + }; + })(div, e, area)); + } + + function doOnClick(area, source, originalEvent) { + var args = {}; + args.area = area; + args.source = source; + args.originalEvent = originalEvent; + args.preventDefault = function() { + args.preventDefault.value = true; + }; + + if (typeof area.onClick === "function") { + area.onClick(args); + } + return args; + } + + function showBubble(e, area, ev) { + if (DayPilot.Bubble) { + DayPilot.Bubble.touchPosition(ev); + } + + if (e.calendar.bubble) { + e.calendar.bubble.showEvent(e, true); + } + } + + function showContextMenu(div, e, area, ev) { + if (DayPilot.Menu) { + DayPilot.Menu.touchPosition(ev); + } + + var m = area.contextMenu || area.menu; + if (!(m instanceof DayPilot.Menu)) { + if (e.isEvent && e.client.contextMenu()) { + m = e.client.contextMenu(); + } + else if (e.isEvent && e.calendar.contextMenu) { + m = e.calendar.contextMenu; + } + } + if (m && m.show) { + var initiator = { "type": "area", "div": div, "e": e, "area": area, "a": a}; + m.show(e, { "initiator": initiator}); + } + } + + function resolvePosVal(val) { + if (typeof val === "string" && isNaN(val)) { + return val; + } + else if (typeof val !== "undefined") { + return val + "px"; + } + return undefined; + } + + return a; + }; + + DayPilot.Areas.all = []; + + DayPilot.Areas.hideAreas = function(div, ev) { + if (!div) { + return; + } + + if (!div || !div.active) { + return; + } + + var active = div.active; + var areas = div.areas; + + if (active && active.children) { + if (ev) { + var target = ev.toElement || ev.relatedTarget; + if (~DayPilot.indexOf(active.children, target)) { + return; + } + } + } + + if (!areas || areas.length === 0) { + div.active = null; + return; + } + + DayPilot.de(areas); + + div.active = null; + div.areas = []; + + DayPilot.rfa(DayPilot.Areas.all, div); + + active.children = null; + }; + + DayPilot.Areas.hideAll = function(ev) { + if (!DayPilot.Areas.all || DayPilot.Areas.all.length === 0) { + return; + } + for (var i = 0; i < DayPilot.Areas.all.length; i++) { + DayPilot.Areas.hideAreas(DayPilot.Areas.all[i], ev); + } + + }; + + /* end of areas */ + + DayPilot.Exception = function(msg) { + return new Error(msg); + }; + + DayPilot.Locale = function(id, config) { + this.id = id; + this.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; + this.dayNamesShort = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; + this.monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + this.datePattern = "M/d/yyyy"; + this.timePattern = "H:mm"; + this.dateTimePattern = "M/d/yyyy H:mm"; + this.timeFormat = "Clock12Hours"; + this.weekStarts = 0; + + if (config) { + for (var name in config) { + this[name] = config[name]; + } + } + }; + + DayPilot.Locale.all = {}; + + DayPilot.Locale.find = function(id) { + if (!id) { + return null; + } + var normalized = id.toLowerCase(); + if (normalized.length > 2) { + normalized = DayPilot.Util.replaceCharAt(normalized, 2, '-'); + } + return DayPilot.Locale.all[normalized]; + }; + + DayPilot.Locale.register = function(locale) { + DayPilot.Locale.all[locale.id] = locale; + }; + + DayPilot.Locale.register(new DayPilot.Locale('ca-es', {'dayNames':['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'],'dayNamesShort':['dg','dl','dt','dc','dj','dv','ds'],'monthNames':['gener','febrer','març','abril','maig','juny','juliol','agost','setembre','octubre','novembre','desembre',''],'monthNamesShort':['gen.','febr.','març','abr.','maig','juny','jul.','ag.','set.','oct.','nov.','des.',''],'timePattern':'H:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('cs-cz', {'dayNames':['neděle','pondělí','úterý','středa','čtvrtek','pátek','sobota'],'dayNamesShort':['ne','po','út','st','čt','pá','so'],'monthNames':['leden','únor','březen','duben','květen','červen','červenec','srpen','září','říjen','listopad','prosinec',''],'monthNamesShort':['I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII',''],'timePattern':'H:mm','datePattern':'d. M. yyyy','dateTimePattern':'d. M. yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('da-dk', {'dayNames':['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],'dayNamesShort':['sø','ma','ti','on','to','fr','lø'],'monthNames':['januar','februar','marts','april','maj','juni','juli','august','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'HH:mm','datePattern':'dd-MM-yyyy','dateTimePattern':'dd-MM-yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-at', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Jänner','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jän','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-ch', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-de', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-lu', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('en-au', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'h:mm tt','datePattern':'d/MM/yyyy','dateTimePattern':'d/MM/yyyy h:mm tt','timeFormat':'Clock12Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('en-ca', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'h:mm tt','datePattern':'yyyy-MM-dd','dateTimePattern':'yyyy-MM-dd h:mm tt','timeFormat':'Clock12Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('en-gb', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('en-us', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'h:mm tt','datePattern':'M/d/yyyy','dateTimePattern':'M/d/yyyy h:mm tt','timeFormat':'Clock12Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('es-es', {'dayNames':['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],'dayNamesShort':['D','L','M','X','J','V','S'],'monthNames':['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre',''],'monthNamesShort':['ene.','feb.','mar.','abr.','may.','jun.','jul.','ago.','sep.','oct.','nov.','dic.',''],'timePattern':'H:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('es-mx', {'dayNames':['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],'dayNamesShort':['do.','lu.','ma.','mi.','ju.','vi.','sá.'],'monthNames':['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre',''],'monthNamesShort':['ene.','feb.','mar.','abr.','may.','jun.','jul.','ago.','sep.','oct.','nov.','dic.',''],'timePattern':'hh:mm tt','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy hh:mm tt','timeFormat':'Clock12Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('eu-es', {'dayNames':['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'],'dayNamesShort':['ig','al','as','az','og','or','lr'],'monthNames':['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina','uztaila','abuztua','iraila','urria','azaroa','abendua',''],'monthNamesShort':['urt.','ots.','mar.','api.','mai.','eka.','uzt.','abu.','ira.','urr.','aza.','abe.',''],'timePattern':'H:mm','datePattern':'yyyy/MM/dd','dateTimePattern':'yyyy/MM/dd H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fi-fi', {'dayNames':['sunnuntai','maanantai','tiistai','keskiviikko','torstai','perjantai','lauantai'],'dayNamesShort':['su','ma','ti','ke','to','pe','la'],'monthNames':['tammikuu','helmikuu','maaliskuu','huhtikuu','toukokuu','kesäkuu','heinäkuu','elokuu','syyskuu','lokakuu','marraskuu','joulukuu',''],'monthNamesShort':['tammi','helmi','maalis','huhti','touko','kesä','heinä','elo','syys','loka','marras','joulu',''],'timePattern':'H:mm','datePattern':'d.M.yyyy','dateTimePattern':'d.M.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-be', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd-MM-yy','dateTimePattern':'dd-MM-yy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-ch', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-fr', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-lu', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('gl-es', {'dayNames':['domingo','luns','martes','mércores','xoves','venres','sábado'],'dayNamesShort':['do','lu','ma','mé','xo','ve','sá'],'monthNames':['xaneiro','febreiro','marzo','abril','maio','xuño','xullo','agosto','setembro','outubro','novembro','decembro',''],'monthNamesShort':['xan','feb','mar','abr','maio','xuño','xul','ago','set','out','nov','dec',''],'timePattern':'H:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('it-it', {'dayNames':['domenica','lunedì','martedì','mercoledì','giovedì','venerdì','sabato'],'dayNamesShort':['do','lu','ma','me','gi','ve','sa'],'monthNames':['gennaio','febbraio','marzo','aprile','maggio','giugno','luglio','agosto','settembre','ottobre','novembre','dicembre',''],'monthNamesShort':['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('it-ch', {'dayNames':['domenica','lunedì','martedì','mercoledì','giovedì','venerdì','sabato'],'dayNamesShort':['do','lu','ma','me','gi','ve','sa'],'monthNames':['gennaio','febbraio','marzo','aprile','maggio','giugno','luglio','agosto','settembre','ottobre','novembre','dicembre',''],'monthNamesShort':['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('ja-jp', {'dayNames':['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],'dayNamesShort':['日','月','火','水','木','金','土'],'monthNames':['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月',''],'monthNamesShort':['1','2','3','4','5','6','7','8','9','10','11','12',''],'timePattern':'H:mm','datePattern':'yyyy/MM/dd','dateTimePattern':'yyyy/MM/dd H:mm','timeFormat':'Clock24Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('nb-no', {'dayNames':['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],'dayNamesShort':['sø','ma','ti','on','to','fr','lø'],'monthNames':['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember',''],'monthNamesShort':['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('nl-nl', {'dayNames':['zondag','maandag','dinsdag','woensdag','donderdag','vrijdag','zaterdag'],'dayNamesShort':['zo','ma','di','wo','do','vr','za'],'monthNames':['januari','februari','maart','april','mei','juni','juli','augustus','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'HH:mm','datePattern':'d-M-yyyy','dateTimePattern':'d-M-yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('nl-be', {'dayNames':['zondag','maandag','dinsdag','woensdag','donderdag','vrijdag','zaterdag'],'dayNamesShort':['zo','ma','di','wo','do','vr','za'],'monthNames':['januari','februari','maart','april','mei','juni','juli','augustus','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'H:mm','datePattern':'d/MM/yyyy','dateTimePattern':'d/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('nn-no', {'dayNames':['søndag','måndag','tysdag','onsdag','torsdag','fredag','laurdag'],'dayNamesShort':['sø','må','ty','on','to','fr','la'],'monthNames':['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember',''],'monthNamesShort':['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('pt-br', {'dayNames':['domingo','segunda-feira','terça-feira','quarta-feira','quinta-feira','sexta-feira','sábado'],'dayNamesShort':['D','S','T','Q','Q','S','S'],'monthNames':['janeiro','fevereiro','março','abril','maio','junho','julho','agosto','setembro','outubro','novembro','dezembro',''],'monthNamesShort':['jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('pl-pl', {'dayNames':['niedziela','poniedziałek','wtorek','środa','czwartek','piątek','sobota'],'dayNamesShort':['N','Pn','Wt','Śr','Cz','Pt','So'],'monthNames':['styczeń','luty','marzec','kwiecień','maj','czerwiec','lipiec','sierpień','wrzesień','październik','listopad','grudzień',''],'monthNamesShort':['sty','lut','mar','kwi','maj','cze','lip','sie','wrz','paź','lis','gru',''],'timePattern':'HH:mm','datePattern':'yyyy-MM-dd','dateTimePattern':'yyyy-MM-dd HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('pt-pt', {'dayNames':['domingo','segunda-feira','terça-feira','quarta-feira','quinta-feira','sexta-feira','sábado'],'dayNamesShort':['D','S','T','Q','Q','S','S'],'monthNames':['janeiro','fevereiro','março','abril','maio','junho','julho','agosto','setembro','outubro','novembro','dezembro',''],'monthNamesShort':['jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('ro-ro', {'dayNames':['duminică','luni','marți','miercuri','joi','vineri','sâmbătă'],'dayNamesShort':['D','L','Ma','Mi','J','V','S'],'monthNames':['ianuarie','februarie','martie','aprilie','mai','iunie','iulie','august','septembrie','octombrie','noiembrie','decembrie',''],'monthNamesShort':['ian.','feb.','mar.','apr.','mai.','iun.','iul.','aug.','sep.','oct.','nov.','dec.',''],'timePattern':'H:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('ru-ru', {'dayNames':['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],'dayNamesShort':['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],'monthNames':['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь',''],'monthNamesShort':['янв','фев','мар','апр','май','июн','июл','авг','сен','окт','ноя','дек',''],'timePattern':'H:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('sk-sk', {'dayNames':['nedeľa','pondelok','utorok','streda','štvrtok','piatok','sobota'],'dayNamesShort':['ne','po','ut','st','št','pi','so'],'monthNames':['január','február','marec','apríl','máj','jún','júl','august','september','október','november','december',''],'monthNamesShort':['1','2','3','4','5','6','7','8','9','10','11','12',''],'timePattern':'H:mm','datePattern':'d.M.yyyy','dateTimePattern':'d.M.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('sv-se', {'dayNames':['söndag','måndag','tisdag','onsdag','torsdag','fredag','lördag'],'dayNamesShort':['sö','må','ti','on','to','fr','lö'],'monthNames':['januari','februari','mars','april','maj','juni','juli','augusti','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'HH:mm','datePattern':'yyyy-MM-dd','dateTimePattern':'yyyy-MM-dd HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('tr-tr', {'dayNames':['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'],'dayNamesShort':['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],'monthNames':['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran','Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık',''],'monthNamesShort':['Oca','Şub','Mar','Nis','May','Haz','Tem','Ağu','Eyl','Eki','Kas','Ara',''],'timePattern':'HH:mm','datePattern':'d.M.yyyy','dateTimePattern':'d.M.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('uk-ua', {'dayNames':['неділя','понеділок','вівторок','середа','четвер',"п'ятниця",'субота'],'dayNamesShort':['Нд','Пн','Вт','Ср','Чт','Пт','Сб'],'monthNames':['січень','лютий','березень','квітень','травень','червень','липень','серпень','вересень','жовтень','листопад','грудень',''],'monthNamesShort':['Січ','Лют','Бер','Кві','Тра','Чер','Лип','Сер','Вер','Жов','Лис','Гру',''],'timePattern':'H:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('zh-cn', {'dayNames':['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],'dayNamesShort':['日','一','二','三','四','五','六'],'monthNames':['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月',''],'monthNamesShort':['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月',''],'timePattern':'H:mm','datePattern':'yyyy/M/d','dateTimePattern':'yyyy/M/d H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('zh-tw', {'dayNames':['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],'dayNamesShort':['日','一','二','三','四','五','六'],'monthNames':['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月',''],'monthNamesShort':['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月',''],'timePattern':'tt hh:mm','datePattern':'yyyy/M/d','dateTimePattern':'yyyy/M/d tt hh:mm','timeFormat':'Clock12Hours','weekStarts':0})); + + DayPilot.Locale.US = DayPilot.Locale.find("en-us"); + + /** + * Created on 2023-04-04. + */ + + DayPilot.Switcher = function(options) { + + var This = this; + + this._views = []; + this._triggers = []; + this._navigator = {}; + + this.selectedClass = null; + + this._active = null; + + this._day = DayPilot.Date.today(); + + this.onChange = null; + this.onChanged = null; + this.onSelect = null; + + this._navigator.updateMode = function (mode) { + var control = This._navigator.control; + if (!control) { + return; + } + control.selectMode = mode; + control.select(This._day); + }; + + this.addView = function (spec, options) { + var element; + if (typeof spec === 'string') { + element = document.getElementById(spec); + if (!element) { + throw "Element not found: " + spec; + } + } + else { // DayPilot object, DOM element + element = spec; + } + + var control = element; + + var view = {}; + view._isView = true; + view._id = control.id; + view.control = control; + view._options = options || {}; + view._hide = function () { + if (control.hide) { + control.hide(); + } + else if (control.nav && control.nav.top) { + control.nav.top.style.display = 'none'; + } + else { + control.style.display = 'none'; + } + }; + view._sendNavigate = function(date) { + var serverBased = (function() { + if (control.backendUrl) { // ASP.NET MVC, Java + return true; + } + if (typeof WebForm_DoCallback === 'function' && control.uniqueID) { // ASP.NET WebForms + return true; + } + return false; + })(); + if (serverBased) { + if (control.commandCallBack) { + control.commandCallBack("navigate", { "day": date }); + } + } + else { + control.startDate = date; + control.update(); + } + }; + view._show = function () { + This._hideViews(); + if (control.show) { + control.show(); + } + else if (control.nav && control.nav.top) { + control.nav.top.style.display = ''; + } + else { + control.style.display = ''; + } + }; + view._selectMode = function () { // for navigator + if (view._options.navigatorSelectMode) { + return view._options.navigatorSelectMode; + } + + if (control.isCalendar) { + switch (control.viewType) { + case "Day": + return "day"; + case "Week": + return "week"; + case "WorkWeek": + return "week"; + default: + return "day"; + } + } + else if (control.isMonth) { + switch (control.viewType) { + case "Month": + return "month"; + case "Weeks": + return "week"; + default: + return "day"; + } + } + return "day"; + }; + + this._views.push(view); + + return view; + }; + + this.addTrigger = function (id, control) { + var element; + if (typeof id === 'string') { + element = document.getElementById(id); + if (!element) { + throw "Element not found: " + id; + } + } + else { + element = id; + } + + var view = this._findViewByControl(control); + if (!view) { + view = this.addView(control); + } + + var trigger = {}; + trigger._isTrigger = true; + trigger._element = element; + trigger._id = element.id; + trigger._view = view; + trigger._onClick = function (ev) { + + This.show(trigger); + This._select(trigger); + + if (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + } + + }; + + DayPilot.re(element, 'click', trigger._onClick); + + this._triggers.push(trigger); + + return trigger; + }; + + // backwards compatibility + this.addButton = this.addTrigger; + + this.select = function(id) { + var trigger = this._findTriggerById(id); + if (trigger) { + trigger._onClick(); + } + else if (this._triggers.length > 0) { + this._triggers[0]._onClick(); + } + }; + + this._findTriggerById = function(id) { + for (var i = 0; i < this._triggers.length; i++) { + var trigger = this._triggers[i]; + if (trigger._id === id) { + return trigger; + } + } + return null; + }; + + this._select = function(trigger) { + if (!this.selectedClass) { + return; + } + + for (var i = 0; i < this._triggers.length; i++) { + var s = this._triggers[i]; + DayPilot.Util.removeClass(s._element, this.selectedClass); + } + DayPilot.Util.addClass(trigger._element, this.selectedClass); + }; + + this.addNavigator = function (control) { + //this.navigator = {}; + This._navigator.control = control; + + control.timeRangeSelectedHandling = "JavaScript"; + control.onTimeRangeSelected = function() { + var start, end, day; + if (control.api === 1) { + start = arguments[0]; + end = arguments[1]; + day = arguments[2]; + } + else { + var args = arguments[0]; + start = args.start; + end = args.end; + day = args.day; + } + This._day = day; + + navigate(start, end, day); + + }; + }; + + this.show = function (el) { + var view, trigger; + if (el._isTrigger) { + trigger = el; + view = trigger._view; + } + else { + view = el._isView ? el : this._findViewByControl(el); + if (this._active === view) { + return; + } + } + + if (This.onSelect) { + var args = {}; + args.source = trigger ? trigger._element : null; + args.target = view.control; + + This.onSelect(args); + // TODO add preventDefault + } + + this._active = view; + view._show(); + + var mode = view._selectMode(); + This._navigator.updateMode(mode); + + //This.navigator.select(This.day); + + //This.active.sendNavigate(this.day); + + // this ensures first onChange call if single day = today is displayed + var start = This._navigator.control.selectionStart; + var end = This._navigator.control.selectionEnd.addDays(1); + var day = This._navigator.control.selectionDay; + navigate(start, end, day); + }; + + this._findViewByControl = function (control) { + for (var i = 0; i < this._views.length; i++) { + if (this._views[i].control === control) { + return this._views[i]; + } + } + return null; + }; + + this._hideViews = function () { + //var controls = [dp_day, dp_week, dp_month]; + for (var i = 0; i < this._views.length; i++) { + this._views[i]._hide(); + } + }; + + Object.defineProperty(this, "active", { + get: function() { + return This._active; + } + }); + + this.events = {}; + + this.events.load = function(url, success, error) { + if (This._active && This._active.control) { + This._active.control.events.load(url, success, error); + } + else { + throw "DayPilot.Switcher.events.load(): Active view not found"; + } + }; + + this._previousArgs = null; + + this._init = function() { + if (!options) { + return; + } + + for (var name in options) { + if (name === "triggers") { + var triggers = options.triggers || []; + triggers.forEach(function(item) { + This.addTrigger(item.id, item.view); + }); + } + else if (name === "navigator") { + This.addNavigator(options.navigator); + } + else { + This[name] = options[name]; + } + } + + }; + + this._init(); + + function navigate(start, end, day) { + var args = {}; + args.start = start; + args.end = end; + args.day = day; + args.target = This._active.control; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + var previous = This._previousArgs; + if (previous) { + if (previous.start === args.start && previous.end === args.end && previous.day === args.day && previous.target === args.target) { + return; // duplicate, no change + } + } + + This._previousArgs = args; + + if (typeof This.onChange === "function") { + This.onChange(args); + if (args.preventDefault.value) { + return; + } + } + + // backwards compatibility + if (typeof This.onTimeRangeSelect === "function") { + This.onTimeRangeSelect(args); + if (args.preventDefault.value) { + return; + } + } + + This._active._sendNavigate(This._day); + + if (typeof This.onChanged === "function") { + This.onChanged(args); + } + + if (typeof This.onTimeRangeSelected === "function") { + This.onTimeRangeSelected(args); + } + + } + + }; + + // DayPilot.Date START + + DayPilot.Duration = function(ticks) { + var d = this; + + var day = 1000*60*60*24.0; + var hour = 1000*60*60.0; + var minute = 1000*60.0; + var second = 1000.0; + + if (arguments.length === 2) { + var start = arguments[0]; + var end = arguments[1]; + + if (!(start instanceof DayPilot.Date) && (typeof start !== "string")) { + throw "DayPilot.Duration(): Invalid start argument, DayPilot.Date expected"; + } + if (!(end instanceof DayPilot.Date) && (typeof end !== "string")) { + throw "DayPilot.Duration(): Invalid end argument, DayPilot.Date expected"; + } + if (typeof start === "string") { + start = new DayPilot.Date(start); + } + if (typeof end === "string") { + end = new DayPilot.Date(end); + } + ticks = end.getTime() - start.getTime(); + } + + this.ticks = ticks; + + // caching, allows direct comparison + if (DayPilot.Date.Cache.DurationCtor["" + ticks]) { + return DayPilot.Date.Cache.DurationCtor["" + ticks]; + } + DayPilot.Date.Cache.DurationCtor["" + ticks] = this; + + this.toString = function(pattern) { + if (!pattern) { + return d.days() + "." + d.hours() + ":" + d.minutes() + ":" + d.seconds() + "." + d.milliseconds(); + } + + var minutes = d.minutes(); + minutes = (minutes < 10 ? "0" : "") + minutes; + + // dumb replacement + var result = pattern; + result = result.replace("mm", minutes); + result = result.replace("m", d.minutes()); + result = result.replace("H", d.hours()); + result = result.replace("h", d.hours()); + result = result.replace("d", d.days()); + result = result.replace("s", d.seconds()); + return result; + }; + + this.totalHours = function() { + return d.ticks / hour; + }; + + this.totalDays = function() { + return d.ticks / day; + }; + + this.totalMinutes = function() { + return d.ticks / minute; + }; + + this.totalSeconds = function() { + return d.ticks / second; + }; + + this.days = function() { + return Math.floor(d.totalDays()); + }; + + this.hours = function() { + var hourPartTicks = d.ticks - d.days()*day; + return Math.floor(hourPartTicks/hour); + }; + + this.minutes = function() { + var minutePartTicks = d.ticks - Math.floor(d.totalHours()) * hour; + return Math.floor(minutePartTicks/minute); + }; + + this.seconds = function() { + var secondPartTicks = d.ticks - Math.floor(d.totalMinutes()) * minute; + return Math.floor(secondPartTicks/second); + }; + + this.milliseconds = function() { + return d.ticks % second; + }; + + }; + + DayPilot.Duration.weeks = function(i) { + return new DayPilot.Duration(i * 1000*60*60*24*7); + }; + + DayPilot.Duration.days = function(i) { + return new DayPilot.Duration(i * 1000*60*60*24); + }; + + DayPilot.Duration.hours = function(i) { + return new DayPilot.Duration(i * 1000*60*60); + }; + + DayPilot.Duration.minutes = function(i) { + return new DayPilot.Duration(i * 1000*60); + }; + + DayPilot.Duration.seconds = function(i) { + return new DayPilot.Duration(i * 1000); + }; + + // alias to DayPilot.Duration + // disabled, doesn't work with caching + DayPilot.TimeSpan = function() { + + throw "Please use DayPilot.Duration class instead of DayPilot.TimeSpan."; + // DayPilot.Duration.apply(this, arguments); + }; + try { + DayPilot.TimeSpan.prototype = Object.create(DayPilot.Duration.prototype); // make instanceof work + } + catch (e) {} // doesn't work in IE8 + + // DayPilot.TimeSpan.prototype.constructor = DayPilot.TimeSpan; // not necessary, it's an alias, not an inherited class + + /* Date utils */ + + // DayPilot.Date class + /* Constructor signatures: + + -- new DayPilot.Date(date, isLocal) + date - JavaScript Date object + isLocal - true if the local time should be taken from date, otherwise GMT base is used + + -- new DayPilot.Date() - returns now, using local date + + -- new DayPilot.Date(string) + string - date in ISO 8601 format, e.g. 2009-01-01T00:00:00 + + */ + DayPilot.Date = function(date, readLocal) { + + if (date instanceof DayPilot.Date) { // it's already a DayPilot.Date object, return it (no copy) + return date; + } + + var ticks; + + if (DayPilot.Util.isNullOrUndefined(date)) { // date not set, use NOW + ticks = DayPilot.DateUtil.fromLocal().getTime(); + date = ticks; + } + + var cache = DayPilot.Date.Cache.Ctor; + if (cache[date]) { + DayPilot.Stats.cacheHitsCtor += 1; + return cache[date]; + } + + var isString = false; + + if (typeof date === "string") { + ticks = DayPilot.DateUtil.fromStringSortable(date, readLocal).getTime(); + isString = true; + } + else if (typeof date === "number") { + if (isNaN(date)) { + throw "Cannot create DayPilot.Date from NaN"; + } + ticks = date; + } + else if (date instanceof Date) { + if (readLocal) { + ticks = DayPilot.DateUtil.fromLocal(date).getTime(); + } + else { + ticks = date.getTime(); + } + } + else { + throw "Unrecognized parameter: use Date, number or string in ISO 8601 format"; + } + + var value = ticksToSortable(ticks); // normalized value + + if (cache[value]) { + return cache[value]; + } + + cache[value] = this; + cache[ticks] = this; + if (isString && value !== date && DayPilot.DateUtil.hasTzSpec(date)) { // don't cache strings with TZ spec + cache[date] = this; + } + + if (Object.defineProperty) { + Object.defineProperty(this, "ticks", { + get: function() { return ticks; } + }); + Object.defineProperty(this, "value", { + "value": value, + "writable": false, + "enumerable": true + }); + } + else { + this.ticks = ticks; + this.value = value; + } + + if (DayPilot.Date.Config.legacyShowD) { + this.d = new Date(ticks); + } + + DayPilot.Stats.dateObjects += 1; + }; + + DayPilot.Date.Config = {}; + DayPilot.Date.Config.legacyShowD = false; + + DayPilot.Date.Cache = {}; + DayPilot.Date.Cache.Parsing = {}; + DayPilot.Date.Cache.Ctor = {}; + DayPilot.Date.Cache.Ticks = {}; + DayPilot.Date.Cache.DurationCtor = {}; + + DayPilot.Date.Cache.clear = function() { + DayPilot.Date.Cache.Parsing = {}; + DayPilot.Date.Cache.Ctor = {}; + DayPilot.Date.Cache.Ticks = {}; + DayPilot.Date.Cache.DurationCtor = {}; + }; + + + DayPilot.Date.prototype.addDays = function(days) { + if (!days) { + return this; + } + return new DayPilot.Date(this.ticks + days * 24 * 60 * 60 * 1000); + }; + + DayPilot.Date.prototype.addHours = function(hours) { + if (!hours) { + return this; + } + return this.addTime(hours * 60 * 60 * 1000); + }; + + DayPilot.Date.prototype.addMilliseconds = function(millis) { + if (!millis) { + return this; + } + return this.addTime(millis); + }; + + DayPilot.Date.prototype.addMinutes = function(minutes) { + if (!minutes) { + return this; + } + return this.addTime(minutes * 60 * 1000); + }; + + DayPilot.Date.prototype.addMonths = function(months) { + if (!months) { + return this; + } + + var date = new Date(this.ticks); + + var y = date.getUTCFullYear(); + var m = date.getUTCMonth() + 1; + + if (months > 0) { + while (months >= 12) { + months -= 12; + y++; + } + if (months > 12 - m) { + y++; + m = months - (12 - m); + } + else { + m += months; + } + } + else { + while (months <= -12) { + months += 12; + y--; + } + if (m + months <= 0) { // + y--; + m = 12 + m + months; + } + else { + m = m + months; + } + } + + var d = new Date(date.getTime()); + d.setUTCDate(1); + d.setUTCFullYear(y); + d.setUTCMonth(m - 1); + + //var max = DayPilot.Date.daysInMonth(y, m); + var max = new DayPilot.Date(d).daysInMonth(); + d.setUTCDate(Math.min(max, date.getUTCDate())); + + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.addSeconds = function(seconds) { + if (!seconds) { + return this; + } + return this.addTime(seconds * 1000); + }; + + DayPilot.Date.prototype.addTime = function(ticks) { + if (!ticks) { + return this; + } + if (ticks instanceof DayPilot.Duration) { + ticks = ticks.ticks; + } + return new DayPilot.Date(this.ticks + ticks); + }; + + DayPilot.Date.prototype.addYears = function(years) { + var original = new Date(this.ticks); + var d = new Date(this.ticks); + var y = this.getYear() + years; + var m = this.getMonth(); + + d.setUTCDate(1); + d.setUTCFullYear(y); + d.setUTCMonth(m); + + //var max = DayPilot.Date.daysInMonth(y, m + 1); + var max = new DayPilot.Date(d).daysInMonth(); + d.setUTCDate(Math.min(max, original.getUTCDate())); + + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.dayOfWeek = function() { + return new Date(this.ticks).getUTCDay(); + }; + + DayPilot.Date.prototype.getDayOfWeek = function() { + return new Date(this.ticks).getUTCDay(); + }; + + DayPilot.Date.prototype.getDayOfYear = function() { + var first = this.firstDayOfYear(); + return DayPilot.DateUtil.daysDiff(first, this) + 1; + }; + + DayPilot.Date.prototype.daysInMonth = function() { + var date = new Date(this.ticks); + var month = date.getUTCMonth() + 1; + var year = date.getUTCFullYear(); + + + var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + if (month !== 2) + return m[month - 1]; + if (year % 4 !== 0) + return m[1]; + if (year % 100 === 0 && year % 400 !== 0) + return m[1]; + return m[1] + 1; + + }; + + DayPilot.Date.prototype.daysInYear = function() { + var year = this.getYear(); + if (year % 4 !== 0) { + return 365; + } + if (year % 100 === 0 && year % 400 !== 0) { + return 365; + } + return 366; + }; + + DayPilot.Date.prototype.dayOfYear = function() { + return Math.ceil((this.getDatePart().getTime() - this.firstDayOfYear().getTime()) / 86400000) + 1; + }; + + // not required, direct comparison can be used + DayPilot.Date.prototype.equals = function(another) { + if (another === null) { + return false; + } + if (another instanceof DayPilot.Date) { + return this === another; + } + else { + throw "The parameter must be a DayPilot.Date object (DayPilot.Date.equals())"; + } + }; + + DayPilot.Date.prototype.firstDayOfMonth = function() { + //var utc = DayPilot.Date.firstDayOfMonth(this.getYear(), this.getMonth() + 1); + //return new DayPilot.Date(utc); + + var d = new Date(); + d.setUTCFullYear(this.getYear(), this.getMonth(), 1); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return new DayPilot.Date(d); + + }; + + DayPilot.Date.prototype.firstDayOfYear = function() { + var year = this.getYear(); + var d = new Date(); + d.setUTCFullYear(year, 0, 1); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.firstDayOfWeek = function(weekStarts) { + var d = this; + if (weekStarts instanceof DayPilot.Locale) { + weekStarts = weekStarts.weekStarts; + } + else if (typeof weekStarts === "string" && DayPilot.Locale.find(weekStarts)) { + var locale = DayPilot.Locale.find(weekStarts); + weekStarts = locale.weekStarts; + } + else { + weekStarts = weekStarts || 0; + } + + var day = d.dayOfWeek(); + while (day !== weekStarts) { + d = d.addDays(-1); + day = d.dayOfWeek(); + } + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.getDay = function() { + return new Date(this.ticks).getUTCDate(); + }; + + DayPilot.Date.prototype.getDatePart = function() { + var d = new Date(this.ticks); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.getYear = function() { + return new Date(this.ticks).getUTCFullYear(); + }; + + DayPilot.Date.prototype.getHours = function() { + return new Date(this.ticks).getUTCHours(); + }; + + DayPilot.Date.prototype.getMilliseconds = function() { + return new Date(this.ticks).getUTCMilliseconds(); + }; + + DayPilot.Date.prototype.getMinutes = function() { + return new Date(this.ticks).getUTCMinutes(); + }; + + DayPilot.Date.prototype.getMonth = function() { + return new Date(this.ticks).getUTCMonth(); + }; + + DayPilot.Date.prototype.getSeconds = function() { + return new Date(this.ticks).getUTCSeconds(); + }; + + DayPilot.Date.prototype.getTotalTicks = function() { + return this.getTime(); + }; + + // undocumented + DayPilot.Date.prototype.getTime = function() { + return this.ticks; + }; + + DayPilot.Date.prototype.getTimePart = function() { + var datePart = this.getDatePart(); + return DayPilot.DateUtil.diff(this, datePart); + }; + + DayPilot.Date.prototype.lastDayOfMonth = function() { + //var utc = DayPilot.Date.lastDayOfMonth(this.getYear(), this.getMonth() + 1); + //return new DayPilot.Date(utc); + var d = new Date(this.firstDayOfMonth().getTime()); + var length = this.daysInMonth(); + d.setUTCDate(length); + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.weekNumber = function() { + var first = this.firstDayOfYear(); + var days = (this.getTime() - first.getTime()) / 86400000; + return Math.ceil((days + first.dayOfWeek() + 1) / 7); + }; + + // ISO 8601 + DayPilot.Date.prototype.weekNumberISO = function() { + var thursdayFlag = false; + var dayOfYear = this.dayOfYear(); + + var startWeekDayOfYear = this.firstDayOfYear().dayOfWeek(); + var endWeekDayOfYear = this.firstDayOfYear().addYears(1).addDays(-1).dayOfWeek(); + //int startWeekDayOfYear = new DateTime(date.getYear(), 1, 1).getDayOfWeekOrdinal(); + //int endWeekDayOfYear = new DateTime(date.getYear(), 12, 31).getDayOfWeekOrdinal(); + + if (startWeekDayOfYear === 0) { + startWeekDayOfYear = 7; + } + if (endWeekDayOfYear === 0) { + endWeekDayOfYear = 7; + } + + var daysInFirstWeek = 8 - (startWeekDayOfYear); + + if (startWeekDayOfYear === 4 || endWeekDayOfYear === 4) { + thursdayFlag = true; + } + + var fullWeeks = Math.ceil((dayOfYear - (daysInFirstWeek)) / 7.0); + + var weekNumber = fullWeeks; + + if (daysInFirstWeek >= 4) { + weekNumber = weekNumber + 1; + } + + if (weekNumber > 52 && !thursdayFlag) { + weekNumber = 1; + } + + if (weekNumber === 0) { + weekNumber = this.firstDayOfYear().addDays(-1).weekNumberISO(); //weekNrISO8601(new DateTime(date.getYear() - 1, 12, 31)); + } + + return weekNumber; + + }; + + DayPilot.Date.prototype.toDateLocal = function() { + var date = new Date(this.ticks); + + var d = new Date(); + d.setFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); + d.setHours(date.getUTCHours()); + d.setMinutes(date.getUTCMinutes()); + d.setSeconds(date.getUTCSeconds()); + d.setMilliseconds(date.getUTCMilliseconds()); + return d; + + }; + + DayPilot.Date.prototype.toDate = function() { + return new Date(this.ticks); + }; + + DayPilot.Date.prototype.toJSON = function() { + return this.value; + }; + + // formatting and languages needed here + DayPilot.Date.prototype.toString = function(pattern, locale) { + if (!pattern) { + return this.toStringSortable(); + } + return new Pattern(pattern, locale).print(this); + }; + + DayPilot.Date.prototype.toStringSortable = function() { + return ticksToSortable(this.ticks); + }; + + function ticksToSortable(ticks) { + + var cache = DayPilot.Date.Cache.Ticks; + if (cache[ticks]) { + DayPilot.Stats.cacheHitsTicks += 1; + return cache[ticks]; + } + + var d = new Date(ticks); + + var millisecond; + var ms = d.getUTCMilliseconds(); + + if (ms === 0) { + millisecond = ""; + } + else if (ms < 10) { + millisecond = ".00" + ms; + } + else if (ms < 100) { + millisecond = ".0" + ms; + } + else { + millisecond = "." + ms + } + + var second = d.getUTCSeconds(); + if (second < 10) + second = "0" + second; + var minute = d.getUTCMinutes(); + if (minute < 10) + minute = "0" + minute; + var hour = d.getUTCHours(); + if (hour < 10) + hour = "0" + hour; + var day = d.getUTCDate(); + if (day < 10) + day = "0" + day; + var month = d.getUTCMonth() + 1; + if (month < 10) + month = "0" + month; + var year = d.getUTCFullYear(); + + if (year <= 0) { + throw "The minimum year supported is 1."; + } + if (year < 10) { + year = "000" + year; + } + else if (year < 100) { + year = "00" + year; + } + else if (year < 1000) { + year = "0" + year; + } + + var result = year + "-" + month + "-" + day + 'T' + hour + ":" + minute + ":" + second + millisecond; + cache[ticks] = result; + return result; + } + + /* static functions, return DayPilot.Date object */ + + // returns null if parsing was not successful + DayPilot.Date.parse = function(str, pattern, locale) { + var p = new Pattern(pattern, locale); + return p.parse(str); + }; + + var todayCount = 0; + + DayPilot.Date.today = function() { + //return new DayPilot.Date().getDatePart(); + return new DayPilot.Date(DayPilot.DateUtil.localToday(), true); + }; + + DayPilot.Date.now = function() { + return new DayPilot.Date(); + }; + + DayPilot.Date.fromYearMonthDay = function(year, month, day) { + month = month || 1; + day = day || 1; + + var d = new Date(0); + d.setUTCFullYear(year); + d.setUTCMonth(month - 1); + d.setUTCDate(day); + return new DayPilot.Date(d); + }; + + DayPilot.DateUtil = {}; + + /* internal functions, all operate with GMT base of the date object + (except of DayPilot.DateUtil.fromLocal()) */ + + DayPilot.DateUtil.fromStringSortable = function(string, readLocal) { + /* + Supported formats: + 2015-01-01 + 2015-01-01T00:00:00 + 2015-01-01T00:00:00.000 + 2015-01-01T00:00:00Z + 2015-01-01T00:00:00.000Z + 2015-01-01T00:00:00+01:00 + 2015-01-01T00:00:00.000+01:00 + + */ + + if (!string) { + throw "Can't create DayPilot.Date from an empty string"; + } + + var len = string.length; + var date = len === 10; + var datetime = len === 19; + var long = len > 19; + + if (!date && !datetime && !long) { + throw "Invalid string format (use '2010-01-01' or '2010-01-01T00:00:00'): " + string; + } + + if (DayPilot.Date.Cache.Parsing[string] && !readLocal) { + DayPilot.Stats.cacheHitsParsing += 1; + return DayPilot.Date.Cache.Parsing[string]; + } + + var year = string.substring(0, 4); + var month = string.substring(5, 7); + var day = string.substring(8, 10); + + var d = new Date(0); + d.setUTCFullYear(year, month - 1, day); + + if (date) { + /* + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + */ + //result = d; + DayPilot.Date.Cache.Parsing[string] = d; + return d; + } + + var hours = string.substring(11, 13); + var minutes = string.substring(14, 16); + var seconds = string.substring(17, 19); + + d.setUTCHours(hours); + d.setUTCMinutes(minutes); + d.setUTCSeconds(seconds); + //d.setUTCMilliseconds(0); + //result = d; + + if (datetime) { + DayPilot.Date.Cache.Parsing[string] = d; + return d; + } + + var tzdir = string[19]; + + var tzoffset = 0; + + if (tzdir === ".") { + var ms = parseInt(string.substring(20, 23)); /// .000 + d.setUTCMilliseconds(ms); + tzoffset = DayPilot.DateUtil.getTzOffsetMinutes(string.substring(23)); + } + else { + tzoffset = DayPilot.DateUtil.getTzOffsetMinutes(string.substring(19)); + } + + var dd = new DayPilot.Date(d); + if (!readLocal) { + dd = dd.addMinutes(-tzoffset); + } + + d = dd.toDate(); // get UTC base + + DayPilot.Date.Cache.Parsing[string] = d; + return d; + }; + + DayPilot.DateUtil.getTzOffsetMinutes = function(string) { + if (DayPilot.Util.isNullOrUndefined(string) || string === "") { + return 0; + } + if (string === "Z") { + return 0; + } + + var tzdir = string[0]; + + var tzhours = parseInt(string.substring(1, 3)); + var tzminutes = parseInt(string.substring(4)); + var tzoffset = tzhours * 60 + tzminutes; + + if (tzdir === "-") { + return -tzoffset; + } + else if (tzdir === "+") { + return tzoffset; + } + else { + throw "Invalid timezone spec: " + string; + } + }; + + DayPilot.DateUtil.hasTzSpec = function(string) { + if (string.indexOf("+")) { + return true; + } + if (string.indexOf("-")) { + return true; + } + return false; + }; + + + // rename candidate: diffDays + DayPilot.DateUtil.daysDiff = function(first, second) { + (first && second) || (function() { throw "two parameters required"; })(); + + first = new DayPilot.Date(first); + second = new DayPilot.Date(second); + + if (first.getTime() > second.getTime()) { + return null; + } + + var i = 0; + var fDay = first.getDatePart(); + var sDay = second.getDatePart(); + + while (fDay < sDay) { + fDay = fDay.addDays(1); + i++; + } + + return i; + }; + + DayPilot.DateUtil.daysSpan = function(first, second) { + (first && second) || (function() { throw "two parameters required"; })(); + + first = new DayPilot.Date(first); + second = new DayPilot.Date(second); + + if (first.getTime() === second.getTime()) { + return 0; + } + + var diff = DayPilot.DateUtil.daysDiff(first, second); + + if (second.getTime() == second.getDatePart().getTime()) { + diff--; + } + + return diff; + }; + + DayPilot.DateUtil.diff = function(first, second) { // = first - second + if (!(first && second && first.getTime && second.getTime)) { + throw "Both compared objects must be Date objects (DayPilot.Date.diff)."; + } + + return first.getTime() - second.getTime(); + }; + + // returns Date object + DayPilot.DateUtil.fromLocal = function(localDate) { + if (!localDate) { + localDate = new Date(); + } + + var d = new Date(); + d.setUTCFullYear(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()); + d.setUTCHours(localDate.getHours()); + d.setUTCMinutes(localDate.getMinutes()); + d.setUTCSeconds(localDate.getSeconds()); + d.setUTCMilliseconds(localDate.getMilliseconds()); + return d; + }; + + DayPilot.DateUtil.localToday = function() { + var d = new Date(); + d.setHours(0); + d.setMinutes(0); + d.setSeconds(0); + d.setMilliseconds(0); + return d; + }; + + // rename candidate: toHourString + DayPilot.DateUtil.hours = function(date, use12) { + + var minute = date.getUTCMinutes(); + if (minute < 10) + minute = "0" + minute; + + + var hour = date.getUTCHours(); + //if (hour < 10) hour = "0" + hour; + + if (use12) { + var am = hour < 12; + var hour = hour % 12; + if (hour === 0) { + hour = 12; + } + var suffix = am ? "AM" : "PM"; + return hour + ':' + minute + ' ' + suffix; + } + else { + return hour + ':' + minute; + } + }; + + DayPilot.DateUtil.max = function(first, second) { + if (first.getTime() > second.getTime()) { + return first; + } + else { + return second; + } + }; + + DayPilot.DateUtil.min = function(first, second) { + if (first.getTime() < second.getTime()) { + return first; + } + else { + return second; + } + }; + + var Pattern = function(pattern, locale) { + if (typeof locale === "string") { + locale = DayPilot.Locale.find(locale); + } + var locale = locale || DayPilot.Locale.US; + var all = [ + {"seq": "yyyy", "expr": "[0-9]{4,4\u007d", "str": function(d) { + return d.getYear(); + }}, + {"seq": "yy", "expr": "[0-9]{2,2\u007d", "str": function(d) { + return d.getYear() % 100; + }}, + {"seq": "mm", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getMinutes(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "m", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getMinutes(); + return r; + }}, + {"seq": "HH", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getHours(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "H", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getHours(); + return r; + }}, + {"seq": "hh", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var hour = d.getHours(); + var hour = hour % 12; + if (hour === 0) { + hour = 12; + } + var r = hour; + return r < 10 ? "0" + r : r; + }}, + {"seq": "h", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var hour = d.getHours(); + var hour = hour % 12; + if (hour === 0) { + hour = 12; + } + return hour; + }}, + {"seq": "ss", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getSeconds(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "s", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getSeconds(); + return r; + }}, + {"seq": "MMMM", "expr": "[^\\s0-9]*", "str": function(d) { + var r = locale.monthNames[d.getMonth()]; + return r; + }, "transform" : function(input) { + var index = DayPilot.indexOf(locale.monthNames, input, equalsIgnoreCase); + if (index < 0) { + return null; + } + return index + 1; + }}, + {"seq": "MMM", "expr": "[^\\s0-9]*", "str": function(d) { // \u0073 = 's' + var r = locale.monthNamesShort[d.getMonth()]; + return r; + }, "transform" : function(input) { + var index = DayPilot.indexOf(locale.monthNamesShort, input, equalsIgnoreCase); + if (index < 0) { + return null; + } + return index + 1; + }}, + {"seq": "MM", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getMonth() + 1; + return r < 10 ? "0" + r : r; + }}, + {"seq": "M", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getMonth() + 1; + return r; + }}, + {"seq": "dddd", "expr": "[^\\s0-9]*", "str": function(d) { + var r = locale.dayNames[d.getDayOfWeek()]; + return r; + }}, + {"seq": "ddd", "expr": "[^\\s0-9]*", "str": function(d) { + var r = locale.dayNamesShort[d.getDayOfWeek()]; + return r; + }}, + {"seq": "dd", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getDay(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "%d", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getDay(); + return r; + }}, + {"seq": "d", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getDay(); + return r; + }}, + {"seq": "tt", "expr": "(AM|PM|am|pm)", "str": function(d) { + var hour = d.getHours(); + var am = hour < 12; + return am ? "AM" : "PM"; + }, "transform" : function(input) { + return input.toUpperCase(); + }}, + ]; + + var escapeRegex = function(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + }; + + this.init = function() { + this.year = this.findSequence("yyyy"); + this.month = this.findSequence("MMMM") || this.findSequence("MMM") || this.findSequence("MM") || this.findSequence("M"); + this.day = this.findSequence("dd") || this.findSequence("d"); + + this.hours = this.findSequence("HH") || this.findSequence("H"); + this.minutes = this.findSequence("mm") || this.findSequence("m"); + this.seconds = this.findSequence("ss") || this.findSequence("s"); + + this.ampm = this.findSequence("tt"); + this.hours12 = this.findSequence("hh") || this.findSequence("h"); + + /*if (this.hours && this.ampm) { + throw new DayPilot.Exception("'HH' and 'H' specifiers cannot be used in combination with 'tt'. Use 12-hour clock specifiers: 'hh' or 'h'."); + }*/ + }; + + this.findSequence = function(seq) { + + function defaultTransform(value) { + return parseInt(value); + } + + var index = pattern.indexOf(seq); + if (index === -1) { + return null; + } + return { + "findValue": function(input) { + var prepared = escapeRegex(pattern); + var transform = null; + for (var i = 0; i < all.length; i++) { + var len = all[i].length; + var pick = (seq === all[i].seq); + //var expr = ""; + var expr = all[i].expr; + if (pick) { + expr = "(" + expr + ")"; + transform = all[i].transform; + } + prepared = prepared.replace(all[i].seq, expr); + } + + prepared = "^" + prepared + "$"; + + try { + var r = new RegExp(prepared); + var array = r.exec(input); + if (!array) { + return null; + } + transform = transform || defaultTransform; // parseInt is the default transform/parse function + return transform(array[1]); + } + catch (e) { + throw "unable to create regex from: " + prepared; + } + } + }; + }; + + this.print = function(date) { + // always recompiles the pattern + + var find = function(t) { + for (var i = 0; i < all.length; i++) { + if (all[i] && all[i].seq === t) { + return all[i]; + } + } + return null; + }; + + var eos = pattern.length <= 0; + var pos = 0; + var components = []; + + while (!eos) { + var rem = pattern.substring(pos); + var matches = /%?(.)\1*/.exec(rem); // matches a sequence of identical characters, with an optional '%' preceding char + if (matches && matches.length > 0) { + var match = matches[0]; + var q = find(match); + if (q) { + components.push(q); + } + else { + components.push(match); + } + pos += match.length; + eos = pattern.length <= pos; + } + else { + eos = true; + } + } + + // resolve placeholders + for (var i = 0; i < components.length; i++) { + var c = components[i]; + if (typeof c !== 'string') { + components[i] = c.str(date); + } + } + + return components.join(""); + }; + + + + this.parse = function(input) { + + var year = this.year.findValue(input); + if (!year) { + return null; // unparseable + } + + var month = this.month.findValue(input); + if (DayPilot.Util.isNullOrUndefined(month)) { + return null; + } + if (month > 12 || month < 1) { + return null; + } + var day = this.day.findValue(input); + + var daysInMonth = DayPilot.Date.fromYearMonthDay(year, month).daysInMonth(); + if (day < 1 || day > daysInMonth) { + return null; + } + + var hours = this.hours ? this.hours.findValue(input) : 0; + var minutes = this.minutes ? this.minutes.findValue(input) : 0; + var seconds = this.seconds ? this.seconds.findValue(input) : 0; + + var ampm = this.ampm ? this.ampm.findValue(input): null; + + if (this.ampm && this.hours12) { + + var hours12 = this.hours12.findValue(input); + + if (hours12 < 1 || hours12 > 12) { + return null; + } + + if (ampm === "PM") { + if (hours12 === 12) { + hours = 12; + } + else { + hours = hours12 + 12; + } + } + else { + if (hours12 === 12) { + hours = 0; + } + else { + hours = hours12; + } + } + + } + + if (hours < 0 || hours > 23) { + return null; + } + + if (minutes < 0 || minutes > 59) { + return null; + } + + if (seconds < 0 || seconds > 59) { + return null; + } + + var d = new Date(); + d.setUTCFullYear(year, month - 1, day); + d.setUTCHours(hours); + d.setUTCMinutes(minutes); + d.setUTCSeconds(seconds); + d.setUTCMilliseconds(0); + + return new DayPilot.Date(d); + }; + + this.init(); + + }; + + function equalsIgnoreCase(str1, str2) { + if (DayPilot.Util.isNullOrUndefined(str1)) { + return false; + } + if (DayPilot.Util.isNullOrUndefined(str2)) { + return false; + } + return str1.toLocaleLowerCase() === str2.toLocaleLowerCase(); + } + + // DayPilot.Date END + + + DayPilot.ColorUtil = {}; + + function toHex(dec) { + dec = Math.min(dec, 255); + dec = Math.max(dec, 0); + var str = dec.toString(16); + return (dec < 16) ? "0" + str : str; + } + + DayPilot.ColorUtil.hexToRgb = function(hex) { + if (!/^#[0-9a-f]{6}$/i.test(hex)) { + throw new DayPilot.Exception("Invalid color, only full hex color string accepted, eg. '#ffaaff'."); + } + hex = hex.replace("#", ""); + return { + r: parseInt(hex.substring(0, 2), 16), + g: parseInt(hex.substring(2, 4), 16), + b: parseInt(hex.substring(4, 6), 16), + }; + }; + + DayPilot.ColorUtil.rgbToHex = function(rgb) { + return "#" + toHex(rgb.r) + toHex(rgb.g) + toHex(rgb.b); + }; + + // pt in 255 base + DayPilot.ColorUtil.adjustLuminance = function(rgb, pt) { + return { + r: rgb.r + pt, + g: rgb.g + pt, + b: rgb.b + pt + }; + }; + + DayPilot.ColorUtil.darker = function(hexColor, steps) { + var src = DayPilot.ColorUtil.hexToRgb(hexColor); + steps = steps || 1; + var step = 17; // (0xbb - 0xaa = 17) + var pt = steps * step; + var target = DayPilot.ColorUtil.adjustLuminance(src, -pt); + return DayPilot.ColorUtil.rgbToHex(target); + }; + + DayPilot.ColorUtil.lighter = function(hexColor, steps) { + if (typeof steps !== "number") { + steps = 1; + } + return DayPilot.ColorUtil.darker(hexColor, -steps); + }; + + + DayPilot.ColorUtil.pl = function(hexColor) { + var rgb = DayPilot.ColorUtil.hexToRgb(hexColor); + var r = rgb.r / 255; + var g = rgb.g / 255; + var b = rgb.b / 255; + var pl = Math.sqrt(0.299*r*r + 0.587*g*g + 0.114*b*b); + return pl; + }; + + DayPilot.ColorUtil.contrasting = function(hexColor, light, dark) { + var pl = DayPilot.ColorUtil.pl(hexColor); + light = light || "#ffffff"; + dark = dark || "#000000"; + return pl > 0.5 ? dark : light; + }; + + + DayPilot.Event = function(data, calendar, part) { + var e = this; + this.calendar = calendar; + this.data = data ? data : {}; + this.part = part ? part : {}; + + // backwards compatibility, still accepts id in "value" + if (typeof this.data.id === 'undefined') { + this.data.id = this.data.value; + } + + var copy = {}; + var synced = ["id", "text", "start", "end", "resource"]; + + this.isEvent = true; + + // internal + this.temp = function() { + if (copy.dirty) { + return copy; + } + for (var i = 0; i < synced.length; i++) { + copy[synced[i]] = e.data[synced[i]]; + } + copy.dirty = true; + return copy; + + }; + + // internal + this.copy = function() { + var result = {}; + for (var i = 0; i < synced.length; i++) { + result[synced[i]] = e.data[synced[i]]; + } + return result; + }; + + this.commit = function() { + if (!copy.dirty) { + return; + } + + for (var i = 0; i < synced.length; i++) { + e.data[synced[i]] = copy[synced[i]]; + } + + copy.dirty = false; + }; + + this.dirty = function() { + return copy.dirty; + }; + + this.id = function(val) { + if (typeof val === 'undefined') { + return e.data.id; + } + else { + this.temp().id = val; + } + }; + // obsolete, use id() instead + this.value = function(val) { + if (typeof val === 'undefined') { + return e.id(); + } + else { + e.id(val); + } + }; + this.text = function(val) { + if (typeof val === 'undefined') { + return e.data.text; + } + else { + this.temp().text = val; + this.client.innerHTML(val); // update the HTML automatically + } + }; + this.start = function(val) { + if (typeof val === 'undefined') { + return new DayPilot.Date(e.data.start); + } + else { + this.temp().start = new DayPilot.Date(val); + } + }; + this.end = function(val) { + if (typeof val === 'undefined') { + return new DayPilot.Date(e.data.end); + } + else { + this.temp().end = new DayPilot.Date(val); + } + }; + this.resource = function(val) { + if (typeof val === 'undefined') { + return e.data.resource; + } + else { + this.temp().resource = val; + } + }; + this.partStart = function() { + return new DayPilot.Date(this.part.start); + }; + this.partEnd = function() { + return new DayPilot.Date(this.part.end); + }; + + this.tag = function(field) { + var values = e.data.tag; + if (!values) { + return null; + } + if (typeof field === 'undefined') { + return e.data.tag; + } + var fields = e.calendar.tagFields; + var index = -1; + for (var i = 0; i < fields.length; i++) { + if (field === fields[i]) + index = i; + } + if (index === -1) { + throw "Field name not found."; + } + //var tags = t.split('&'); + return values[index]; + }; + + this.client = {}; + this.client.innerHTML = function(val) { + if (typeof val === 'undefined') { + var data = e.cache || e.data; + var xssTextHtml = e.calendar && e.calendar.internal && e.calendar.internal.xssTextHtml; + if (xssTextHtml) { + return xssTextHtml(data.text, data.html); + } + return DayPilot.Util.escapeTextHtml(data.text, data.html); + + /* + if (e.cache && typeof e.cache.html !== "undefined") { + return e.cache.html; + } + if (typeof e.data.html !== "undefined") { + return e.data.html; + } + return e.data.text; + */ + } + else { + e.data.html = val; + } + }; + + this.client.html = this.client.innerHTML; + + this.client.header = function(val) { + if (typeof val === 'undefined') { + return e.data.header; + } + else { + e.data.header = val; + } + }; + + this.client.cssClass = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.cssClass !== "undefined") { + return e.cache.cssClass; + } + return e.data.cssClass; + } + else { + e.data.cssClass = val; + } + }; + this.client.toolTip = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.toolTip !== "undefined") { + return e.cache.toolTip; + } + return typeof e.data.toolTip !== 'undefined' ? e.data.toolTip : e.data.text; + } + else { + e.data.toolTip = val; + } + }; + + this.client.barVisible = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.barHidden !== "undefined") { + return !e.cache.barHidden; + } + return e.calendar.durationBarVisible && !e.data.barHidden; + } + else { + e.data.barHidden = !val; + } + }; + + this.client.backColor = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.backColor !== "undefined") { + return e.cache.backColor; + } + return typeof e.data.backColor !== "undefined" ? e.data.backColor : e.calendar.eventBackColor; + } + else { + e.data.backColor = val; + } + }; + + this.client.borderColor = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.borderColor !== "undefined") { + return e.cache.borderColor; + } + return typeof e.data.borderColor !== "undefined" ? e.data.borderColor : e.calendar.eventBorderColor; + } + else { + e.data.borderColor = val; + } + }; + + this.client.contextMenu = function(val) { + if (typeof val === 'undefined') { + if (e.oContextMenu) { + return e.oContextMenu; + } + var cm = e.cache ? e.cache.contextMenu : e.data.contextMenu; + } + else { + e.oContextMenu = val; + } + }; + + this.client.moveEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.moveDisabled !== "undefined") { + return !e.cache.moveDisabled; + } + + return e.calendar.eventMoveHandling !== 'Disabled' && !e.data.moveDisabled; + } + else { + e.data.moveDisabled = !val; + } + }; + + this.client.resizeEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.resizeDisabled !== "undefined") { + return !e.cache.resizeDisabled; + } + return e.calendar.eventResizeHandling !== 'Disabled' && !e.data.resizeDisabled; + } + else { + e.data.resizeDisabled = !val; + } + }; + + this.client.clickEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.clickDisabled !== "undefined") { + return !e.cache.clickDisabled; + } + return e.calendar.eventClickHandling !== 'Disabled' && !e.data.clickDisabled; + } + else { + e.data.clickDisabled = !val; + } + }; + + this.client.rightClickEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.rightClickDisabled !== "undefined") { + return !e.cache.rightClickDisabled; + } + return e.calendar.eventRightClickHandling !== 'Disabled' && !e.data.rightClickDisabled; + } + else { + e.data.rightClickDisabled = !val; + } + }; + + this.client.deleteEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.deleteDisabled !== "undefined") { + return !e.cache.deleteDisabled; + } + return e.calendar.eventDeleteHandling !== 'Disabled' && !e.data.deleteDisabled; + } + else { + e.data.deleteDisabled = !val; + } + }; + + this.toJSON = function(key) { + var json = {}; + json.value = this.id(); // still sending it with the old name + json.id = this.id(); + json.text = this.text(); + json.start = this.start(); + json.end = this.end(); + json.tag = {}; + + if (e.calendar && e.calendar.tagFields) { + var fields = e.calendar.tagFields; + for (var i = 0; i < fields.length; i++) { + json.tag[fields[i]] = this.tag(fields[i]); + } + } + + return json; + }; + }; + +})(); + +/* JSON */ +// thanks to http://www.json.org/js.html + + +// declares DayPilot.JSON.stringify() +DayPilot.JSON = {}; + +(function () { + function f(n) { + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON2 !== 'function') { + + Date.prototype.toJSON2 = function (key) { + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + ''; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + function quote(string) { + escapeable.lastIndex = 0; + return escapeable.test(string) ? + '"' + string.replace(escapeable, function (a) { + var c = meta[a]; + if (typeof c === 'string') { + return c; + } + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + function str(key, holder) { + var i, + k, + v, + length, + mind = gap, + partial, + value = holder[key]; + if (value && typeof value === 'object' && typeof value.toJSON2 === 'function') { + value = value.toJSON2(key); + } + else if (value && typeof value === 'object' && typeof value.toJSON === 'function' && !value.ignoreToJSON) { + value = value.toJSON(key); + } + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + switch (typeof value) { + case 'string': + return quote(value); + case 'number': + return isFinite(value) ? String(value) : 'null'; + case 'boolean': + case 'null': + return String(value); + case 'object': + if (!value) { + return 'null'; + } + gap += indent; + partial = []; + if (typeof value.length === 'number' && + !value.propertyIsEnumerable('length')) { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + v = (partial.length === 0) ? '{\u007D' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '\u007D' : '{' + partial.join(',') + '\u007D'; + gap = mind; + return v; + } + } + + if (typeof DayPilot.JSON.stringify !== 'function') { + DayPilot.JSON.stringify = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } else if (typeof space === 'string') { + indent = space; + } + rep = replacer; + if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + return str('', {'': value}); + }; + } + +})(); +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function() { + + var doNothing = function() {}; + + if (typeof DayPilot.Calendar !== 'undefined' && DayPilot.Calendar.events) { + return; + } + + var DayPilotCalendar = {}; + + // internal selecting + DayPilotCalendar.selectedCells = []; + DayPilotCalendar.topSelectedCell = null; + DayPilotCalendar.bottomSelectedCell = null; + DayPilotCalendar.selecting = false; + DayPilotCalendar.column = null; + DayPilotCalendar.firstSelected = null; + DayPilotCalendar.firstMousePos = null; + + // internal resizing + DayPilotCalendar.originalMouse = null; + DayPilotCalendar.originalHeight = null; + DayPilotCalendar.originalTop = null; + DayPilotCalendar.resizing = null; + DayPilotCalendar.globalHandlers = false; + + // internal moving + DayPilotCalendar.moving = null; + + // helpers + DayPilotCalendar.register = function(calendar) { + if (!DayPilotCalendar.registered) { + DayPilotCalendar.registered = []; + } + var r = DayPilotCalendar.registered; + + for (var i = 0; i < r.length; i++) { + if (r[i] === calendar) { + return; + } + } + r.push(calendar); + }; + + DayPilotCalendar.unregister = function (calendar) { + var a = DayPilotCalendar.registered; + if (!a) { + return; + } + + var i = DayPilot.indexOf(a, calendar); + if (i === -1) { + return; + } + a.splice(i, 1); + }; + + DayPilotCalendar.getCellsAbove = function(cell) { + var array = []; + var c = DayPilotCalendar.getColumn(cell); + + var tr = cell.parentNode; + + var select = null; + while (tr && select !== DayPilotCalendar.firstSelected) { + select = tr.getElementsByTagName("td")[c]; + array.push(select); + tr = tr.previousSibling; + while (tr && tr.tagName !== "TR") { + tr = tr.previousSibling; + } + } + return array; + }; + + DayPilotCalendar.getCellsBelow = function(cell) { + var array = []; + var c = DayPilotCalendar.getColumn(cell); + var tr = cell.parentNode; + + var select = null; + while (tr && select !== DayPilotCalendar.firstSelected) { + select = tr.getElementsByTagName("td")[c]; + array.push(select); + tr = tr.nextSibling; + while (tr && tr.tagName !== "TR") { + tr = tr.nextSibling; + } + } + return array; + }; + + DayPilotCalendar.getColumn = function(cell) { + var i = 0; + while (cell.previousSibling) { + cell = cell.previousSibling; + if (cell.tagName === "TD") { + i++; + } + } + return i; + }; + + DayPilotCalendar.gUnload = function (ev) { + + if (!DayPilotCalendar.registered) { + return; + } + var r = DayPilotCalendar.registered; + + for (var i = 0; i < r.length; i++) { + var c = r[i]; + c.dispose(); + + DayPilotCalendar.unregister(c); + } + + }; + + DayPilotCalendar.gMouseUp = function (ev){ + + if (DayPilotCalendar.resizing) { + if (!DayPilotCalendar.resizingShadow) { + DayPilotCalendar.resizing.style.cursor = 'default'; + document.body.style.cursor = 'default'; + DayPilotCalendar.resizing = null; + DayPilot.Global.resizing = null; + return; + } + + var dpEvent = DayPilotCalendar.resizing.event; + var height = DayPilotCalendar.resizingShadow.clientHeight + 4; + var top = DayPilotCalendar.resizingShadow.offsetTop; + var border = DayPilotCalendar.resizing.dpBorder; + + // stop resizing on the client + DayPilotCalendar.deleteShadow(DayPilotCalendar.resizingShadow); + DayPilotCalendar.resizingShadow = null; + DayPilotCalendar.resizing.style.cursor = 'default'; + dpEvent.calendar.nav.top.style.cursor = 'auto'; + //document.body.style.cursor = 'default'; + DayPilotCalendar.resizing.onclick = null; // will be re-created anyway + + DayPilotCalendar.resizing = null; + DayPilot.Global.resizing = null; + + dpEvent.calendar._eventResizeDispatch(dpEvent, height, top, border); + } + else if (DayPilotCalendar.moving) { + if (!DayPilotCalendar.movingShadow) { + DayPilotCalendar.moving = null; + DayPilot.Global.moving = null; + document.body.style.cursor = 'default'; + return; + } + + var top = DayPilotCalendar.movingShadow.offsetTop; + var dpEvent = DayPilotCalendar.moving.event; + + DayPilotCalendar.deleteShadow(DayPilotCalendar.movingShadow); + DayPilot.Util.removeClass(DayPilotCalendar.moving, dpEvent.calendar._prefixCssClass("_event_moving_source")); + + var newColumnIndex = DayPilotCalendar.movingShadow.column; + + // stop moving on the client + DayPilotCalendar.moving = null; + DayPilot.Global.moving = null; + DayPilotCalendar.movingShadow = null; + //document.body.style.cursor = 'default'; + dpEvent.calendar.nav.top.style.cursor = 'auto'; + + dpEvent.calendar._eventMoveDispatch(dpEvent, newColumnIndex, top, ev); + } + else if (DayPilotCalendar.selecting && DayPilotCalendar.topSelectedCell !== null) { + var calendar = DayPilotCalendar.selecting.calendar; + DayPilotCalendar.selecting = false; + + var sel = calendar.getSelection(); + + calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource); + if (calendar.timeRangeSelectedHandling !== "Hold" && calendar.timeRangeSelectedHandling !== "HoldForever") { + doNothing(); + } + } + else { + DayPilotCalendar.selecting = false; + } + + + }; + + DayPilotCalendar.deleteShadow = function(shadow) { + if (!shadow) { + return; + } + if (!shadow.parentNode) { + return; + } + + shadow.parentNode.removeChild(shadow); + }; + + DayPilotCalendar.moveShadow = function(column) { + var shadow = DayPilotCalendar.movingShadow; + var parent = shadow.parentNode; + + parent.style.display = 'none'; + + shadow.parentNode.removeChild(shadow); + column.firstChild.appendChild(shadow); + shadow.style.left = '0px'; + + parent.style.display = ''; + + shadow.style.width = (DayPilotCalendar.movingShadow.parentNode.offsetWidth + 1) + 'px'; + }; + + DayPilotCalendar.Calendar = function(id, options) { + + var isConstructor = false; + if (this instanceof DayPilotCalendar.Calendar && !this.__constructor) { + isConstructor = true; + this.__constructor = true; + } + + if (!isConstructor) { + throw "DayPilot.Calendar() is a constructor and must be called as 'var c = new DayPilot.Calendar(id);'"; + } + + var calendar = this; + this.uniqueID = null; + this.isCalendar = true; + + this.v = '2024.3.539-lite'; + this.id = id; + this.clientName = id; + + this.cache = {}; + this.cache.pixels = {}; + + this.elements = {}; + this.elements.events = []; + this.elements.selection = []; + + this.nav = {}; + + this.afterRender = function() {}; + + this.fasterDispose = true; + + this.angularAutoApply = false; + this.api = 2; + this.businessBeginsHour = 9; + this.businessEndsHour = 18; + this.cellHeight = 30; + this.columnMarginRight = 5; + this.columnsLoadMethod = "GET"; + this.contextMenu = null; + this.days = 1; + this.durationBarVisible = true; + this.eventsLoadMethod = "GET"; + this.headerDateFormat = null; // uses locale.dateFormat by default + this.headerHeight = 30; + this.headerTextWrappingEnabled = false; + this.height = 300; + this.heightSpec = 'BusinessHours'; + this.hideUntilInit = true; + this.hourWidth = 60; + this.initScrollPos = 'Auto'; + this.loadingLabelHtml = null; + this.loadingLabelText = "Loading..."; + this.loadingLabelVisible = true; + this.locale = "en-us"; + this.showToolTip = true; + this.startDate = new DayPilot.Date().getDatePart(); + this.cssClassPrefix = "calendar_default"; + this.theme = null; + this.timeFormat = 'Auto'; + this.viewType = "Days"; + this.visible = true; + this.xssProtection = "Enabled"; + + this.headerClickHandling = "Enabled"; + this.eventClickHandling = 'Enabled'; + this.eventResizeHandling = 'Update'; + this.eventRightClickHandling = 'ContextMenu'; + this.eventMoveHandling = 'Update'; + this.eventDeleteHandling = "Disabled"; + this.timeRangeSelectedHandling = 'Enabled'; + + this.onBeforeCellRender = null; + this.onBeforeEventRender = null; + + this.onEventClick = null; + this.onEventClicked = null; + this.onEventDelete = null; + this.onEventDeleted = null; + this.onEventMove = null; + this.onEventMoved = null; + this.onEventResize = null; + this.onEventResized = null; + this.onEventRightClick = null; + this.onEventRightClicked = null; + this.onHeaderClick = null; + this.onHeaderClicked = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + + this._disposed = false; + + this.clearSelection = function() { + DayPilotCalendar.topSelectedCell = null; + DayPilotCalendar.bottomSelectedCell = null; + this._hideSelection(); + }; + + this._hideSelection = function() { + DayPilot.de(calendar.elements.selection); + calendar.elements.selection = []; + calendar.nav.activeSelection = null; + }; + + this.cleanSelection = this.clearSelection; + + this._postBack2 = function(action, data, parameters) { + var envelope = {}; + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); + __doPostBack(calendar.uniqueID, commandstring); + }; + + this._callBack2 = function(action, data, parameters) { + + if (this.callbackTimeout) { + window.clearTimeout(this.callbackTimeout); + } + + this.callbackTimeout = window.setTimeout(function() { + calendar.loadingStart(); + }, 100); + + var envelope = {}; + + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); + if (this.backendUrl) { + DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this.ajaxError); + } + else if (typeof WebForm_DoCallback === 'function') { + WebForm_DoCallback(this.uniqueID, commandstring, this._updateView, this.clientName, this.onCallbackError, true); + } + }; + + this.onCallbackError = function(result, context) { + alert("Error!\r\nResult: " + result + "\r\nContext:" + context); + }; + + this.dispose = function() { + + + var c = calendar; + + if (c._disposed) { + return; + } + c._disposed = true; + + clearInterval(c._visibilityInterval); + + c._deleteEvents(); + c.nav.scroll.root = null; + + DayPilot.pu(c.nav.loading); + + c._disposeMain(); + c._disposeHeader(); + + c.nav.select = null; + c.nav.cornerRight = null; + c.nav.scrollable = null; + c.nav.zoom = null; + c.nav.loading = null; + c.nav.header = null; + c.nav.hourTable = null; + c.nav.scrolltop = null; + c.nav.scroll.onscroll = null; + c.nav.scroll = null; + c.nav.main = null; + c.nav.message = null; + c.nav.messageClose = null; + c.nav.top = null; + + DayPilotCalendar.unregister(c); + }; + + this.disposed = function() { + return this._disposed; + }; + + this._registerDispose = function() { + this.nav.top.dispose = this.dispose; + }; + + this._callBackResponse = function(response) { + calendar._updateView(response.responseText); + }; + + this._getCallBackHeader = function() { + var h = {}; + + h.control = "dpc"; + h.id = this.id; + h.v = this.v; + + h.days = calendar.days; + h.startDate = calendar.startDate; + h.heightSpec = calendar.heightSpec; + h.businessBeginsHour = calendar.businessBeginsHour; + h.businessEndsHour = calendar.businessEndsHour; + h.hashes = calendar.hashes; + + // h.backColor = calendar.cellBackColor; + h.timeFormat = calendar.timeFormat; + h.viewType = calendar.viewType; + h.locale = calendar.locale; + + return h; + }; + + this._createShadow = function(object, copyText) { + var parentTd = object.parentNode; + while (parentTd && parentTd.tagName !== "TD") { + parentTd = parentTd.parentNode; + } + + var shadow = document.createElement('div'); + shadow.setAttribute('unselectable', 'on'); + shadow.style.position = 'absolute'; + shadow.style.width = (object.offsetWidth) + 'px'; + shadow.style.height = (object.offsetHeight) + 'px'; + shadow.style.left = (object.offsetLeft) + 'px'; + shadow.style.top = (object.offsetTop) + 'px'; + shadow.style.boxSizing = "border-box"; + shadow.style.zIndex = 101; + + // shadow.style.backgroundColor = "#aaaaaa"; + // shadow.style.opacity = 0.5; + // shadow.style.filter = "alpha(opacity=50)"; + // shadow.style.border = '2px solid #aaaaaa'; + + shadow.className = calendar._prefixCssClass("_shadow"); + + var inner = document.createElement("div"); + inner.className = calendar._prefixCssClass("_shadow_inner"); + shadow.appendChild(inner); + + if (copyText && false) { // disabled + shadow.style.overflow = 'hidden'; + shadow.style.fontSize = object.style.fontSize; + shadow.style.fontFamily = object.style.fontFamily; + shadow.style.color = object.style.color; + shadow.innerHTML = object.data.client.html(); + } + + /* + shadow.style.MozBorderRadius = "5px"; + shadow.style.webkitBorderRadius = "5px"; + shadow.style.borderRadius = "5px"; + */ + + parentTd.firstChild.appendChild(shadow); + + return shadow; + }; + + + this._resolved = {}; + this._resolved.locale = function() { + var found = DayPilot.Locale.find(calendar.locale); + if (!found) { + return DayPilot.Locale.US; + } + return found; + }; + + this._resolved.timeFormat = function() { + if (calendar.timeFormat !== 'Auto') { + return calendar.timeFormat; + } + return this.locale().timeFormat; + }; + + this._resolved._xssProtectionEnabled = function() { + return calendar.xssProtection !== "Disabled"; + }; + + this._resolved._weekStarts = function() { + if (calendar.weekStarts === 'Auto') { + var locale = resolved.locale(); + if (locale) { + return locale.weekStarts; + } + else { + return 0; // Sunday + } + } + else { + return calendar.weekStarts || 0; + } + }; + + var resolved = this._resolved; + + this._updateView = function(result, context) { + + if (result && result.indexOf("$$$") === 0) { + if (window.console) { + console.log("Error received from the server side: " + result); + } + else { + throw "Error received from the server side: " + result; + } + return; + } + + var result = JSON.parse(result); + + if (result.CallBackRedirect) { + document.location.href = result.CallBackRedirect; + return; + } + + if (result.UpdateType === "None") { + calendar.loadingStop(); + calendar._show(); + return; + } + + calendar._deleteEvents(); + + if (result.UpdateType === "Full") { + + calendar.columns = result.Columns; + + // properties + calendar.days = result.Days; + calendar.startDate = new DayPilot.Date(result.StartDate); + calendar.heightSpec = result.HeightSpec ? result.HeightSpec : calendar.heightSpec; + calendar.businessBeginsHour = result.BusinessBeginsHour ? result.BusinessBeginsHour : calendar.businessBeginsHour; + calendar.businessEndsHour = result.BusinessEndsHour ? result.BusinessEndsHour : calendar.businessEndsHour; + calendar.headerDateFormat = result.HeaderDateFormat ? result.HeaderDateFormat : calendar.headerDateFormat; + calendar.viewType = result.ViewType; // + calendar.backColor = result.BackColor ? result.BackColor : calendar.backColor; + calendar.eventHeaderVisible = result.EventHeaderVisible ? result.EventHeaderVisible : calendar.eventHeaderVisible; + calendar.timeFormat = result.TimeFormat ? result.TimeFormat : calendar.timeFormat; + calendar.locale = result.Locale ? result.Locale : calendar.locale; + + calendar._prepareColumns(); + } + + // hashes + if (result.Hashes) { + for (var key in result.Hashes) { + calendar.hashes[key] = result.Hashes[key]; + } + } + + calendar.events.list = result.Events; + calendar._loadEvents(); + calendar._updateHeaderHeight(); + + if (result.UpdateType === "Full") { + calendar._drawHeader(); + calendar._drawMain(); + calendar._drawHourTable(); + calendar._updateHeight(); + } + + calendar._show(); + + calendar._drawEvents(); + calendar.clearSelection(); + + calendar.afterRender(result.CallBackData, true); + + calendar.loadingStop(); + + }; + + this._durationHours = function() { + return this._duration() / (3600 * 1000); + }; + + this._businessHoursSpan = function() { + if (this.businessBeginsHour > this.businessEndsHour) { + return 24 - this.businessBeginsHour + this.businessEndsHour; + } + else { + return this.businessEndsHour - this.businessBeginsHour; + } + }; + + this._rowCount = function() { + return this._duration() / (60 * 60 * 1000 / 2); + }; + + // in ticks + this._duration = function() { + var dHours = 0; + + if (this.heightSpec === 'BusinessHoursNoScroll') { + dHours = this._businessHoursSpan(); + } + else { + dHours = 24; + } + return dHours * 60 * 60 * 1000; // return ticks + }; + + this._visibleStart = function() { + if (this.heightSpec === 'BusinessHoursNoScroll') { + return this.businessBeginsHour; + } + return 0; + }; + + + + this._api2 = function() { + return calendar.api === 2; + }; + + this.eventClickCallBack = function(e, data) { + this._callBack2('EventClick', data, e); + }; + + this.eventClickPostBack = function(e, data) { + this._postBack2('EventClick', data, e); + }; + + this._eventClickDispatch = function (ev) { + var thisDiv = this; + + var e = thisDiv.event; + + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.originalEvent = ev; + args.meta = ev.metaKey; + args.ctrl = ev.ctrlKey; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventClick === 'function') { + calendar._angular.apply(function() { + calendar.onEventClick(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventClickHandling) { + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'PostBack': + calendar.eventClickPostBack(e); + break; + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(e); + } + } + break; + } + + if (typeof calendar.onEventClicked === 'function') { + calendar._angular.apply(function() { + calendar.onEventClicked(args); + }); + } + } + else { + switch (calendar.eventClickHandling) { + case 'PostBack': + calendar.eventClickPostBack(e); + break; + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'JavaScript': + calendar.onEventClick(e); + break; + } + } + + }; + + this._eventRightClickDispatch = function(ev) { + + var e = this.event; + + if (ev.stopPropagation) { + ev.stopPropagation(); + } + + if (!e.client.rightClickEnabled()) { + return false; + } + + var args = {}; + args.e = e; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventRightClick === 'function') { + calendar.onEventRightClick(args); + if (args.preventDefault.value) { + return false; + } + } + + switch (calendar.eventRightClickHandling) { + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(this.event); + } + } + break; + } + + if (typeof calendar.onEventRightClicked === 'function') { + calendar.onEventRightClicked(args); + } + + + if (ev.preventDefault) { + ev.preventDefault(); + } + return false; + }; + + + this.eventDeleteCallBack = function(e, data) { + this._callBack2('EventDelete', data, e); + }; + + this.eventDeletePostBack = function(e, data) { + this._postBack2('EventDelete', data, e); + }; + + this._eventDeleteDispatch = function (e) { + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventDelete === 'function') { + calendar._angular.apply(function() { + calendar.onEventDelete(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventDeleteHandling) { + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'Update': + calendar.events.remove(e); + break; + } + + if (typeof calendar.onEventDeleted === 'function') { + calendar._angular.apply(function() { + calendar.onEventDeleted(args); + }); + } + } + else { + switch (calendar.eventDeleteHandling) { + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'JavaScript': + calendar.onEventDelete(e); + break; + } + } + + }; + + this.eventResizeCallBack = function(e, newStart, newEnd, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._callBack2('EventResize', data, params); + }; + + this.eventResizePostBack = function(e, newStart, newEnd, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._postBack2('EventResize', data, params); + }; + + this._eventResizeDispatch = function (e, shadowHeight, shadowTop, border ) { + var _startOffset = 1; + + var newStart = new Date(); + var newEnd = new Date(); + + var start = e.start(); + var end = e.end(); + + if (border === 'top') { + var day = start.getDatePart(); + var step = Math.floor((shadowTop - _startOffset) / calendar.cellHeight); + var minutes = step * 30; + var ts = minutes * 60 * 1000; + var visibleStartOffset = calendar._visibleStart() * 60 * 60 * 1000; + + newStart = day.addTime(ts + visibleStartOffset); + newEnd = e.end(); + + } + else if (border === 'bottom') { + var day = end.getDatePart(); + var step = Math.floor((shadowTop + shadowHeight - _startOffset) / calendar.cellHeight); + var minutes = step * 30; + var ts = minutes * 60 * 1000; + var visibleStartOffset = calendar._visibleStart() * 60 * 60 * 1000; + + newStart = start; + newEnd = day.addTime(ts + visibleStartOffset); + } + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.control = calendar; + args.newStart = newStart; + args.newEnd = newEnd; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventResize === 'function') { + calendar._angular.apply(function() { + calendar.onEventResize(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventResizeHandling) { + case 'PostBack': + calendar.eventResizePostBack(e, newStart, newEnd); + break; + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventResized === 'function') { + calendar._angular.apply(function() { + calendar.onEventResized(args); + }); + } + } + else { + switch (calendar.eventResizeHandling) { + case 'PostBack': + calendar.eventResizePostBack(e, newStart, newEnd); + break; + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'JavaScript': + calendar.onEventResize(e, newStart, newEnd); + break; + } + } + }; + + this.eventMovePostBack = function(e, newStart, newEnd, newResource, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._postBack2('EventMove', data, params); + }; + + this.eventMoveCallBack = function(e, newStart, newEnd, newResource, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._callBack2('EventMove', data, params); + }; + + this._eventMoveDispatch = function (e, newColumnIndex, shadowTop, ev) { + var _startOffset = 1; + var step = Math.floor((shadowTop - _startOffset) / calendar.cellHeight); + + var boxStart = step * 30 * 60 * 1000; + var start = e.start(); + var end = e.end(); + var day = new Date(); + + if (start instanceof DayPilot.Date) { + start = start.toDate(); + } + day.setTime(Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate())); + + var startOffset = start.getTime() - (day.getTime() + start.getUTCHours() * 3600 *1000 + Math.floor(start.getUTCMinutes()/30)*30*60*1000 ); + var length = end.getTime() - start.getTime(); + + var newColumn = this._columns[newColumnIndex]; + var newResource = newColumn.id; + + var date = newColumn.start.getTime(); + var newStartUTC = new Date(); + newStartUTC.setTime(date + boxStart + startOffset); + + var newStart = new DayPilot.Date(newStartUTC); + + var newEnd = newStart.addTime(length); + + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.newStart = newStart; + args.newEnd = newEnd; + args.newResource = newResource; + args.ctrl = ev.ctrlKey; + args.shift = ev.shiftKey; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventMove === 'function') { + calendar._angular.apply(function() { + calendar.onEventMove(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventMoveHandling) { + case 'PostBack': + calendar.eventMovePostBack(e, newStart, newEnd, newColumn.id); + break; + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd, newColumn.id); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + e.resource(newResource); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventMoved === 'function') { + calendar._angular.apply(function() { + calendar.onEventMoved(args); + }); + } + } + else { + switch (calendar.eventMoveHandling) { + case 'PostBack': + calendar.eventMovePostBack(e, newStart, newEnd, newColumn.id); + break; + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd, newColumn.id); + break; + case 'JavaScript': + calendar.onEventMove(e, newStart, newEnd, newColumn.id, false); + break; + } + } + + }; + + this.timeRangeSelectedPostBack = function(start, end, resource, data) { + + var range = {}; + range.start = start; + range.end = end; + + this._postBack2('TimeRangeSelected', data, range); + }; + + this.timeRangeSelectedCallBack = function(start, end, resource, data) { + + var range = {}; + range.start = start; + range.end = end; + + this._callBack2('TimeRangeSelected', data, range); + }; + + this._timeRangeSelectedDispatch = function (start, end, resource) { + + // make sure it's DayPilot.Date + start = new DayPilot.Date(start); + end = new DayPilot.Date(end); + + if (this._api2()) { + var args = {}; + args.start = start; + args.end = end; + args.resource = resource; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onTimeRangeSelect === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelect(args); + }); + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (calendar.timeRangeSelectedHandling) { + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end); + break; + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + } + + if (typeof calendar.onTimeRangeSelected === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelected(args); + }); + } + } + else { + switch (calendar.timeRangeSelectedHandling) { + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end); + break; + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + case 'JavaScript': + calendar.onTimeRangeSelected(start, end); + break; + } + } + }; + + this._onCellMousedown = function(ev) { + + if (DayPilotCalendar.selecting) { + return; + } + + if (calendar.timeRangeSelectedHandling === "Disabled") { + return; + } + + var button = ev.which; + if (button !== 1 && button !== 0) { // Khtml says first button is 0 + return; + } + + DayPilotCalendar.firstMousePos = DayPilot.mc(ev); + DayPilotCalendar.selecting = {}; + DayPilotCalendar.selecting.calendar = calendar; + if (DayPilotCalendar.selectedCells) { + calendar.clearSelection(); + DayPilotCalendar.selectedCells = []; + } + DayPilotCalendar.column = DayPilotCalendar.getColumn(this); + DayPilotCalendar.selectedCells.push(this); + DayPilotCalendar.firstSelected = this; + + DayPilotCalendar.topSelectedCell = this; + DayPilotCalendar.bottomSelectedCell = this; + + calendar._activateSelection(); + + return false; + }; + + this._activateSelection = function() { + var selection = this.getSelection(); + + (function activateSelectionNew() { + + var first = DayPilotCalendar.topSelectedCell; + var last = DayPilotCalendar.bottomSelectedCell; + + // var columnIndex = first.parentNode.cells.indexOf(first); + + var columnIndex = (function() { + // it's the new div cell + if (first.data) { + return first.data.x; + } + + var cells = first.parentNode.cells; + for (var i = 0; i < cells.length; i++) { + if (cells[i] === first) { + return i; + } + } + return -1; + })(); + + var col = calendar._columns[columnIndex]; + + if (!col) { + return; + } + + var colStart = col.start; + + var top = calendar.getPixels(first.start, colStart).boxTop; + var bottom = calendar.getPixels(last.end, colStart).boxBottom; + var height = bottom - top; + + var div = (function() { + if (calendar.nav.activeSelection) { + return calendar.nav.activeSelection; + } + var div = document.createElement("div"); + div.setAttribute("unselectable", "on"); + // div.style.zIndex = calendar._shadowZindex; + div.style.position = "absolute"; + div.style.left = "0px"; + div.style.width = "100%"; + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = calendar._prefixCssClass("_shadow_inner"); + + div.appendChild(inner); + + calendar.nav.events.rows[0].cells[columnIndex].selection.appendChild(div); + calendar.elements.selection.push(div); + calendar.nav.activeSelection = div; + + return div; + })(); + + // reset + div.className = calendar._prefixCssClass("_shadow"); + div.firstChild.innerHTML = ""; + + // position + div.style.top = top + "px"; + div.style.height = height + "px"; + + })(); + }; + + this._mousemove = function(ev) { + + if (typeof (DayPilotCalendar) === 'undefined') { + return; + } + + if (!DayPilotCalendar.selecting) { + return; + } + + var mousePos = DayPilot.mc(ev); + + var thisColumn = DayPilotCalendar.getColumn(this); + if (thisColumn !== DayPilotCalendar.column) { + return; + } + + // clean + calendar.clearSelection(); + + // new selected cells + if (mousePos.y < DayPilotCalendar.firstMousePos.y) { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsBelow(this); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.selectedCells[0]; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.firstSelected; + } + else { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsAbove(this); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.firstSelected; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.selectedCells[0]; + } + + calendar._activateSelection(); + }; + + this.getSelection = function() { + var start = DayPilotCalendar.topSelectedCell.start; + var end = DayPilotCalendar.bottomSelectedCell.end; + var resource = DayPilotCalendar.topSelectedCell.resource; + + return new DayPilot.Selection(start, end, resource, calendar); + }; + + this._getColumnForPixels = function(x) { + + if (x < 0) { + return null; + } + + var i = 0; + var cells = calendar.nav.events.rows[0].cells; + + for (var j = 0; j < cells.length; j++) { + var cell = cells[j]; + var width = cell.offsetWidth; + i += width; + if (x < i) { + return j; + } + } + return null; + }; + + this._table = {}; + this._table.getCellCoords = function() { + var result = {}; + result.x = 0; + result.y = 0; + + if (!calendar.coords) { + return null; + } + + result.x = calendar._getColumnForPixels(calendar.coords.x); + + var _startOffset = 0; + var row = Math.floor((calendar.coords.y - _startOffset) / calendar.cellHeight); + result.y = row; + + if (result.x < 0) { + return null; + } + + return result; + }; + + this.columns = {}; + this.columns.list = []; + + this.columns.load = function(url, success, error) { + + if (!url) { + throw new DayPilot.Exception("columns.load(): 'url' parameter required"); + } + + var onError = function(args) { + var largs = {}; + largs.exception = args.exception; + largs.request = args.request; + + if (typeof error === 'function') { + error(largs); + } + }; + + var onSuccess = function(args) { + var r = args.request; + var data; + + // it's supposed to be JSON + try { + data = JSON.parse(r.responseText); + } + catch (e) { + var fargs = {}; + fargs.exception = e; + onError(fargs); + return; + } + + if (DayPilot.isArray(data)) { + var sargs = {}; + sargs.preventDefault = function() { + this.preventDefault.value = true; + }; + sargs.data = data; + if (typeof success === "function") { + success(sargs); + } + + if (sargs.preventDefault.value) { + return; + } + + calendar.columns.list = data; + if (calendar._initialized) { + calendar.update(); + } + } + }; + + var usePost = calendar.columnsLoadMethod && calendar.columnsLoadMethod.toUpperCase() === "POST"; + + if (usePost) { + DayPilot.ajax({ + "method": "POST", + "url": url, + "success": onSuccess, + "error": onError + }); + } + else { + DayPilot.ajax({ + "method": "GET", + "url": url, + "success": onSuccess, + "error": onError + }); + } + }; + + + this._prepareColumns = function() { + var columns; + if (calendar.viewType !== "Resources") { + columns = this._createDaysViewColumns(); + } + else { + columns = calendar.columns.list; + } + + this._columns = []; + for (var i = 0; i < columns.length; i++) { + var c = this._activateColumn(columns[i]); + this._columns.push(c); + } + }; + + this._activateColumn = function(column) { + +/* + if (column.Start) { + column.start = column.Start; + column.html = column.InnerHTML; + column.name = column.Name; + } +*/ + var result = {}; + result.name = column.name; + result.html = column.html; + result.id = column.id; + result.toolTip = column.toolTip; + result.data = column; + + if (column.start) { + result.start = new DayPilot.Date(column.start); + } + else { + result.start = new DayPilot.Date(calendar.startDate); + } + + result.putIntoBlock = function(ep) { + + for (var i = 0; i < this.blocks.length; i++) { + var block = this.blocks[i]; + if (block.overlapsWith(ep.part.top, ep.part.height)) { + block.events.push(ep); + block.min = Math.min(block.min, ep.part.top); + block.max = Math.max(block.max, ep.part.top + ep.part.height); + return i; + } + } + + // no suitable block found, create a new one + var block = []; + block.lines = []; + block.events = []; + + block.overlapsWith = function(start, width) { + var end = start + width - 1; + + if (!(end < this.min || start > this.max - 1)) { + return true; + } + + return false; + }; + block.putIntoLine = function (ep) { + var thisCol = this; + + for (var i = 0; i < this.lines.length; i++) { + var line = this.lines[i]; + if (line.isFree(ep.part.top, ep.part.height)) { + line.push(ep); + return i; + } + } + + var line = []; + line.isFree = function(start, width) { + var end = start + width - 1; + var max = this.length; + + for (var i = 0; i < max; i++) { + var e = this[i]; + if (!(end < e.part.top || start > e.part.top + e.part.height - 1)) { + return false; + } + } + + return true; + }; + + line.push(ep); + + this.lines.push(line); + + return this.lines.length - 1; + + }; + + block.events.push(ep); + block.min = ep.part.top; + block.max = ep.part.top + ep.part.height; + + this.blocks.push(block); + + return this.blocks.length - 1; + + }; + + result.putIntoLine = function(ep) { + var thisCol = this; + + for (var i = 0; i < this.lines.length; i++) { + var line = this.lines[i]; + if (line.isFree(ep.part.top, ep.part.height)) { + line.push(ep); + return i; + } + } + + var line = []; + line.isFree = function(start, width) { + var end = start + width - 1; + var max = this.length; + + for (var i = 0; i < max; i++) { + var e = this[i]; + if (!(end < e.part.top || start > e.part.top + e.part.height - 1)) { + return false; + } + } + + return true; + }; + + line.push(ep); + + this.lines.push(line); + + return this.lines.length - 1; + }; + + return result; + + }; + + this._createDaysViewColumns = function() { + var columns = []; + + var start = this.startDate.getDatePart(); + + var days = this.days; + switch (this.viewType) { + case "Day": + days = 1; + break; + case "Week": + days = 7; + var weekStarts = resolved._weekStarts(); + start = start.firstDayOfWeek(weekStarts); + break; + case "WorkWeek": + days = 5; + start = start.firstDayOfWeek(1); // Monday + break; + } + + if (this.heightSpec === 'BusinessHoursNoScroll') { + start = start.addHours(this.businessBeginsHour); + } + + for (var i = 0; i < days; i++) { + + var format = calendar.headerDateFormat ? calendar.headerDateFormat : resolved.locale().datePattern; + + var column = {}; + column.start = start.addDays(i); + column.name = column.start.toString(format, resolved.locale()); + + columns.push(column); + } + + return columns; + }; + + this.visibleStart = function() { + if (calendar.viewType === "Resources") { + if (calendar._columns.length === 0) { + return DayPilot.Date.today(); + } + var dates = calendar._columns.map(function(column) { + return column.start.getTime(); + }); + var min = Math.min.apply(null, dates); + return new DayPilot.Date(min); + } + return this._columns[0].start; + }; + + this.visibleEnd = function() { + if (calendar.viewType === "Resources") { + if (calendar._columns.length === 0) { + return DayPilot.Date.today().addDays(1); + } + var dates = calendar._columns.map(function(column) { + return column.start.getTime(); + }); + var max = Math.max.apply(null, dates); + return new DayPilot.Date(max).addDays(1); + } + var max = this._columns.length - 1; + return this._columns[max].start.addDays(1); + }; + + + this._prefixCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + if (prefix) { + return prefix + part; + } + else { + return ""; + } + }; + + this._deleteEvents = function() { + + if (this.elements.events) { + + for (var i = 0; i < this.elements.events.length; i++) { + var div = this.elements.events[i]; + + var object = div.event; + if (object) { + object.calendar = null; + } + + div.onclick = null; + div.onclickSave = null; + div.onmouseover = null; + div.onmouseout = null; + div.onmousemove = null; + div.onmousedown = null; + + if (div.firstChild && div.firstChild.firstChild && div.firstChild.firstChild.tagName && div.firstChild.firstChild.tagName.toUpperCase() === 'IMG') { + var img = div.firstChild.firstChild; + img.onmousedown = null; + img.onmousemove = null; + img.onclick = null; + + } + + div.helper = null; + div.data = null; + div.event = null; + + DayPilot.de(div); + } + } + this.elements.events = []; + }; + + this._drawEvent = function(e) { + /* + + supported e.data properties: + * text + * html + * cssClass + * backColor + * barColor + * barBackColor + * toolTip + * barHidden + * borderColor + * fontColor + + */ + + + var data = e.cache || e.data; + + var main = this.nav.events; + + var rounded = true; + var radius = true; + var pixels = false; + + // var borderColor = this.eventBorderColor; + + var div = document.createElement("div"); + div.style.position = 'absolute'; + div.style.left = e.part.left + '%'; + div.style.top = (e.part.top) + 'px'; + div.style.width = e.part.width + '%'; + div.style.height = Math.max(e.part.height, 2) + 'px'; + div.style.overflow = 'hidden'; + + // TODO unify + div.data = e; + div.event = e; + + div.unselectable = 'on'; + div.style.MozUserSelect = 'none'; + div.style.KhtmlUserSelect = 'none'; + + div.className = this._prefixCssClass("_event"); + + if (data.cssClass) { + DayPilot.Util.addClass(div, data.cssClass); + } + + if (calendar.showToolTip && e.client.toolTip()) { + div.title = e.client.toolTip(); + } + + div.isFirst = e.part.start.getTime() === e.start().getTime(); + div.isLast = e.part.end.getTime() === e.end().getTime(); + + div.onclick = this._eventClickDispatch; + DayPilot.re(div, "contextmenu", this._eventRightClickDispatch); + + div.onmouseout = function(ev) { + if (div.deleteIcon) { + div.deleteIcon.style.display = "none"; + } + }; + + div.onmousemove = function (ev) { + // const + var resizeMargin = 5; + + if (typeof(DayPilotCalendar) === 'undefined') { + return; + } + + // position + var offset = DayPilot.mo3(div, ev); + if (!offset) { + return; + } + + if (DayPilotCalendar.resizing || DayPilotCalendar.moving) { + return; + } + + if (div.deleteIcon) { + div.deleteIcon.style.display = ""; + } + + var isLastPart = this.isLast; + + if (offset.y <= resizeMargin && e.client.resizeEnabled()) { + this.style.cursor = "n-resize"; + this.dpBorder = 'top'; + } + else if (this.offsetHeight - offset.y <= resizeMargin && e.client.resizeEnabled()) { + if (isLastPart) { + this.style.cursor = "s-resize"; + this.dpBorder = 'bottom'; + } + else { + this.style.cursor = 'not-allowed'; + } + } + else if (!DayPilotCalendar.resizing && !DayPilotCalendar.moving) { + if (calendar.eventClickHandling !== 'Disabled') { + this.style.cursor = 'pointer'; + } + else { + this.style.cursor = 'default'; + } + } + + }; + + div.onmousedown = function (ev) { + var button = ev.which || ev.button; + + if ((this.style.cursor === 'n-resize' || this.style.cursor === 's-resize') && button === 1) { + // set + DayPilotCalendar.resizing = this; + DayPilot.Global.resizing = this; + DayPilotCalendar.originalMouse = DayPilot.mc(ev); + DayPilotCalendar.originalHeight = this.offsetHeight; + DayPilotCalendar.originalTop = this.offsetTop; + + calendar.nav.top.style.cursor = this.style.cursor; + + } + else if (button === 1 && e.client.moveEnabled()) { + DayPilotCalendar.moving = this; + DayPilot.Global.moving = this; + DayPilotCalendar.moving.event = this.event; + var helper = DayPilotCalendar.moving.helper = {}; + helper.oldColumn = calendar._columns[this.data.part.dayIndex].id; + DayPilotCalendar.originalMouse = DayPilot.mc(ev); + DayPilotCalendar.originalTop = this.offsetTop; + + var offset = DayPilot.mo3(this, ev); + if (offset) { + DayPilotCalendar.moveOffsetY = offset.y; + } + else { + DayPilotCalendar.moveOffsetY = 0; + } + + // cursor + //document.body.style.cursor = 'move'; + calendar.nav.top.style.cursor = 'move'; + } + + return false; + }; + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = calendar._prefixCssClass("_event_inner"); + inner.innerHTML = e.client.html(); + + if (data.borderColor === "darker" && data.backColor) { + inner.style.borderColor = DayPilot.ColorUtil.darker(data.backColor, 2); + } + else { + inner.style.borderColor = data.borderColor; + } + + if (data.backColor) { + inner.style.background = data.backColor; + } + + if (data.fontColor) { + inner.style.color = data.fontColor; + } + + div.appendChild(inner); + + // TODO + if (e.client.barVisible()) { + var height = e.part.height - 2; + var barTop = 100 * e.part.barTop / height; // % + var barHeight = Math.ceil(100 * e.part.barHeight / height); // % + + var bar = document.createElement("div"); + bar.setAttribute("unselectable", "on"); + bar.className = this._prefixCssClass("_event_bar"); + bar.style.position = "absolute"; + + if (data.barBackColor) { + bar.style.backgroundColor = data.barBackColor; + } + + var barInner = document.createElement("div"); + barInner.setAttribute("unselectable", "on"); + barInner.className = this._prefixCssClass("_event_bar_inner"); + barInner.style.top = barTop + "%"; + if (0 < barHeight && barHeight <= 1) { + barInner.style.height = "1px"; + } + else { + barInner.style.height = barHeight + "%"; + } + + if (data.barColor) { + barInner.style.backgroundColor = data.barColor; + } + + bar.appendChild(barInner); + div.appendChild(bar); + } + + if (e.client.deleteEnabled()) { + var del = document.createElement("div"); + del.style.position = "absolute"; + del.style.right = "2px"; + del.style.top = "2px"; + del.style.width = "17px"; + del.style.height = "17px"; + del.className = calendar._prefixCssClass("_event_delete"); + del.onmousedown = function(ev) { + ev.stopPropagation(); + }; + del.onclick = function(ev) { + ev.stopPropagation(); + var e = this.parentNode.event; + if (e) { + calendar._eventDeleteDispatch(e); + } + }; + del.style.display = "none"; + div.deleteIcon = del; + div.appendChild(del); + } + + // areas + var areas = data.areas ? DayPilot.Areas.copy(data.areas) : []; + +/* var col = calendar._columnsBottom[e.part.dayIndex]; + + areas.forEach(function(area) { + if (area.start) { + area.top = calendar._getPixels(new DayPilot.Date(area.start), col.start).top - e.part.top - calendar._autoHiddenPixels(); + } + if (area.end) { + area.bottom = e.part.top + e.part.height - calendar._getPixels(new DayPilot.Date(area.end), col.start).top - calendar._autoHiddenPixels(); + } + }); + + if (e.client.deleteEnabled()) { + areas.push({"action":"JavaScript","v":"Hover","w":17,"h":17,"top":2,"right":2, "css": calendar._prefixCssClass("_event_delete"),"js":function(e) { calendar._eventDeleteDispatch(e); } }); + }*/ + + DayPilot.Areas.attach(div, e, {"areas": areas}); + + if (main.rows[0].cells[e.part.dayIndex]) { // temporary fix for multirow header, but won't hurt later + var wrapper = main.rows[0].cells[e.part.dayIndex].firstChild; + wrapper.appendChild(div); + + calendar._makeChildrenUnselectable(div); + + //var e = new DayPilotCalendar.Event(div, calendar); + } + + if (typeof calendar.onAfterEventRender === 'function') { + var args = {}; + args.e = div.event; + args.div = div; + + calendar.onAfterEventRender(args); + } + + calendar.elements.events.push(div); + }; + + this._makeChildrenUnselectable = function(el) { + var c = (el && el.childNodes) ? el.childNodes.length : 0; + for (var i = 0; i < c; i++) { + try { + var child = el.childNodes[i]; + if (child.nodeType === 1) { + child.unselectable = 'on'; + this._makeChildrenUnselectable(child); + } + } + catch (e) { + } + } + }; + + this._drawEvents = function() { + + //var start = new Date(); + + for (var i = 0; i < this._columns.length; i++) { + var col = this._columns[i]; + if (!col.blocks) { + continue; + } + + for (var m = 0; m < col.blocks.length; m++) { + var block = col.blocks[m]; + for (var j = 0; j < block.lines.length; j++) { + var line = block.lines[j]; + + for(var k = 0; k < line.length; k++) { + var e = line[k]; + + e.part.width = 100 / block.lines.length; + e.part.left = e.part.width * j; + + var isLastBlock = (j === block.lines.length - 1); + if (!isLastBlock) { + e.part.width = e.part.width * 1.5; + } + + this._drawEvent(e); + } + } + } + } + + //var end = new Date(); + //var diff = end.getTime() - start.getTime(); + }; + + this._drawTop = function() { + + //this.nav.top = document.getElementById(this.id); + this.nav.top.innerHTML = ''; + + DayPilot.Util.addClass(this.nav.top, this._prefixCssClass("_main")); + + this.nav.top.style.MozUserSelect = 'none'; + this.nav.top.style.KhtmlUserSelect = 'none'; + this.nav.top.style.position = 'relative'; + this.nav.top.style.width = this.width ? this.width : '100%'; + + if (this.hideUntilInit) { + this.nav.top.style.visibility = 'hidden'; + } + + if (!this.visible) { + this.nav.top.style.display = "none"; + } + + this.nav.scroll = document.createElement("div"); + this.nav.scroll.style.height = this._getScrollableHeight() + "px"; + + if (this.heightSpec === 'BusinessHours') { + this.nav.scroll.style.overflow = "auto"; + } + else + { + this.nav.scroll.style.overflow = "hidden"; + } + + this.nav.scroll.style.position = "relative"; + + var header = this._drawTopHeaderDiv(); + this.nav.top.appendChild(header); + + // fixing the column alignment bug + // solved thanks to http://stackoverflow.com/questions/139000/div-with-overflowauto-and-a-100-wide-table-problem + this.nav.scroll.style.zoom = 1; + + var wrap = this._drawScrollable(); + this.nav.scrollable = wrap.firstChild; + this.nav.scroll.appendChild(wrap); + this.nav.top.appendChild(this.nav.scroll); + + this.nav.scrollLayer = document.createElement("div"); + this.nav.scrollLayer.style.position = 'absolute'; + this.nav.scrollLayer.style.top = '0px'; + this.nav.scrollLayer.style.left = '0px'; + this.nav.top.appendChild(this.nav.scrollLayer); + + this.nav.loading = document.createElement("div"); + this.nav.loading.style.position = 'absolute'; + this.nav.loading.style.top = '0px'; + this.nav.loading.style.left = (this.hourWidth + 5) + "px"; + // this.nav.loading.style.backgroundColor = this.loadingLabelBackColor; + // this.nav.loading.style.fontSize = this.loadingLabelFontSize; + // this.nav.loading.style.fontFamily = this.loadingLabelFontFamily; + // this.nav.loading.style.color = this.loadingLabelFontColor; + // this.nav.loading.style.padding = '2px'; + this.nav.loading.innerHTML = calendar._xssTextHtml(calendar.loadingLabelText, calendar.loadingLabelHtml); + this.nav.loading.style.display = 'none'; + + this.nav.top.appendChild(this.nav.loading); + + }; + + // used during full update + this._drawHourTable = function() { + // clear old hour table + if (!this.fasterDispose) DayPilot.pu(this.nav.hourTable); + this.nav.scrollable.rows[0].cells[0].innerHTML = ''; + this.nav.hourTable = this._createHourTable(); + this.nav.scrollable.rows[0].cells[0].appendChild(this.nav.hourTable); + }; + + // used during initial load only + this._drawScrollable = function() { + var zoom = document.createElement("div"); + zoom.style.zoom = 1; + zoom.style.position = 'relative'; + // zoom.onmousemove = calendar._mousemove; + + var table = document.createElement("table"); + + table.cellSpacing = "0"; + table.cellPadding = "0"; + table.border = "0"; + table.style.border = "0px none"; + table.style.width = "100%"; + table.style.position = 'absolute'; + + var r = table.insertRow(-1); + + var c; + c = r.insertCell(-1); + c.valign = "top"; + c.style.padding = '0px'; + c.style.border = '0px none'; + + this.nav.hourTable = this._createHourTable(); + c.appendChild(this.nav.hourTable); + + c = r.insertCell(-1); + c.valign = "top"; + c.width = "100%"; + c.style.padding = '0px'; + c.style.border = '0px none'; + + var wrap = document.createElement("div"); + wrap.style.position = "relative"; + c.appendChild(wrap); + + wrap.appendChild(this._createEventsAndCells()); + wrap.appendChild(this._createEventsTable()); + + zoom.appendChild(table); + + this.nav.zoom = zoom; + + return zoom; + }; + + this._createEventsAndCells = function() { + var table = document.createElement("table"); + + table.cellPadding = "0"; + table.cellSpacing = "0"; + table.border = "0"; + table.style.width = "100%"; + table.style.border = "0px none"; + table.style.tableLayout = 'fixed'; + + this.nav.main = table; + this.nav.events = table; + + return table; + }; + + this._createEventsTable = function() { + var table = document.createElement("table"); + + //table.style.position = "absolute"; + table.style.top = "0px"; + table.cellPadding = "0"; + table.cellSpacing = "0"; + table.border = "0"; + table.style.position = "absolute"; + table.style.width = "100%"; + table.style.border = "0px none"; + table.style.tableLayout = 'fixed'; + //table.setAttribute("events", "true"); + + this.nav.events = table; + var create = true; + var columns = this._columns; + var cl = columns.length; + + var r = (create) ? table.insertRow(-1) : table.rows[0]; + + for (var j = 0; j < cl; j++) { + var c = (create) ? r.insertCell(-1) : r.cells[j]; + + if (create) { + + c.style.padding = '0px'; + c.style.border = '0px none'; + c.style.height = '0px'; + c.style.overflow = 'visible'; + if (!calendar.rtl) { + c.style.textAlign = 'left'; + } + + // withpct + //c.style.width = (100.0 / columns.length) + "%"; + + var div = document.createElement("div"); + div.style.marginRight = calendar.columnMarginRight + "px"; + div.style.position = 'relative'; + div.style.height = '1px'; + div.style.marginTop = '-1px'; + + var selection = document.createElement("div"); + c.selection = selection; + + c.appendChild(div); + c.appendChild(selection); + + } + } + + return table; + }; + + this._createHourTable = function() { + var table = document.createElement("table"); + table.cellSpacing = "0"; + table.cellPadding = "0"; + table.border = "0"; + table.style.border = '0px none'; + table.style.width = this.hourWidth + "px"; + table.oncontextmenu = function() { return false; }; + + var hours = calendar._durationHours(); + for (var i = 0; i < hours; i++) { + this._createHourRow(table, i); + } + + return table; + + }; + + this._createHourRow = function(table, i) { + var height = (this.cellHeight * 2); + + var r = table.insertRow(-1); + r.style.height = height + "px"; + + var c = r.insertCell(-1); + c.valign = "bottom"; + c.unselectable = "on"; + c.style.cursor = "default"; + c.style.padding = '0px'; + c.style.border = '0px none'; + + var frame = document.createElement("div"); + frame.style.position = "relative"; + frame.className = this._prefixCssClass("_rowheader"); + frame.style.width = this.hourWidth + "px"; + frame.style.height = (height) + "px"; + frame.style.overflow = 'hidden'; + frame.unselectable = 'on'; + + var block = document.createElement("div"); + block.className = this._prefixCssClass("_rowheader_inner"); + block.unselectable = "on"; + + var text = document.createElement("div"); + text.unselectable = "on"; + + var start = this.startDate.addHours(i).addHours(calendar._visibleStart()); + var hour = start.getHours(); + + var am = hour < 12; + var timeFormat = resolved.timeFormat(); + if (timeFormat === "Clock12Hours") { + hour = hour % 12; + if (hour === 0) { + hour = 12; + } + } + + text.innerHTML = hour; + + var span = document.createElement("span"); + span.unselectable = "on"; + span.className = this._prefixCssClass("_rowheader_minutes"); + + var sup; + if (timeFormat === "Clock12Hours") { + if (am) { + sup = "AM"; + } + else { + sup = "PM"; + } + } + else { + sup = "00"; + } + + span.innerHTML = sup; + + text.appendChild(span); + + block.appendChild(text); + + frame.appendChild(block); + + c.appendChild(frame); + }; + + this._getScrollableHeight = function() { + switch (this.heightSpec) { + case "Full": + return (24 * 2 * this.cellHeight); + case "BusinessHours": + var dHours = this._businessHoursSpan(); + return dHours * this.cellHeight * 2; + case "BusinessHoursNoScroll": + var dHours = this._businessHoursSpan(); + return dHours * this.cellHeight * 2; + default: + throw "DayPilot.Calendar: Unexpected 'heightSpec' value."; + + } + }; + + this._updateCorner = function() { + var parent = calendar.nav.corner ? calendar.nav.corner.parentNode : null; + if (!parent) { + return; + } + + parent.innerHTML = ''; + + var corner = this._drawCorner(); + parent.appendChild(corner); + calendar.nav.corner = corner; + + }; + + this._drawTopHeaderDiv = function() { + var header = document.createElement("div"); + header.style.overflow = "auto"; + + var table = document.createElement("table"); + table.cellPadding = "0"; + table.cellSpacing = "0"; + table.border = "0"; + table.style.width = "100%"; + table.style.borderCollapse = 'separate'; + table.style.border = "0px none"; + + var r = table.insertRow(-1); + + // corner + var c = r.insertCell(-1); + c.style.padding = '0px'; + c.style.border = '0px none'; + + var corner = this._drawCorner(); + c.appendChild(corner); + this.nav.corner = corner; + + // top header + c = r.insertCell(-1); + + c.style.width = "100%"; + c.valign = "top"; + c.style.position = 'relative'; // ref point + c.style.padding = '0px'; + c.style.border = '0px none'; + + this.nav.header = document.createElement("table"); + this.nav.header.cellPadding = "0"; + this.nav.header.cellSpacing = "0"; + this.nav.header.border = "0"; + this.nav.header.width = "100%"; + this.nav.header.style.tableLayout = "fixed"; + this.nav.header.oncontextmenu = function() { return false; }; + + var scrollbar = this.nav.scroll.style.overflow !== 'hidden'; + c.appendChild(this.nav.header); + + if (scrollbar) { + c = r.insertCell(-1); + c.unselectable = "on"; + + var inside = document.createElement("div"); + inside.unselectable = "on"; + inside.style.position = "relative"; + inside.style.width = "16px"; + inside.style.height = this.headerHeight + "px"; + inside.className = this._prefixCssClass("_cornerright"); + + var inner = document.createElement("div"); + inner.className = this._prefixCssClass('_cornerright_inner'); + inside.appendChild(inner); + + c.appendChild(inside); + + this.nav.cornerRight = inside; + } + + header.appendChild(table); + + return header; + + }; + + this._drawCorner = function() { + var wrap = document.createElement("div"); + wrap.style.position = 'relative'; + wrap.className = this._prefixCssClass("_corner"); + wrap.style.width = this.hourWidth + "px"; + wrap.style.height = this.headerHeight + "px"; + wrap.oncontextmenu = function() { return false; }; + + var corner = document.createElement("div"); + corner.unselectable = "on"; + corner.className = this._prefixCssClass("_corner_inner"); + + wrap.appendChild(corner); + + return wrap; + }; + + this._disposeMain = function() { + var table = this.nav.main; + table.root = null; + table.onmouseup = null; + + for (var y = 0; y < table.rows.length; y++) { + var r = table.rows[y]; + for (var x = 0; x < r.cells.length; x++) { + var c = r.cells[x]; + c.root = null; + + c.onmousedown = null; + c.onmousemove = null; + c.onmouseout = null; + c.onmouseup = null; + } + } + + if (!this.fasterDispose) DayPilot.pu(table); + }; + + // draw time cells + this._drawMain = function() { + + //DayPilotCalendar.selectedCells = []; + var cols = []; + var dates = []; + + var table = this.nav.main; + var step = 30 * 60 * 1000; + var rowCount = this._rowCount(); + + var columns = calendar._columns; + //var create = !this.tableCreated || columns.length !== table.rows[0].cells.length || rowCount !== table.rows.length; // redraw only if number of columns changes + var create = true; + + if (table) { + this._disposeMain(); + } + + while (table && table.rows && table.rows.length > 0 && create) { + if (!this.fasterDispose) { + DayPilot.pu(table.rows[0]); + } + table.deleteRow(0); + } + + this.tableCreated = true; + + var cl = columns.length; + + var events = this.nav.events; + while (events && events.rows && events.rows.length > 0 && create) { + if (!this.fasterDispose) { + DayPilot.pu(events.rows[0]); + } + events.deleteRow(0); + } + + var cl = columns.length; + + var r = (create) ? events.insertRow(-1) : events.rows[0]; + + for (var j = 0; j < cl; j++) { + var c = (create) ? r.insertCell(-1) : r.cells[j]; + + if (create) { + + c.style.padding = '0px'; + c.style.border = '0px none'; + c.style.height = '0px'; + c.style.overflow = 'visible'; + if (!calendar.rtl) { + c.style.textAlign = 'left'; + } + + // withpct + //c.style.width = (100.0 / columns.length) + "%"; + + var div = document.createElement("div"); + div.style.marginRight = calendar.columnMarginRight + "px"; + div.style.position = 'relative'; + div.style.height = '1px'; + div.style.marginTop = '-1px'; + + var selection = document.createElement("div"); + selection.style.position = "relative"; + c.selection = selection; + + c.appendChild(div); + c.appendChild(selection); + + } + } + + for (var i = 0; i < rowCount; i++) { + var r = (create) ? table.insertRow(-1) : table.rows[i]; + + if (create) { + r.style.MozUserSelect = 'none'; + r.style.KhtmlUserSelect = 'none'; + } + + for (var j = 0; j < cl; j++) { + var col = this._columns[j]; + + var c = (create) ? r.insertCell(-1) : r.cells[j]; + + // always update + c.start = col.start.addTime(i * step); + c.end = c.start.addTime(step); + c.resource = col.id; + + c.onmousedown = this._onCellMousedown; + // c.onmousemove = this._mousemove; + c.onmouseup = function() { + return false; + }; + + c.onclick = function() { + return false; + }; + + if (create) { + c.root = this; + + c.style.padding = '0px'; + c.style.border = '0px none'; + c.style.verticalAlign = 'top'; + c.style.height = calendar.cellHeight + 'px'; + c.style.overflow = 'hidden'; + c.unselectable = 'on'; + + var div = document.createElement("div"); + div.unselectable = 'on'; + div.style.height = calendar.cellHeight + "px"; + div.style.position = "relative"; + div.className = this._prefixCssClass("_cell"); + + var business = this._isBusinessCell(c.start, c.end); + + var properties = { + "business": business, + "text": null, + "html": null, + "cssClass": null, + "backColor": null, + "backImage": null, + "backRepeat": null, + }; + + (function() { + if (typeof calendar.onBeforeCellRender === 'function') { + var args = {}; + args.cell = { + "start": c.start, + "end": c.end, + "resource": c.resource, + "properties": properties + }; + calendar.onBeforeCellRender(args); + } + })(); + + + if (properties.business) { + DayPilot.Util.addClass(div, calendar._prefixCssClass("_cell_business")); + } + + if (properties.cssClass) { + DayPilot.Util.addClass(div, properties.cssClass); + } + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = this._prefixCssClass("_cell_inner"); + + var html = DayPilot.Util.escapeTextHtml(properties.text, properties.html); + if (html) { + inner.innerHTML = html; + } + + if (properties.backColor) { + inner.style.backgroundColor = properties.backColor; + } + + if (properties.backImage) { + inner.style.backgroundImage = "url(" + properties.backImage + ")"; + } + + if (properties.backRepeat) { + inner.style.backgroundRepeat = properties.backRepeat; + } + + div.appendChild(inner); + c.appendChild(div); + + c.appendChild(div); + + } + } + } + + table.root = this; + + calendar.nav.scrollable.onmousemove = function(ev) { + var ref = calendar.nav.scrollable; + calendar.coords = DayPilot.mo3(ref, ev); + + var mousePos = DayPilot.mc(ev); + + if (DayPilotCalendar.resizing) { + if (!DayPilotCalendar.resizingShadow) { + DayPilotCalendar.resizingShadow = calendar._createShadow(DayPilotCalendar.resizing, false, calendar.shadow); + } + + var _step = calendar.cellHeight; + var _startOffset = 1; + var delta = (mousePos.y - DayPilotCalendar.originalMouse.y); + + // TODO: clear + if (DayPilotCalendar.resizing.dpBorder === 'bottom') { + var newHeight = Math.floor(((DayPilotCalendar.originalHeight + DayPilotCalendar.originalTop + delta) + _step / 2) / _step) * _step - DayPilotCalendar.originalTop + _startOffset; + + if (newHeight < _step) + newHeight = _step; + + var max = calendar.nav.main.clientHeight; + if (DayPilotCalendar.originalTop + newHeight > max) + newHeight = max - DayPilotCalendar.originalTop; + + // DayPilotCalendar.resizingShadow.style.height = (newHeight - 4) + 'px'; + DayPilotCalendar.resizingShadow.style.height = (newHeight) + 'px'; + } + else if (DayPilotCalendar.resizing.dpBorder === 'top') { + var newTop = Math.floor(((DayPilotCalendar.originalTop + delta - _startOffset) + _step / 2) / _step) * _step + _startOffset; + + if (newTop < _startOffset) { + newTop = _startOffset; + } + + if (newTop > DayPilotCalendar.originalTop + DayPilotCalendar.originalHeight - _step) { + newTop = DayPilotCalendar.originalTop + DayPilotCalendar.originalHeight - _step; + } + + // var newHeight = DayPilotCalendar.originalHeight - (newTop - DayPilotCalendar.originalTop) - 4; + var newHeight = DayPilotCalendar.originalHeight - (newTop - DayPilotCalendar.originalTop); + + if (newHeight < _step) { + newHeight = _step; + } + else { + DayPilotCalendar.resizingShadow.style.top = newTop + 'px'; + } + + DayPilotCalendar.resizingShadow.style.height = (newHeight) + 'px'; + } + } + else if (DayPilotCalendar.moving) { + + if (!calendar.coords) { + return; + } + + if (!DayPilotCalendar.movingShadow) { + + var minDistance = 3; + var mousePos = DayPilot.mc(ev); + var distance = Math.abs(mousePos.x - DayPilotCalendar.originalMouse.x) + Math.abs(mousePos.y - DayPilotCalendar.originalMouse.y); + if (distance <= minDistance) { + return; + } + // fixes the ie8 bug (incorrect offsetX and offsetY causes flickering during move if there are inline elements in the event + DayPilotCalendar.movingShadow = calendar._createShadow(DayPilotCalendar.moving, true, calendar.shadow); + DayPilotCalendar.movingShadow.style.width = (DayPilotCalendar.movingShadow.parentNode.offsetWidth + 1) + 'px'; + } + + var _step = calendar.cellHeight; + var _startOffset = 1; + + var offset = DayPilotCalendar.moveOffsetY; + if (!offset) { + offset = _step / 2; // for external drag + } + + var newTop = Math.floor(((calendar.coords.y - offset - _startOffset) + _step / 2) / _step) * _step + _startOffset; + + if (newTop < _startOffset) { + newTop = _startOffset; + } + + var main = calendar.nav.events; + var max = calendar.nav.main.clientHeight + _startOffset; + + var height = parseInt(DayPilotCalendar.movingShadow.style.height); // DayPilotCalendar.moving.data.height + if (newTop + height > max) { + newTop = max - height; + } + + DayPilot.Util.addClass(DayPilotCalendar.moving, calendar._prefixCssClass("_event_moving_source")); + + DayPilotCalendar.movingShadow.parentNode.style.display = 'none'; + DayPilotCalendar.movingShadow.style.top = newTop + 'px'; + DayPilotCalendar.movingShadow.parentNode.style.display = ''; + + var colWidth = main.clientWidth / main.rows[0].cells.length; + var column = Math.floor((calendar.coords.x - 45) / colWidth); + + if (column < 0) { + column = 0; + } + + if (column < main.rows[0].cells.length && column >= 0 && DayPilotCalendar.movingShadow.column !== column) { + DayPilotCalendar.movingShadow.column = column; + DayPilotCalendar.moveShadow(main.rows[0].cells[column]); + } + } + else if (DayPilotCalendar.selecting) { + + var mousePos = DayPilot.mc(ev); + + var cellcoords = calendar._table.getCellCoords(); + var x = DayPilotCalendar.column; + var cell = calendar.nav.main.rows[cellcoords.y].cells[x]; + + + // clean + // calendar.clearSelection(); + + // new selected cells + if (mousePos.y < DayPilotCalendar.firstMousePos.y) { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsBelow(cell); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.selectedCells[0]; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.firstSelected; + } + else { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsAbove(cell); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.firstSelected; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.selectedCells[0]; + } + + calendar._activateSelection(); + + } + }; + calendar.nav.scrollable.style.display = ''; + }; + + this._isBusinessCell = function(start, end) { + if (this.businessBeginsHour < this.businessEndsHour) + { + return !(start.getHours() < this.businessBeginsHour || start.getHours() >= this.businessEndsHour || start.getDayOfWeek() === 6 || start.getDayOfWeek() === 0); + } + + if (start.getHours() >= this.businessBeginsHour) + { + return true; + } + + if (start.getHours() < this.businessEndsHour) + { + return true; + } + + return false; + }; + + this._disposeHeader = function() { + var table = this.nav.header; + if (table && table.rows) { + for(var y = 0; y < table.rows.length; y++) { + var r = table.rows[y]; + for (var x = 0; x < r.cells.length; x++) { + var c = r.cells[x]; + c.onclick = null; + c.onmousemove = null; + c.onmouseout = null; + } + } + } + if (!this.fasterDispose) DayPilot.pu(table); + }; + + this._drawHeaderRow = function(create) { + + // column headers + var r = (create) ? this.nav.header.insertRow(-1) : this.nav.header.rows[0]; + + var columns = this._columns; + + var len = columns.length; + + function drawHeaderCell(i) { + var data = columns[i]; + + var cell = (create) ? r.insertCell(-1) : r.cells[i]; + cell.data = data; + + cell.style.overflow = 'hidden'; + cell.style.padding = '0px'; + cell.style.border = '0px none'; + cell.style.height = (calendar.headerHeight) + "px"; + + cell.onclick = calendar._headerClickDispatch; + + var div = (create) ? document.createElement("div") : cell.firstChild; + var inner; + + if (create) { + div.unselectable = 'on'; + div.style.MozUserSelect = 'none'; + div.style.cursor = 'default'; + div.style.position = 'relative'; + div.className = calendar._prefixCssClass('_colheader'); + div.style.height = calendar.headerHeight + "px"; + + if (!calendar.headerTextWrappingEnabled) { + div.style.whiteSpace = 'nowrap'; + } + + inner = document.createElement("div"); + inner.className = calendar._prefixCssClass('_colheader_inner'); + inner.unselectable = 'on'; + + div.appendChild(inner); + cell.appendChild(div); + } + else { + inner = div.firstChild; + } + + var args = {}; + args.header = {}; + args.header.cssClass = null; + args.header.verticalAlignment = "center"; + args.column = calendar._createColumn(data, calendar); + + if (typeof calendar.onBeforeHeaderRender === 'function') { + DayPilot.Util.copyProps(data, args.header, ['id', 'start', 'name', 'html', 'backColor', 'toolTip', 'areas']); + calendar.onBeforeHeaderRender(args); + DayPilot.Util.copyProps(args.header, data, ['html', 'backColor', 'toolTip', 'areas', 'cssClass', 'verticalAlignment']); + } + + if (data.toolTip) { + inner.title = data.toolTip; + } + + if (data.cssClass) { + DayPilot.Util.addClass(div, data.cssClass); + } + + if (data.backColor) { + inner.style.background = data.backColor; + } + + if (data.areas) { + DayPilot.Areas.attach(div, data); + } + + var va = data.verticalAlignment; + if (va) { + inner.style.display = "flex"; + switch (va) { + case "center": + inner.style.alignItems = "center"; + break; + case "top": + inner.style.alignItems = "flex-start"; + break; + case "bottom": + inner.style.alignItems = "flex-end"; + break; + } + } + + var text = div.firstChild; + text.innerHTML = calendar._xssTextHtml(data.name, data.html); + } + + for (var i = 0; i < len; i++) { + drawHeaderCell(i); + } + }; + + this._headerClickDispatch = function(ev) { + + var handling = calendar.headerClickHandling; + + if (handling === "Disabled") { + return; + } + + var data = this.data; + var c = calendar._createColumn(data); + + var args = {}; + args.header = {}; + args.header.id = data.id; + args.header.name = data.name; + args.header.start = data.start; + args.column = c; + args.originalEvent = ev; + args.shift = ev.shiftKey; + args.ctrl = ev.ctrlKey; + args.meta = ev.metaKey; + + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onHeaderClick === 'function') { + calendar.onHeaderClick(args); + if (args.preventDefault.value) { + return; + } + } + + if (typeof calendar.onHeaderClicked === 'function') { + calendar.onHeaderClicked(args); + } + + }; + + this._createColumn = function(data) { + return new DayPilot.CalendarColumn(data, calendar); + }; + + this._widthUnit = function() { + if (this.width && this.width.indexOf("px") !== -1) { + return "Pixel"; + } + return "Percentage"; + }; + + this._drawHeader = function() { + + var header = this.nav.header; + var create = true; + + var columns = this._columns; + var len = columns.length; + + while (this.headerCreated && header && header.rows && header.rows.length > 0 && create) { + if (!this.fasterDispose) DayPilot.pu(header.rows[0]); + header.deleteRow(0); + } + + this.headerCreated = true; + + if (!create) { + // corner + var corner = calendar.nav.corner; + if (!this.fasterDispose) DayPilot.pu(corner.firstChild); + } + + this._drawHeaderRow(create); + }; + + this.loadingStart = function() { + if (this.loadingLabelVisible) { + this.nav.loading.innerHTML = this.loadingLabelText; + this.nav.loading.style.top = (this.headerHeight + 5) + "px"; + this.nav.loading.style.display = ''; + } + }; + + this.commandCallBack = function(command, data) { + var params = {}; + params.command = command; + this._callBack2('Command', data, params); + }; + + this.loadingStop = function(msg) { + if (this.callbackTimeout) { + window.clearTimeout(this.callbackTimeout); + } + + this.nav.loading.style.display = 'none'; + }; + + this._enableScrolling = function() { + + var scrollDiv = this.nav.scroll; + + if (!scrollDiv.onscroll) { + scrollDiv.onscroll = function() { + calendar._saveScrollHour(); + }; + } + + var scrollpos = (typeof this._config.scrollpos !== 'undefined') ? this._config.scrollpos : this.initScrollPos; + + if (!scrollpos) { + return; + } + + + if (scrollpos === 'Auto') { + if (this.heightSpec === "BusinessHours") { + scrollpos = 2 * this.cellHeight * this.businessBeginsHour; + } + else { + scrollpos = 0; + } + } + + scrollDiv.root = this; + + // initial position + if (scrollDiv.scrollTop === 0) { + scrollDiv.scrollTop = scrollpos; + } + }; + + this.callbackError = function (result, context) { + alert("Error!\r\nResult: " + result + "\r\nContext:" + context); + }; + + this._fixScrollHeader = function() { + var w = DayPilot.sw(this.nav.scroll); + var d = this.nav.cornerRight; + if (d) { + d.style.width = w + 'px'; + } + }; + + this._registerGlobalHandlers = function() { + if (!DayPilotCalendar.globalHandlers) { + DayPilotCalendar.globalHandlers = true; + DayPilot.re(document, 'mouseup', DayPilotCalendar.gMouseUp); + DayPilot.re(window, 'unload', DayPilotCalendar.gUnload); + } + }; + + this.events = {}; + //this.events.list = []; + + this.events.add = function(e) { + + var data = null; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + data = e; + } + else { + throw "DayPilot.Calendar.events.add() expects an object or DayPilot.Event instance."; + } + + if (!calendar.events.list) { + calendar.events.list = []; + } + + calendar.events.list.push(data); + calendar._update({"eventsOnly": true}); + calendar._angular.notify(); + }; + + + this.events.find = function(id) { + if (!calendar.events.list) { + return null; + } + + if (typeof id === "function") { + var fn = id; + for (var i = 0; i < calendar.events.list.length; i++) { + var e = new DayPilot.Event(calendar.events.list[i], calendar); + if (fn(e)) { + return e; + } + } + return null; + } + + for (var i = 0; i < calendar.events.list.length; i++) { + var data = calendar.events.list[i]; + if (data.id === id) { + return new DayPilot.Event(data, calendar); + } + } + return null; + }; + + this.events.update = function(e) { + if (e instanceof DayPilot.Event) { + e.commit(); + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + var index = DayPilot.indexOf(calendar.events.list, target.data); + calendar.events.list.splice(index, 1, e); + } + } + + calendar._update({"eventsOnly": true}); + calendar._angular.notify(); + }; + + this.events.remove = function(e) { + var data; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + data = target.data; + } + } + else if (typeof e === "string" || typeof e === "number") { + var target = calendar.events.find(e); + if (target) { + data = target.data; + } + } + + var index = DayPilot.indexOf(calendar.events.list, data); + calendar.events.list.splice(index, 1); + calendar._update({"eventsOnly": true}); + calendar._angular.notify(); + }; + + this.events.load = function(url, success, error) { + var onError = function(args) { + var largs = {}; + largs.exception = args.exception; + largs.request = args.request; + + if (typeof error === 'function') { + error(largs); + } + }; + + var onSuccess = function(args) { + var r = args.request; + var data; + + // it's supposed to be JSON + try { + data = JSON.parse(r.responseText); + } + catch (e) { + var fargs = {}; + fargs.exception = e; + onError(fargs); + return; + } + + if (DayPilot.isArray(data)) { + var sargs = {}; + sargs.preventDefault = function() { + this.preventDefault.value = true; + }; + sargs.data = data; + if (typeof success === "function") { + success(sargs); + } + + if (sargs.preventDefault.value) { + return; + } + + calendar.events.list = data; + if (calendar._initialized) { + calendar._update({"eventsOnly": true}); + } + } + }; + + var usePost = calendar.eventsLoadMethod && calendar.eventsLoadMethod.toUpperCase() === "POST"; + + if (usePost) { + DayPilot.Http.ajax({ + "method": "POST", + "data": { "start": calendar.visibleStart().toString(), "end": calendar.visibleEnd().toString()}, + "url": url, + "success": onSuccess, + "error": onError + }); + } + else { + var fullUrl = url; + var queryString = "start=" + calendar.visibleStart().toString() + "&end=" + calendar.visibleEnd().toString(); + if (fullUrl.indexOf("?") > -1) { + fullUrl += "&" + queryString; + } + else { + fullUrl += "?" + queryString; + } + + DayPilot.Http.ajax({ + "method": "GET", + "url": fullUrl, + "success": onSuccess, + "error": onError + }); + } + + }; + + this._updateTheme = function() { + // manually update theme for elements that are not redrawn during update + //return; + + var needsUpdate = calendar.nav.top.className !== calendar._prefixCssClass("_main"); + + if (!needsUpdate) { + return; + } + + calendar.nav.top.className = calendar._prefixCssClass("_main"); + var corner = calendar.nav.corner; + corner.className = calendar._prefixCssClass("_corner"); + corner.firstChild.className = calendar._prefixCssClass("_corner_inner"); + + var cr = calendar.nav.cornerRight; + if (cr) { + cr.className = calendar._prefixCssClass("_cornerright"); + cr.firstChild.className = calendar._prefixCssClass("_cornerright_inner"); + } + }; + + this.update = function(options) { + + if (calendar._disposed) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Calendar instance that has been disposed."); + } + + calendar._loadOptions(options); + calendar._update(); + }; + + this._update = function(args) { + + if (!this._initialized) { + return; + } + + var args = args || {}; + var full = !args.eventsOnly; + + calendar._prepareVariables(); + calendar._deleteEvents(); + + // reset after drag and drop/deleting + calendar.nav.top.style.cursor = "auto"; + + // calendar._show(); + + if (full) { + calendar._prepareColumns(); + calendar._drawHeader(); + calendar._drawMain(); + calendar._drawHourTable(); + calendar._updateHeight(); + calendar._updateCorner(); + calendar._fixScrollHeader(); + calendar._updateTheme(); + + calendar._restoreScrollHour(); + } + + calendar._loadEvents(); + calendar._updateHeaderHeight(); + + calendar._drawEvents(); + calendar.clearSelection(); + + if (this.visible) { + this.show(); + } + else { + this.hide(); + } + }; + + + this._specialHandling = null; + this._loadOptions = function(options) { + if (!options) { + return; + } + var specialHandling = { + "events": { + "preInit": function() { + var events = this.data || []; + if (DayPilot.isArray(events.list)) { + calendar.events.list = events.list; + } + else { + calendar.events.list = events; + } + } + }, + "columns": { + "preInit": function() { + calendar.columns.list = this.data; + } + } + }; + this._specialHandling = specialHandling; + + for (var name in options) { + if (specialHandling[name]) { + var item = specialHandling[name]; + item.data = options[name]; + if (item.preInit) { + item.preInit(); + } + } + else { + calendar[name] = options[name]; + } + } + + }; + + this._postInit = function() { + var specialHandling = this._specialHandling; + for (var name in specialHandling) { + var item = specialHandling[name]; + if (item.postInit) { + item.postInit(); + } + } + }; + + this._loadTop = function() { + if (this.id && this.id.tagName) { + this.nav.top = this.id; + } + else if (typeof this.id === "string") { + this.nav.top = document.getElementById(this.id); + if (!this.nav.top) { + throw "DayPilot.Calendar: The placeholder element not found: '" + id + "'."; + } + } + else { + throw "DayPilot.Calendar() constructor requires the target element or its ID as a parameter"; + } + }; + + this._cache = {}; + this._cache.events = []; + + this._doBeforeEventRender = function(i) { + var cache = this._cache.events; + var data = this.events.list[i]; + var evc = {}; + + // make a copy + for (var name in data) { + evc[name] = data[name]; + } + + if (typeof this.onBeforeEventRender === 'function') { + var args = {}; + args.control = calendar; + args.data = evc; + this.onBeforeEventRender(args); + } + + cache[i] = evc; + + }; + + this._loadEvents = function() { + + var events = this.events.list; + + calendar._cache.events = []; + + if (!events) { + return; + } + + if (!DayPilot.isArray(events)) { + throw new DayPilot.Exception("DayPilot.Calendar.events.list expects an array object. You supplied: " + (typeof events)); + } + + var length = events.length; + var duration = 24 * 60 * 60 * 1000; + + this.cache.pixels = {}; + + var loadCache = []; + + this.scrollLabels = []; + + this.minStart = 10000; + this.maxEnd = 0; + + for (var i = 0; i < length; i++) { + var e = events[i]; + var edata = e; + + if (typeof edata !== "object") { + throw new DayPilot.Exception("Event data item must be an object"); + } + if (!edata.start) { + throw new DayPilot.Exception("Event data item must specify 'start' property"); + } + if (!edata.end) { + throw new DayPilot.Exception("Event data item must specify 'end' property"); + } + + if (edata instanceof DayPilot.Event) { + throw new DayPilot.Exception("DayPilot.Calendar: DayPilot.Event object detected in events.list array. Use raw event data instead."); + } + + e.start = new DayPilot.Date(e.start); + e.end = new DayPilot.Date(e.end); + } + + if (typeof this.onBeforeEventRender === 'function') { + for (var i = 0; i < length; i++) { + this._doBeforeEventRender(i); + } + } + + for(var i = 0; i < this._columns.length; i++) { + + var scroll = {}; + scroll.minEnd = 1000000; + scroll.maxStart = -1; + this.scrollLabels.push(scroll); + + var col = this._columns[i]; + col.events = []; + col.lines = []; + col.blocks = []; + + var colStart = new DayPilot.Date(col.start); + var colStartTicks = colStart.getTime(); + var colEnd = colStart.addTime(duration); + var colEndTicks = colEnd.getTime(); + + for (var j = 0; j < length; j++) { + if (loadCache[j]) { + continue; + } + + var e = events[j]; + + var start = e.start; + var end = e.end; + + var startTicks = start.getTime(); + var endTicks = end.getTime(); + + if (endTicks < startTicks) { // skip invalid events + continue; + } + + // belongs here + var belongsHere = !(endTicks <= colStartTicks || startTicks >= colEndTicks); + if (calendar.viewType === "Resources") { + belongsHere = belongsHere && col.id === e.resource; + } + + if (belongsHere) { + var ep = new DayPilot.Event(e, calendar); // event part + ep.part.dayIndex = i; + ep.part.start = colStartTicks < startTicks ? e.start : colStart; + ep.part.end = colEndTicks > endTicks ? e.end : colEnd; + + var partStartPixels = this.getPixels(ep.part.start, col.start); + var partEndPixels = this.getPixels(ep.part.end, col.start); + + var top = partStartPixels.top; + var bottom = partEndPixels.top; + + // events in the hidden areas + if (top === bottom && (partStartPixels.cut || partEndPixels.cut)) { + continue; + } + + var boxBottom = partEndPixels.boxBottom; + + ep.part.top = Math.floor(top / this.cellHeight) * this.cellHeight + 1; + ep.part.height = Math.max(Math.ceil(boxBottom / this.cellHeight) * this.cellHeight - ep.part.top, this.cellHeight - 1) + 1; + ep.part.barTop = Math.max(top - ep.part.top - 1, 0); // minimum 0 + ep.part.barHeight = Math.max(bottom - top - 2, 1); // minimum 1 + + var start = ep.part.top; + var end = ep.part.top + ep.part.height; + + if (start > scroll.maxStart) { + scroll.maxStart = start; + } + if (end < scroll.minEnd) { + scroll.minEnd = end; + } + + if (start < this.minStart) { + this.minStart = start; + } + if (end > this.maxEnd) { + this.maxEnd = end; + } + col.events.push(ep); + + if (typeof this.onBeforeEventRender === 'function') { + ep.cache = this._cache.events[j]; + } + + if (ep.part.start.getTime() === startTicks && ep.part.end.getTime() === endTicks) { + loadCache[j] = true; + } + } + } + + } + + + // sort events inside rows + for (var i = 0; i < this._columns.length; i++) { + var col = this._columns[i]; + col.events.sort(this._eventComparer); + + // put into lines + for (var j = 0; j < col.events.length; j++) { + var e = col.events[j]; + col.putIntoBlock(e); + } + + for (var j = 0; j < col.blocks.length; j++) { + var block = col.blocks[j]; + block.events.sort(this._eventComparer); + for (var k = 0; k < block.events.length; k++ ) { + var e = block.events[k]; + block.putIntoLine(e); + } + } + } + }; + + this._eventComparer = function(a, b) { + if (!a || !b || !a.start || !b.start) { + return 0; // no sorting, invalid arguments + } + + var byStart = a.start().getTime() - b.start().getTime(); + if (byStart !== 0) { + return byStart; + } + + var byEnd = b.end().getTime() - a.end().getTime(); // desc + return byEnd; + }; + + this.debug = function(msg, append) { + if (!this.debuggingEnabled) { + return; + } + + if (!calendar.debugMessages) { + calendar.debugMessages = []; + } + calendar.debugMessages.push(msg); + + if (typeof console !== 'undefined') { + console.log(msg); + } + }; + + this.getPixels = function(date, start) { + if (!start) start = this.startDate; + + var startTicks = start.getTime(); + var ticks = date.getTime(); + + var cache = this.cache.pixels[ticks + "_" + startTicks]; + if (cache) { + return cache; + } + + startTicks = start.getTime(); + + var boxTicks = 30 * 60 * 1000; + var topTicks = ticks - startTicks; + var boxOffsetTicks = topTicks % boxTicks; + + var boxStartTicks = topTicks - boxOffsetTicks; + var boxEndTicks = boxStartTicks + boxTicks; + if (boxOffsetTicks === 0) { + boxEndTicks = boxStartTicks; + } + + // it's linear scale so far + var result = {}; + result.cut = false; + result.top = this._ticksToPixels(topTicks); + result.boxTop = this._ticksToPixels(boxStartTicks); + result.boxBottom = this._ticksToPixels(boxEndTicks); + + this.cache.pixels[ticks + "_" + startTicks] = result; + + return result; + }; + + this._ticksToPixels = function(ticks) { + return Math.floor( (this.cellHeight * ticks) / (1000 * 60 * 30) ); + }; + + this._prepareVariables = function() { + this.startDate = new DayPilot.Date(this.startDate).getDatePart(); + }; + + this._updateHeaderHeight = function() { + if (this.nav.corner) { + this.nav.corner.style.height = this.headerHeight + "px"; + } + }; + + this._updateHeight = function() { + var sh = this._getScrollableHeight(); + if (this.nav.scroll && sh > 0) { + this.nav.scroll.style.height = sh + "px"; + } + }; + + this._angular = {}; + this._angular.scope = null; + this._angular.notify = function() { + if (calendar._angular.scope) { + calendar._angular.scope["$apply"](); + } + }; + this._angular.apply = function(f) { + // autoapply has been disabled + f(); + + /* + if (calendar.angularAutoApply && calendar._angular.scope) { + calendar._angular.scope["$apply"](f); + } + else { + f(); + } + */ + }; + + this._saveScrollHour = function() { + if (!calendar.nav.scroll) { + return; + } + var top = calendar.nav.scroll.scrollTop; + var pos = top / (2*calendar.cellHeight); + calendar._config.scrollHour = pos; + }; + + this._restoreScrollHour = function() { + var scrollpos = 0; + if (typeof calendar._config.scrollHour === "number") { + scrollpos = 2 * calendar.cellHeight * calendar._config.scrollHour; + //calendar._config.scrollHour = null; + } + else { + if (calendar.initScrollPos === 'Auto') { + if (this.heightSpec === "BusinessHours") { + scrollpos = 2 * this.cellHeight * this.businessBeginsHour; + } + else { + scrollpos = 0; + } + } + } + + calendar.nav.scroll.scrollTop = scrollpos; + }; + + this._loadFromServer = function() { + // make sure it has a place to ask + if (this.backendUrl || typeof WebForm_DoCallback === 'function') { + return (typeof calendar.events.list === 'undefined') || (!calendar.events.list); + } + else { + return false; + } + }; + + this._show = function() { + if (this.nav.top.style.visibility === 'hidden') { + this.nav.top.style.visibility = 'visible'; + } + }; + + this.show = function() { + calendar.visible = true; + calendar.nav.top.style.display = ''; + this._fixScrollHeader(); + }; + + this.hide = function() { + calendar.visible = false; + calendar.nav.top.style.display = 'none'; + }; + this._initShort = function() { + this._prepareVariables(); + this._prepareColumns(); + this._drawTop(); + this._drawHeader(); + this._drawMain(); + this._fixScrollHeader(); + this._enableScrolling(); + this._registerGlobalHandlers(); + DayPilotCalendar.register(this); + + this._waitForVisibility(); + this._callBack2('Init'); + }; + + this._config = {}; + + this._saveConfig = function() { + this._config.themes = []; + this._config.themes.push(this.theme || this.cssClassPrefix); + }; + + this._clearThemes = function() { + var themes = this._config.themes; + for (var i = 0; i < themes.length; i++) { + var theme = themes[i]; + DayPilot.Util.removeClass(this.nav.top, theme + "_main"); + } + this._config.themes = []; + }; + + this._doAfterRender = function() { + this.afterRender(null, false); + if (typeof this.onAfterRender === "function") { + var args = {}; + args.isCallBack = false; + this.onAfterRender(args); + } + }; + + this._doInit = function() { + if (typeof this.onInit === "function" && !this._onInitCalled) { + this._onInitCalled = true; + var args = {}; + this.onInit(args); + } + }; + + this._visible = function() { + var el = calendar.nav.top; + if (!el) { + return false; + } + return el.offsetWidth > 0 && el.offsetHeight > 0; + }; + + this._waitForVisibility = function() { + var visible = calendar._visible; + + if (!visible()) { + calendar._visibilityInterval = setInterval(function() { + if (visible()) { + calendar._enableScrolling(); + calendar._fixScrollHeader(); + clearInterval(calendar._visibilityInterval); + } + }, 100); + } + }; + + this._xssTextHtml = function(text, html) { + + if (calendar._resolved._xssProtectionEnabled()) { + return DayPilot.Util.escapeTextHtml(text, html); + } + + if (!DayPilot.Util.isNullOrUndefined(html)) { + return html; + } + if (DayPilot.Util.isNullOrUndefined(text)) { + return ""; + } + return text; + }; + + + this.internal = {}; + this.internal.loadOptions = calendar._loadOptions; + this.internal.xssTextHtml = calendar._xssTextHtml; + + this.init = function() { + this._loadTop(); + + var loadFromServer = this._loadFromServer(); + + this._saveConfig(); + + if (loadFromServer) { + this._initShort(); + return; + } + + this._prepareVariables(); + this._prepareColumns(); + + this._loadEvents(); + + this._drawTop(); + this._drawHeader(); + this._drawMain(); + + this._show(); + + this._fixScrollHeader(); + this._enableScrolling(); + this._registerGlobalHandlers(); + DayPilotCalendar.register(this); + + if (this.events) { // are events available? + this._updateHeaderHeight(); + this._drawEvents(); + } + + this._doAfterRender(); + this._doInit(); + this._waitForVisibility(); + this._initialized = true; + + return this; + }; + + this.Init = this.init; + + this._loadOptions(options); + }; + + DayPilot.CalendarColumn = function(col, calendar) { + var column = this; + + column.id = col.id; + column.name = col.name; + column.data = col.data; + column.start = new DayPilot.Date(col.start); + column.calendar = calendar; + + column.toJSON = function() { + var json = {}; + json.id = this.id; + if (this.start) { + json.start = this.start.toString(); + } + json.name = this.name; + return json; + }; + }; + + + // publish the API + DayPilot.Calendar = DayPilotCalendar.Calendar; + + // jQuery plugin + if (typeof jQuery !== 'undefined') { + (function( $ ){ + $.fn.daypilotCalendar = function(options) { + var first = null; + var j = this.each(function() { + if (this.daypilot) { // already initialized + return; + }; + + var daypilot = new DayPilot.Calendar(this.id); + this.daypilot = daypilot; + for (name in options) { + daypilot[name] = options[name]; + } + daypilot.init(); + if (!first) { + first = daypilot; + } + }); + if (this.length === 1) { + return first; + } + else { + return j; + } + }; + })( jQuery ); + } + + (function registerAngularModule() { + + var app = DayPilot.am(); + + if (!app) { + return; + } + + app.directive("daypilotCalendar", ['$parse', function($parse) { +// app.directive("daypilotCalendar", function() { + return { + "restrict": "E", + "template": "
", + "replace": true, + "link": function (scope, element, attrs) { + + var calendar = new DayPilot.Calendar(element[0]); + calendar._angular.scope = scope; + calendar.init(); + + var oattr = attrs["id"]; + if (oattr) { + scope[oattr] = calendar; + } + + // save DayPilot.Calendar object in the specified variable + var pas = attrs["publishAs"]; + if (pas) { + var getter = $parse(pas); + var setter = getter.assign; + setter(scope, calendar); + } + + // bind event handlers from attributes starting with "on" + for (var name in attrs) { + if (name.indexOf("on") === 0) { // event handler + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + scope["$apply"](function() { + f(scope, {"args": args}); + }); + }; + })(name); + } + } + + var watch = scope["$watch"]; + var config = attrs["config"] || attrs["daypilotConfig"]; + var events = attrs["events"] || attrs["daypilotEvents"]; + + watch.call(scope, config, function (value) { + //var bbOld = calendar.businessBeginsHour; + + for (var name in value) { + calendar[name] = value[name]; + } + calendar.update(); + calendar._doInit(); + }, true); + + watch.call(scope, events, function(value) { + //var calendar = element.data("calendar"); + calendar.events.list = value; + calendar.update(); + }, true); + + } + }; + }]); + })(); + +})(); +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +(function() { + + if (typeof DayPilot.DatePicker !== 'undefined' && DayPilot.DatePicker.close) { + return; + } + + DayPilot.DatePicker = function(properties) { + this.v = '2024.3.539-lite'; + var navigatorId = "navigator_" + new Date().getTime(); + var This = this; + + this.onShow = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + // this.dateFormat = null; + + this.prepare = function() { + this.locale = "en-us"; + this.target = null; + this.targetAlignment = "left"; + this.resetTarget = true; + this.pattern = this._resolved.locale().datePattern; // "M/d/yyyy" + this.theme = "navigator_default"; + this.patterns = []; + this.zIndex = null; + + // load settings + if (properties) { + for (var name in properties) { + this[name] = properties[name]; + } + } + + }; + + this.init = function() { + + this.date = new DayPilot.Date(this.date); + + var value = this._readFromTarget(); + + if (this.resetTarget && !value) { + this._writeToTarget(this.date); + } + else if (!this.resetTarget) { + This.date = value; + } + + var target = this._element(); + if (target) { + target.addEventListener("input", function() { + This.date = This._readFromTarget(); + if (This.date) { + This.navigator.select(This.date, {dontNotify: true}); + } + }); + } + + document.addEventListener("mousedown", function() { + This.close(); + }); + + return this; + + }; + + this.close = function() { + if (!this._visible) { + return; + } + + this._visible = false; + + if (this.navigator) { + this.navigator.dispose(); + } + this.div.innerHTML = ''; + if (this.div && this.div.parentNode === document.body) { + document.body.removeChild(this.div); + } + }; + + this.setDate = function(date) { + this.date = new DayPilot.Date(date); + this._writeToTarget(this.date); + }; + + this._readFromTarget = function() { + // recognized targets: input (value), other DOM elements (innerHTML) + var element = this._element(); + + if (!element) { + return this.date; + } + + var value = null; + if (element.tagName === "INPUT") { + value = element.value; + } + else { + value = element.innerText; + } + + if (!value) { + return null; + } + + var date = DayPilot.Date.parse(value, This.pattern); + for (var i = 0; i < This.patterns.length; i++) { + if (date) { + return date; + } + date = DayPilot.Date.parse(value, This.patterns[i]); + } + + return date; + }; + + this._writeToTarget = function(date) { + var element = this._element(); + + if (!element) { + return; + } + + var value = date.toString(This.pattern, This.locale); + if (element.tagName === "INPUT") { + element.value = value; + } + else { + element.innerHTML = value; + } + + }; + + this._resolved = {}; + this._resolved.locale = function() { + return DayPilot.Locale.find(This.locale); + }; + + /* this._resolved.dateFormat = function() { + if (typeof This.dateFormat === "string") { + return This.dateFormat; + } + return This._resolved.locale().datePattern; + }*/ + + this._element = function() { + var id = this.target; + // accept DOM element or id (string) + var element = (id && id.nodeType && id.nodeType === 1 ) ? id : document.getElementById(id); + return element; + }; + + Object.defineProperty(this, "visible", { + get: function() { return This._visible; } + }); + + this.show = function() { + + if (this._visible) { + return; + } + + var element = this._element(); + var navigator = this.navigator; + + var navigator = new DayPilot.Navigator(navigatorId); + navigator.api = 2; + navigator.cssOnly = true; + navigator.theme = This.theme; + navigator.weekStarts = "Auto"; + navigator.locale = This.locale; + navigator.onTimeRangeSelected = function(args) { + This.date = args.start; + + var start = args.start.addTime(navigator._pickerTimePart); + var value = start.toString(This.pattern, This.locale); + + var args = {}; + args.start = start; + args.date = start; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof This.onTimeRangeSelect === 'function') { + This.onTimeRangeSelect(args); + if (args.preventDefault.value) { + return; + } + } + + This._writeToTarget(value); + This.close(); + + if (typeof This.onTimeRangeSelected === 'function') { + This.onTimeRangeSelected(args); + } + }; + + this.navigator = navigator; + + var position = DayPilot.abs(element); + var height = element.offsetHeight; + + var align = This.targetAlignment; + + var div = document.createElement("div"); + div.style.position = "absolute"; + + if (align === "left") { + div.style.left = position.x + "px"; + } + + + div.style.top = (position.y + height) + "px"; + if (This.zIndex) { + div.style.zIndex = This.zIndex; + } + + var nav = document.createElement("div"); + nav.id = navigatorId; + div.appendChild(nav); + + div.addEventListener("mousedown", function(ev) { + var ev = ev || window.event; + ev.cancelBubble = true; + ev.stopPropagation && ev.stopPropagation(); + }); + + document.body.appendChild(div); + + this.div = div; + + var selected = This._readFromTarget() || new DayPilot.Date().getDatePart(); + + navigator.startDate = selected; + navigator._pickerTimePart = selected.getTimePart(); + // navigator.selectionStart = selected.getDatePart(); + navigator.selectionDay = selected.getDatePart(); + navigator.init(); + + if (align === "right") { + var left = (position.x + element.offsetWidth - navigator.nav.top.offsetWidth); + div.style.left = left + "px"; + } + + this._visible = true; + if (this.onShow) { + this.onShow(); + } + }; + + this.prepare(); // prepare only called once, in the constructor + this.init(); + }; + +})(); +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function(DayPilot) { + 'use strict'; + + if (typeof DayPilot.Menu !== 'undefined' && DayPilot.Menu.def) { + return; + } + + var doNothing = function() {}; + + var DayPilotMenu = {}; + + DayPilotMenu.mouse = null; + DayPilotMenu.menu = null; + DayPilotMenu.handlersRegistered = false; + DayPilotMenu.hideTimeout = null; + DayPilotMenu.waitingSubmenu = null; + + DayPilot.Menu = function(items) { + var menu = this; + var initiatorAreaDiv = null; + + this.v = '2024.3.539-lite'; + this.zIndex = 120; // more than 10,001 used by ModalPopupExtender + //this.useShadow = true; + this.cssClassPrefix = "menu_default"; + this.cssOnly = true; + this.menuTitle = null; + this.showMenuTitle = false; + this.hideOnMouseOut = false; + this.hideAfter = 200; + this.theme = null; + + this.onShow = null; + + // hiding internal properties for angular + this._state = function() {}; + //this._state.ref = null; // ref object, used for position + + if (items && DayPilot.isArray(items)) { + this.items = items; + } + + // angular change detection + this.toJSON = function() { + return null; + }; + + this.show = function(e, options) { + options = options || {}; + + var value = null; + if (!e) { + value = null; + } + else if (typeof e.id === 'string' || typeof e.id === 'number') { + value = e.id; + } + else if (typeof e.id === 'function') { + value = e.id(); + } + else if (typeof e.value === 'function') { + value = e.value(); + } + + if (typeof(DayPilot.Bubble) !== 'undefined') { // hide any bubble if active + DayPilot.Bubble.hideActive(); + } + + if (!options.submenu) { + DayPilotMenu.menuClean(); + } + + // clear old data + this._state.submenu = null; + + if (DayPilotMenu.mouse === null) { // not possible to execute before mouse move (TODO) + return; + } + + if (!menu.cssOnly) { + menu.cssOnly = true; + } + + var source = null; + if (e && e.isRow && e.$.row.task) { + source = new DayPilot.Task(e.$.row.task, e.calendar); + source.menuType = "resource"; + } + else if (e && e.isEvent && e.data.task) { + source = new DayPilot.Task(e, e.calendar); + } + else { + source = e; + } + + if (typeof menu.onShow === "function") { + var args = {}; + args.source = source; + args.menu = menu; + args.preventDefault = function () { + args.preventDefault.value = true; + }; + menu.onShow(args); + if (args.preventDefault.value) { + return; + } + } + + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.top = "0px"; + div.style.left = "0px"; + div.style.display = 'none'; + div.style.overflow = 'hidden'; + div.style.zIndex = this.zIndex + 1; + div.className = this._applyCssClass('main'); + div.onclick = function(ev) { + ev.cancelBubble = true; + this.parentNode.removeChild(this); + }; + + if (this.hideOnMouseOut) { + div.onmousemove = function(ev) { + clearTimeout(DayPilotMenu.hideTimeout); + }; + div.onmouseleave = function(ev) { + menu.delayedHide({"hideParent": true}); + }; + } + + if (!this.items || this.items.length === 0) { + throw "No menu items defined."; + } + + if (this.showMenuTitle) { + var title = document.createElement("div"); + title.innerHTML = this.menuTitle; + title.className = this._applyCssClass("title"); + div.appendChild(title); + } + + for (var i = 0; i < this.items.length; i++) { + var mi = this.items[i]; + var item = document.createElement("div"); + DayPilot.Util.addClass(item, this._applyCssClass("item")); + if (mi.items) { + DayPilot.Util.addClass(item, this._applyCssClass("item_haschildren")); + DayPilot.Util.addClass(div, this._applyCssClass(("withchildren"))); + } + + if (typeof mi === 'undefined') { + continue; + } + + if (mi.hidden) { + continue; + } + + + if (mi.text === '-') { + var separator = document.createElement("div"); + separator.addEventListener("click", function(ev) { + ev.stopPropagation(); + }); + + item.appendChild(separator); + } + else { + var link = document.createElement("a"); + link.style.position = 'relative'; + link.style.display = "block"; + + if (mi.cssClass) { + DayPilot.Util.addClass(link, mi.cssClass); + } + + if (mi.disabled) { + DayPilot.Util.addClass(link, menu._applyCssClass("item_disabled")); + } + else { + if (mi.onclick || mi.onClick) { + link.item = mi; + link.onclick = (function(mi, link) { + return function (e) { + if (typeof mi.onClick === "function") { + var args = {}; + args.item = mi; + args.source = link.source; + args.originalEvent = e; + args.preventDefault = function () { + args.preventDefault.value = true; + }; + mi.onClick(args); + if (args.preventDefault.value) { + return; + } + } + if (mi.onclick) { + mi.onclick.call(link, e); + } + }; + })(mi, link); + + var assignTouchEnd = function(mi, link) { + return function(e) { + e.stopPropagation(); + e.preventDefault(); + + var cleanup = function() { + window.setTimeout(function() { + link.source.calendar.internal.touch.active = false; + }, 500); + }; + + if (typeof mi.onClick === "function") { + var args = {}; + args.item = mi; + args.source = link.source; + args.originalEvent = e; + args.preventDefault = function() { + args.preventDefault.value = true; + }; + mi.onClick(args); + if (args.preventDefault.value) { + cleanup(); + return; + } + } + + if (mi.onclick) { + mi.onclick.call(link, e); + } + + DayPilotMenu.menuClean(); + cleanup(); + }; + }; + + DayPilot.reNonPassive(link, "touchstart", function(ev) { + ev.stopPropagation(); + ev.preventDefault(); + + link.source.calendar.internal.touch.active = true; + }); + DayPilot.reNonPassive(link, "touchend", assignTouchEnd(mi, link)); + + // link.ontouchend = assignTouchEnd(mi, link); + } + + + if (mi.items && !mi.disabled) { + var assign = function(mi, link) { + return function(ev) { + ev.preventDefault(); + ev.stopPropagation(); + menu._showSubmenu(mi, link); + }; + }; + link.ontouchend = assign(mi, link); + } + + if (mi.onclick) { + doNothing(); + } + else if (mi.href) { + link.href = mi.href.replace(/\x7B0\x7D/gim, value); // for NavigateUrl actions, only for backwards compatibility + if (mi.target) { + link.setAttribute("target", mi.target); + } + } + else if (mi.command) { + var assign = function(mi, link) { + return function(e) { + var source = link.source; + var item = mi; + item.action = item.action ? item.action : 'CallBack'; + var cal = source.calendar || source.root; + + if (source instanceof DayPilot.Link) { + cal.internal.linkMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Selection) { + cal.internal.timeRangeMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Event) { + cal.internal.eventMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Selection) { + cal.internal.timeRangeMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Task) { + if (source.menuType === "resource") { + cal.internal.resourceHeaderMenuClick(item.command, link.menuSource, item.action); + } + else { + cal.internal.eventMenuClick(item.command, link.menuSource, item.action); + } + return; + } + else { + switch (source.menuType) { // TODO legacy, remove + case 'resource': + cal.internal.resourceHeaderMenuClick(item.command, source, item.action); + return; + case 'selection': // fully replaced + cal.internal.timeRangeMenuClick(item.command, source, item.action); + return; + default: // fully replaced + cal.internal.eventMenuClick(item.command, source, item.action); + return; + } + } + + e.preventDefault(); + }; + }; + link.onclick = assign(mi, link); + link.ontouchend = assign(mi, link); + } + + } + + + if (mi.items) { + link.addEventListener("click", function(ev) { + ev.stopPropagation(); + }); + } + + link.source = source; + link.menuSource = e; + + var span = document.createElement("span"); + span.className = menu._applyCssClass("item_text"); + span.innerHTML = DayPilot.Util.escapeTextHtml(mi.text, mi.html); + link.appendChild(span); + + if (mi.image) { + var image = document.createElement("img"); + image.src = mi.image; + image.style.position = 'absolute'; + image.style.top = '0px'; + image.style.left = '0px'; + + link.appendChild(image); + } + + if (mi.icon) { + var icon = document.createElement("span"); + icon.className = menu._applyCssClass("item_icon"); + + var iel = document.createElement("i"); + iel.className = mi.icon; + icon.appendChild(iel); + + link.appendChild(icon); + } + + if (mi.symbol) { + var ns = "http://www.w3.org/2000/svg"; + var svg = document.createElementNS(ns,"svg"); + svg.setAttribute("width", "100%"); + svg.setAttribute("height", "100%"); + var use = document.createElementNS(ns,"use"); + use.setAttribute("href", mi.symbol); + svg.appendChild(use); + + var svgWrap = document.createElement("span"); + svgWrap.className = menu._applyCssClass("item_symbol"); + svgWrap.style.position = "absolute"; + svgWrap.style.top = "0px"; + svgWrap.style.left = "0px"; + svgWrap.appendChild(svg); + + link.appendChild(svgWrap); + } + + var assignOnMouseOver = function(mi, link) { + return function() { + var source = link.source; + var item = mi; + + var ws = DayPilotMenu.waitingSubmenu; + if (ws) { + if (ws.parent === item) { + return; + } + else { + clearTimeout(ws.timeout); + DayPilotMenu.waitingSubmenu = null; + } + } + + if (mi.disabled) { + return; + } + + DayPilotMenu.waitingSubmenu = {}; + DayPilotMenu.waitingSubmenu.parent = item; + DayPilotMenu.waitingSubmenu.timeout = setTimeout(function() { + + DayPilotMenu.waitingSubmenu = null; + + menu._showSubmenu(item, link); + + }, 300); + }; + }; + + link.onmouseover = assignOnMouseOver(mi, link); + + item.appendChild(link); + } + + div.appendChild(item); + + } + + var delayedDismiss = function(e) { + window.setTimeout(function() { + DayPilotMenu.menuClean(); + DayPilot.MenuBar.deactivate(); + }, 100); + }; + + div.onclick = delayedDismiss; + div.ontouchend = delayedDismiss; + + div.onmousedown = function(e) { + e = e || window.event; + e.cancelBubble = true; + if (e.stopPropagation) + e.stopPropagation(); + }; + div.oncontextmenu = function() { + return false; + }; + + document.body.appendChild(div); + menu._state.visible = true; + menu._state.source = e; + + div.style.display = ''; + var height = div.offsetHeight; + var width = div.offsetWidth; + div.style.display = 'none'; + + // don't show the menu outside of the visible window + var windowHeight = document.documentElement.clientHeight; + // required for ipad with zoom instead of document.documentElement.clientWidth + var windowWidth = window.innerWidth; + + var windowMargin = (typeof options.windowMargin == "number") ? options.windowMargin : 5; + + (function showInitiator() { + var initiator = options.initiator; + // initiator = options.initiator; + if (!initiator) { + return; + } + var div = initiator.div; + var e = initiator.e; + var area = initiator.area; + + var v = area.visibility || area.v || "Visible"; + var a = initiator.a; + if (v !== "Visible") { + // make sure the source area is visible + a = DayPilot.Areas.createArea(div, e, area); + div.appendChild(a); + // will be used to remove it on hide + initiatorAreaDiv = a; + } + + if (a) { + var abs = DayPilot.abs(a); + options.x = abs.x; + options.y = abs.y + abs.h + 2; + } + + })(); + + + (function adjustPosition() { + + // don't show it exactly under the cursor + var x = (typeof options.x === "number") ? options.x : DayPilotMenu.mouse.x + 1; + var y = (typeof options.y === "number") ? options.y : DayPilotMenu.mouse.y + 1; + + var topOffset = document.body.scrollTop || document.documentElement.scrollTop; + var leftOffset = document.body.scrollLeft || document.documentElement.scrollLeft; + + if (y - topOffset > windowHeight - height && windowHeight !== 0) { + var offsetY = y - topOffset - (windowHeight - height) + windowMargin; + div.style.top = (y - offsetY) + 'px'; + } + else { + div.style.top = y + 'px'; + } + + if (options.align === "right") { + x -= width; + } + + if (x - leftOffset > windowWidth - width && windowWidth !== 0) { + var offsetX = x - leftOffset - (windowWidth - width) + windowMargin; + div.style.left = (x - offsetX) + 'px'; + } + else { + div.style.left = x + 'px'; + } +/* + if (DayPilotMenu.mouse.clientY > windowHeight - height && windowHeight !== 0) { + var offsetY = DayPilotMenu.mouse.clientY - (windowHeight - height) + 5; + div.style.top = (y - offsetY) + 'px'; + } + else { + div.style.top = y + 'px'; + } + + if (DayPilotMenu.mouse.clientX > windowWidth - width && windowWidth !== 0) { + var offsetX = DayPilotMenu.mouse.clientX - (windowWidth - width) + 5; + div.style.left = (x - offsetX) + 'px'; + } + else { + div.style.left = x + 'px'; + } +*/ + })(); + + if (options.parentLink) { + + var parent = options.parentLink; + + var verticalOffset = parseInt(new DayPilot.StyleReader(div).get("border-top-width")); + + var pos = DayPilot.abs(options.parentLink.parentNode); + var x = pos.x + parent.offsetWidth; + var y = pos.y - verticalOffset; + + if (x + width > windowWidth) { + x = Math.max(0, pos.x - width); + } + + var docScrollTop = document.body.scrollTop + document.documentElement.scrollTop; + if (y + height - docScrollTop > windowHeight) { + y = Math.max(0, windowHeight - height + docScrollTop); + } + + div.style.left = x + "px"; + div.style.top = y + "px"; + + } + div.style.display = ''; + + this.addShadow(div); + this._state.div = div; + + if (!options.submenu) { + DayPilot.Menu.active = this; + } + + //this._initiator = null; + + }; + + this._showSubmenu = function(item, link) { + var mi = item; + var source = link.source; + + if (menu._state.submenu && menu._state.submenu.item === item) { // already visible + return; + } + + if (menu._state.submenu && menu._state.submenu.item !== item) { // hide submenus of other items + DayPilot.Util.removeClass(menu._state.submenu.link.parentNode, menu._applyCssClass("item_haschildren_active")); + menu._state.submenu.menu.hide(); + menu._state.submenu = null; + } + + if (!item.items) { // no submenu for this item + return; + } + + var options = menu.cloneOptions(); + options.items = item.items; + + menu._state.submenu = {}; + menu._state.submenu.menu = new DayPilot.Menu(options); + menu._state.submenu.menu._parentMenu = menu; + menu._state.submenu.menu.show(source, {"submenu": true, "parentLink": link, "parentItem": mi}); + menu._state.submenu.item = item; + menu._state.submenu.link = link; + DayPilot.Util.addClass(link.parentNode, menu._applyCssClass("item_haschildren_active")); + + }; + + this._applyCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + var sep = (this.cssOnly ? "_" : ""); + if (prefix) { + return prefix + sep + part; + } + else { + return ""; + } + }; + + this.cloneOptions = function() { + return DayPilot.Util.copyProps(options, {}, ["cssClassPrefix", "theme", "hideAfter", "hideOnMouseOut", "zIndex"]); + }; + + this.hide = function(props) { + props = props || {}; + + if (this._state.submenu) { + this._state.submenu.menu.hide(); + } + + var ws = DayPilotMenu.waitingSubmenu; + if (ws) { + DayPilotMenu.waitingSubmenu = null; + clearTimeout(ws.timeout); + } + + this.removeShadow(); + if (this._state.div && this._state.div.parentNode === document.body) { + document.body.removeChild(this._state.div); + } + +/* + if (this._initiator) { + DayPilot.de(this._initiator); + this._initiator = null; + } +*/ + + if (initiatorAreaDiv) { + DayPilot.de(initiatorAreaDiv); + initiatorAreaDiv = null; + } + + menu._state.visible = false; + menu._state.source = null; + + if (menu._parentMenu && props.hideParent) { + menu._parentMenu.hide(props); + } + + if (DayPilot.Menu.active === menu) { + DayPilot.Menu.active = null; + } + + if (typeof this.onHide === "function") { + var args = {}; + this.onHide(args); + } + + }; + + this.delayedHide = function(props) { + DayPilotMenu.hideTimeout = setTimeout(function() { + menu.hide(props); + }, menu.hideAfter); + }; + + this.cancelHideTimeout = function() { + clearTimeout(DayPilotMenu.hideTimeout); + }; + + // detects the mouse position, use when creating menu right before opening (.show) + this.init = function(ev) { + DayPilotMenu.mouseMove(ev); + return this; + }; + + // disabled + this.addShadow = function(object) {}; + + // disabled + this.removeShadow = function() { + /* if (!this._state.shadows) { + return; + } + + for (var i = 0; i < this._state.shadows.length; i++) { + document.body.removeChild(this._state.shadows[i]); + } + this._state.shadows = [];*/ + }; + + + var options = DayPilot.isArray(items) ? null : items; + if (options) { + for (var name in options) { + this[name] = options[name]; + } + } + + }; + + DayPilot.MenuBar = function(id, options) { + var menubar = this; + + options = options || {}; + + this.items = []; + this.theme = "menubar_default"; + this.windowMargin = 0; + + this.nav = {}; + this.elements = {}; + this.elements.items = DayPilot.list(); + + this._active = null; + this._initialized = false; + + for (var name in options) { + this[name] = options[name]; + } + + this._cssClass = function(cl) { + return this.theme + "_" + cl; + }; + + this._show = function() { + this.nav.top = document.getElementById(id); + + var top = this.nav.top; + top.className = this._cssClass("main"); + + DayPilot.list(menubar.items).forEach(function(item) { + var div = document.createElement("span"); + div.innerHTML = DayPilot.Util.escapeTextHtml(item.text, item.html); + div.className = menubar._cssClass("item"); + if (item.cssClass) { + div.classList.add(item.cssClass); + } + div.data = item; + div.onclick = function(e) { + if (menubar.active && menubar.active.item === item) { + menubar._hideActive(); + } + else if (item.children) { + menubar._activate(div); + return; + } + + if (typeof item.onClick === "function") { + var args = {}; + args.item = item; + args.originalEvent = e; + item.onClick(args); + } + }; + div.onmousedown = function(ev) { + ev.stopPropagation(); + }; + div.onmouseover = function() { + if (menubar.active && menubar.active.item !== item) { + menubar._activate(div); + } + }; + + top.appendChild(div); + menubar.elements.items.push(div); + }); + }; + + this._hideActive = function() { + var activeCss = menubar._cssClass("item_active"); + menubar.elements.items.forEach(function(div) { + DayPilot.Util.removeClass(div, activeCss); + }); + + if (menubar.active && menubar.active.menu) { + menubar.active.menu.hide(); + } + menubar.active = null; + }; + + this._isActive = function(div) { + if (!menubar.active) { + return false; + } + return menubar.active.item === div.data; + }; + + this._activate = function(div) { + if (menubar._isActive(div)) { + return; + } + + menubar._hideActive(); + + var item = div.data; + var a = menubar.active = {}; + a.item = item; + a.div = div; + + var activeCss = menubar._cssClass("item_active"); + DayPilot.Util.addClass(div, activeCss); + + var abs = DayPilot.abs(div); + + if (item.children) { + a.menu = new DayPilot.Menu({"items": item.children}); + // a.menu.show(null, { "x": abs.x + abs.w, "y": abs.y + abs.h, "align": item.align, "windowMargin": menubar.windowMargin}); + var x = abs.x; + if (item.align === "right") { + x += abs.w; + } + a.menu.show(null, { "x": x, "y": abs.y + abs.h, "align": item.align, "windowMargin": menubar.windowMargin}); + } + + DayPilot.MenuBar.active = menubar; + }; + + this.init = function() { + this._show(); + this._initialized = true; + return this; + }; + + this.dispose = function() { + if (!this._initialized) { + return; + } + this.nav.top.innerHTML = ""; + this.elements.items = []; + }; + + }; + + DayPilot.MenuBar.deactivate = function() { + if (DayPilot.MenuBar.active) { + DayPilot.MenuBar.active._hideActive(); + DayPilot.MenuBar.active = null; + } + }; + + DayPilotMenu.menuClean = function() { + if (typeof(DayPilot.Menu.active) === 'undefined') + return; + + if (DayPilot.Menu.active) { + DayPilot.Menu.active.hide(); + DayPilot.Menu.active = null; + } + + }; + + DayPilotMenu.mouseDown = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + DayPilotMenu.menuClean(); + + DayPilot.MenuBar.deactivate(); + }; + + DayPilotMenu.mouseMove = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + DayPilotMenu.mouse = DayPilotMenu.mousePosition(ev); + }; + + DayPilotMenu.touchMove = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev); + }; + + DayPilotMenu.touchStart = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + //DayPilotMenu.menuClean(); + DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev); + }; + + DayPilotMenu.touchEnd = function(ev) { + // do not call menuClean() here, it doesn't work with eventTapAndHoldHandling="ContextMenu" + // DayPilotMenu.menuClean(); + }; + + DayPilotMenu.touchPosition = function(ev) { + if (!ev || !ev.touches) { + return null; + } + var touch = ev.touches[0]; + var mouse = {}; + mouse.x = touch.pageX; + mouse.y = touch.pageY; + return mouse; + }; + + DayPilotMenu.mousePosition = function(e) { + return DayPilot.mo3(null, e); + }; + + DayPilot.Menu.touchPosition = function(ev) { + if (ev.touches) { + DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev); + } + }; + // publish the API + + DayPilot.Menu.hide = function(options) { + options = options || {}; + + if (options.calendar) { + var active = DayPilot.Menu.active; + if (active) { + var source = active._state.source; + if (source && source.calendar === options.calendar) { + DayPilotMenu.menuClean(); + } + } + } + else { + DayPilotMenu.menuClean(); + } + }; + + // current + //DayPilot.Menu = DayPilotMenu.Menu; + if (!DayPilotMenu.handlersRegistered && typeof document !== 'undefined') { + DayPilot.re(document, 'mousemove', DayPilotMenu.mouseMove); + DayPilot.re(document, 'mousedown', DayPilotMenu.mouseDown); + DayPilot.re(document, 'touchmove', DayPilotMenu.touchMove); + DayPilot.re(document, 'touchstart', DayPilotMenu.touchStart); + DayPilot.re(document, 'touchend', DayPilotMenu.touchEnd); + DayPilotMenu.handlersRegistered = true; + } + + DayPilot.Menu.def = {}; + +})(DayPilot); +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). + +v3.15.0 +https://modal.daypilot.org/ + +*/ + +if (typeof(DayPilot) === 'undefined') { + DayPilot = {}; +} + +(function(DayPilot) { + 'use strict'; + + // modal.js -> 1482 + + if (DayPilot.ModalStatic) { + return; + } + + DayPilot.ModalStatic = {}; + + DayPilot.ModalStatic.list = []; + + // hide the last one + DayPilot.ModalStatic.hide = function() { + if (this.list.length > 0) { + var last = this.list.pop(); + if (last) { + last.hide(); + } + } + }; + + DayPilot.ModalStatic.remove = function(modal) { + var list = DayPilot.ModalStatic.list; + for (var i = 0; i < list.length; i++) { + if (list[i] === modal) { + list.splice(i, 1); + return; + } + } + }; + + DayPilot.ModalStatic.close = function(result) { + DayPilot.ModalStatic.result(result); + DayPilot.ModalStatic.hide(); + }; + + DayPilot.ModalStatic.result = function(r) { + var list = DayPilot.ModalStatic.list; + if (list.length > 0) { + list[list.length - 1].result = r; + } + }; + + DayPilot.ModalStatic.displayed = function(modal) { + var list = DayPilot.ModalStatic.list; + for (var i = 0; i < list.length; i++) { + if (list[i] === modal) { + return true; + } + } + return false; + }; + + DayPilot.ModalStatic.stretch = function() { + if (this.list.length > 0) { + var last = this.list[this.list.length - 1]; + if (last) { + last.stretch(); + } + } + }; + + DayPilot.ModalStatic.last = function() { + var list = DayPilot.ModalStatic.list; + if (list.length > 0) { + return list[list.length - 1]; + } + return null; + }; + + var Sheet = function() { + + if (typeof window === "undefined") { + // next.js server-side rendering + var sheet = {}; + sheet.add = function() {}; + sheet.commit = function() {}; + return sheet; + } + + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + if (!style.styleSheet) { // ie + style.appendChild(document.createTextNode("")); + } + + var h = document.head || document.getElementsByTagName('head')[0]; + h.appendChild(style); + + var oldStyle = !! style.styleSheet; // old ie + + var sheet = {}; + sheet.rules = []; + sheet.commit = function() { + try { + if (oldStyle) { + style.styleSheet.cssText = this.rules.join("\n"); + } + } + catch (e) { + //alert("Error registering the built-in stylesheet (IE stylesheet limit reached). Stylesheet count: " + document.styleSheets.length); + } + }; + + sheet.add = function(selector, rules, index) { + if (oldStyle) { + this.rules.push(selector + "{" + rules + "\u007d"); + return; + } + if(style.sheet.insertRule) { // normal browsers, ie9+ + if (typeof index === "undefined") { + index = style.sheet.cssRules.length; + } + style.sheet.insertRule(selector + "{" + rules + "\u007d", index); + } + else if (style.sheet.addRule) { + style.sheet.addRule(selector, rules, index); + } + else { + throw "No CSS registration method found"; + } + }; + return sheet; + }; + + var iconCalendar = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB3aWR0aD0iMTAiCiAgIGhlaWdodD0iMTUiCj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDUpIj4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojY2NjY2NjO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjM4MDM3MzM2O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDE5MjgiCiAgICAgICB3aWR0aD0iOS45MTUzMDYxIgogICAgICAgaGVpZ2h0PSIxMS4zNjkzNyIKICAgICAgIHg9IjAuMTE3MTg3NSIKICAgICAgIHk9Ii0zLjAwOTk5NTciCiAgICAgICByeT0iMS4zMTE4NTA1IiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNjY2NjY2M7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNTk4MTQwMTI7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MTkzMCIKICAgICAgIHdpZHRoPSIxLjUzNDQxMzYiCiAgICAgICBoZWlnaHQ9IjIuMjE5ODI1IgogICAgICAgeD0iMi4xNTU4NDgzIgogICAgICAgeT0iLTQuMzkzNzAwMSIKICAgICAgIHJ5PSIwLjY3MTc4OTE3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSItMS4xNjU4NDY2IgogICAgICAgeD0iMS41MjM5NTA2IgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QxOTQ4IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjY3MTc4OTE3IgogICAgICAgeT0iLTQuMzkzNzAwMSIKICAgICAgIHg9IjYuNDUyNzIzNSIKICAgICAgIGhlaWdodD0iMi4yMTk4MjUiCiAgICAgICB3aWR0aD0iMS41MzQ0MTM2IgogICAgICAgaWQ9InJlY3QyMDAzIgogICAgICAgc3R5bGU9ImZpbGw6I2NjY2NjYztmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS41OTgxNDAxMjtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MjAwNSIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHg9IjQuMjE5MjYzMSIKICAgICAgIHk9Ii0xLjE2NTg0NjYiCiAgICAgICByeT0iMC4yOTYwMTQ3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSItMS4xNjU4NDY2IgogICAgICAgeD0iNi45OTI3MDA2IgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QyMDA3IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MjAxMyIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHg9IjEuNTIzOTUwNiIKICAgICAgIHk9IjEuODAyOTAzNCIKICAgICAgIHJ5PSIwLjI5NjAxNDciIC8+CiAgICA8cmVjdAogICAgICAgcnk9IjAuMjk2MDE0NyIKICAgICAgIHk9IjEuODAyOTAzNCIKICAgICAgIHg9IjQuMjE5MjYzMSIKICAgICAgIGhlaWdodD0iMS44Mjk5MDkxIgogICAgICAgd2lkdGg9IjEuODM0MjI1MSIKICAgICAgIGlkPSJyZWN0MjAxNSIKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgLz4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjQyMTg5MTkzO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDIwMTciCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB4PSI2Ljk5MjcwMDYiCiAgICAgICB5PSIxLjgwMjkwMzQiCiAgICAgICByeT0iMC4yOTYwMTQ3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSI0LjczMjU5MDciCiAgICAgICB4PSIxLjU2MzAxMzEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBpZD0icmVjdDIwMTkiCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjQyMTg5MTkzO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiIC8+CiAgICA8cmVjdAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgaWQ9InJlY3QyMDIxIgogICAgICAgd2lkdGg9IjEuODM0MjI1MSIKICAgICAgIGhlaWdodD0iMS44Mjk5MDkxIgogICAgICAgeD0iNC4yNTgzMjU2IgogICAgICAgeT0iNC43MzI1OTA3IgogICAgICAgcnk9IjAuMjk2MDE0NyIgLz4KICAgIDxyZWN0CiAgICAgICByeT0iMC4yOTYwMTQ3IgogICAgICAgeT0iNC43MzI1OTA3IgogICAgICAgeD0iNy4wMzE3NjMxIgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QyMDIzIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogIDwvZz4KPC9zdmc+Cg=="; + var iconExpand = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB3aWR0aD0iMTAiCiAgIGhlaWdodD0iMTUiCj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDUpIj4KICAgIDxwYXRoCiAgICAgICBpZD0icGF0aDMxNzMiCiAgICAgICBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojOTk5OTk5O3N0cm9rZS13aWR0aDoxLjg1MTk2ODUzO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIKICAgICAgIGQ9Ik0gMC45NTQxNDgzOCwwLjY4MTYwMzEgNS4wMzkwNjI1LDUuNDExNTM4NiA5LjEyMzk3NjYsMC42ODE2MDMxIgogICAgICAgIC8+CiAgPC9nPgo8L3N2Zz4K"; + + var sheet = new Sheet(); + sheet.add(".modal_default_main", "border: 10px solid #ccc; max-width: 90%;"); + sheet.add(".modal_default_main:focus", "outline: none;"); + sheet.add(".modal_default_content", "padding: 10px 0px;"); + sheet.add(".modal_default_inner", "padding: 20px;"); + sheet.add(".modal_default_input", "padding: 10px 0px;"); + sheet.add(".modal_default_buttons", "margin-top: 10px;"); + sheet.add(".modal_default_buttons", "padding: 10px 0px;"); + sheet.add(".modal_default_form_item", "padding: 10px 0px; position: relative;"); + sheet.add(".modal_default_form_item_level1", "border-left: 2px solid #ccc; margin-left: 10px; padding-left: 20px;"); + sheet.add(".modal_default_form_item.modal_default_form_title", "font-size: 1.5rem; font-weight: bold;"); + sheet.add(".modal_default_form_item input[type=text]", "width: 100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item textarea", "width: 100%; height: 200px; box-sizing: border-box;"); + sheet.add(".modal_default_form_item input[type=select]", "width: 100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item label", "display: block;"); + sheet.add(".modal_default_form_item select", "width: 100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item_label", "margin: 2px 0px;"); + sheet.add(".modal_default_form_item_image img", "max-width: 100%; height: auto;"); + + sheet.add(".modal_default_form_item_invalid", ""); + sheet.add(".modal_default_form_item_invalid_message", "position: absolute; right: 0px; top: 9px; background-color: red; color: #ffffff; padding: 2px; border-radius: 2px;"); + + sheet.add(".modal_default_background", "opacity: 0.5; background-color: #000;"); + sheet.add(".modal_default_ok", "padding: 3px; width: 80px;"); + sheet.add(".modal_default_cancel", "padding: 3px; width: 80px;"); + + sheet.add(".modal_default_form_item_date", "position: relative;"); + sheet.add(".modal_default_form_item_date:after", "content: ''; position: absolute; right: 7px; top: 50%; margin-top: 3px; width: 10px; height: 15px; background-image:url(" + iconCalendar + ")"); + + if (typeof navigator !== "undefined" && navigator.userAgent.indexOf("Edge") !== -1) { + sheet.add(".modal_default_form_item_date input::-ms-clear", "display: none;"); + } + + sheet.add(".modal_default_form_item_scrollable_scroll", "width: 100%; height: 200px; box-sizing: border-box; border: 1px solid #ccc; overflow-y: auto;"); + sheet.add(".modal_default_form_item_scrollable_scroll_content", "padding: 5px;"); + + sheet.add(".modal_default_form_item_searchable", "position: relative;"); + sheet.add(".modal_default_form_item_searchable_icon", ""); + sheet.add(".modal_default_form_item_searchable_icon:after", "content:''; position: absolute; right: 5px; top: 50%; margin-top: -8px; width: 10px; height: 15px; background-image:url(" + iconExpand + ");"); + sheet.add(".modal_default_form_item_searchable_list", "box-sizing: border-box; border: 1px solid #999; max-height: 150px; overflow-y: auto;"); + sheet.add(".modal_default_form_item_searchable_list_item", "background: white; padding: 2px; cursor: default;"); + sheet.add(".modal_default_form_item_searchable_list_item_highlight", "background: #ccc;"); + + sheet.add(".modal_default_form_item_time", "position: relative;"); + sheet.add(".modal_default_form_item_time_icon", ""); + sheet.add(".modal_default_form_item_time_icon:after", "content:''; position: absolute; right: 5px; top: 50%; margin-top: -8px; width: 10px; height: 15px; background-image:url(" + iconExpand + ");"); + sheet.add(".modal_default_form_item_time_list", "box-sizing: border-box; border: 1px solid #999; max-height: 150px; overflow-y: auto;"); + sheet.add(".modal_default_form_item_time_list_item", "background: white; padding: 2px; cursor: default;"); + sheet.add(".modal_default_form_item_time_list_item_highlight", "background: #ccc;"); + + sheet.add(".modal_default_form_item_datetime_parent", "display: flex;"); + sheet.add(".modal_default_form_item_datetime .modal_default_form_item_time_main", "margin-left: 5px;"); + sheet.add(".modal_default_form_item_datetime input[type='text'].modal_default_input_date ", ""); + + sheet.add(".modal_default_form_item_tabular_main", "margin-top: 10px;"); + sheet.add(".modal_default_form_item_tabular_table", "display: table; width: 100%; xbackground-color: #fff; border-collapse: collapse;"); + sheet.add(".modal_default_form_item_tabular_tbody", "display: table-row-group;"); + sheet.add(".modal_default_form_item_tabular_row", "display: table-row;"); + sheet.add(".modal_default_form_item_tabular_row.modal_default_form_item_tabular_header", ""); // used to be bold + sheet.add(".modal_default_form_item_tabular_cell.modal_default_form_item_tabular_rowaction", "padding: 0px; width: 23px;"); // _delete: width + marginLeft + sheet.add(".modal_default_form_item_tabular_cell", "display: table-cell; border: 0px; padding: 2px 2px 2px 0px; cursor: default; vertical-align: bottom;"); + sheet.add(".modal_default_form_item_tabular_header .modal_default_form_item_tabular_cell", "padding-left: 0px; padding-bottom: 0px;"); + sheet.add(".modal_default_form_item_tabular_table input[type=text], .modal_default_form_item_tabular_table input[type=number]", "width:100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item_tabular_table select", "width:100%; height:100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item_tabular_plus", "display: inline-block; background-color: #ccc; color: white; width: 20px; height: 20px; border-radius: 10px; box-sizing: border-box; position: relative; margin-left: 3px; margin-top: 3px; cursor: pointer;"); + sheet.add(".modal_default_form_item_tabular_plus:after", "content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTAnIGhlaWdodD0nMTAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTSA1LjAgMC41IEwgNS4wIDkuNSBNIDAuNSA1LjAgTCA5LjUgNS4wJyBzdHlsZT0nZmlsbDpub25lO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpidXR0JyAvPjwvc3ZnPg==\")"); + sheet.add(".modal_default_form_item_tabular_delete", "display: inline-block; background-color: #ccc; color: white; width: 20px; height: 20px; border-radius: 10px; box-sizing: border-box; position: relative; margin-left: 3px; margin-top: 3px; cursor: pointer;"); + sheet.add(".modal_default_form_item_tabular_delete:after", "content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTAnIGhlaWdodD0nMTAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTSAwLjUgMC41IEwgOS41IDkuNSBNIDAuNSA5LjUgTCA5LjUgMC41JyBzdHlsZT0nZmlsbDpub25lO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpidXR0JyAvPjwvc3ZnPg==\")"); + sheet.add(".modal_default_form_item_tabular_disabled .modal_default_form_item_tabular_plus", "display: none;"); + sheet.add(".modal_default_form_item_tabular_plus_max.modal_default_form_item_tabular_plus", "display: none;"); + sheet.add(".modal_default_form_item_tabular_disabled .modal_default_form_item_tabular_delete", "visibility: hidden;"); + sheet.add(".modal_default_form_item_tabular_empty", "height: 1px; margin: 5px 23px 5px 0px; background-color: #ccc;"); + sheet.add(".modal_default_form_item_tabular_spacer .modal_default_form_item_tabular_cell", "padding: 0px;"); + + sheet.add(".modal_min_main", "border: 1px solid #ccc; max-width: 90%;"); + sheet.add(".modal_min_background", "opacity: 0.5; background-color: #000;"); + sheet.add(".modal_min_ok", "padding: 3px 10px;"); + sheet.add(".modal_min_cancel", "padding: 3px 10px;"); + + + sheet.add(".navigator_modal_main", "border-left: 1px solid #c0c0c0;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;background-color: white;color: #000000; box-sizing: content-box;"); + sheet.add(".navigator_modal_main *, .navigator_modal_main *:before, .navigator_modal_main *:after", "box-sizing: content-box;"); + sheet.add(".navigator_modal_month", "font-size: 11px;"); + sheet.add(".navigator_modal_day", "color: black;"); + sheet.add(".navigator_modal_weekend", "background-color: #f0f0f0;"); + sheet.add(".navigator_modal_dayheader", "color: black;"); + sheet.add(".navigator_modal_line", "border-bottom: 1px solid #c0c0c0;"); + sheet.add(".navigator_modal_dayother", "color: gray;"); + sheet.add(".navigator_modal_todaybox", "border: 1px solid red;"); + sheet.add(".navigator_modal_title, .navigator_modal_titleleft, .navigator_modal_titleright", 'border-top: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;color: #333;background: #f3f3f3;'); + sheet.add(".navigator_modal_busy", "font-weight: bold;"); + sheet.add(".navigator_modal_cell", "text-align: center;"); + sheet.add(".navigator_modal_select .navigator_modal_cell_box", "background-color: #FFE794; opacity: 0.5;"); + sheet.add(".navigator_modal_title", "text-align: center;"); + sheet.add(".navigator_modal_titleleft, .navigator_modal_titleright", "text-align: center;"); + sheet.add(".navigator_modal_dayheader", "text-align: center;"); + sheet.add(".navigator_modal_weeknumber", "text-align: center;"); + sheet.add(".navigator_modal_cell_text", "cursor: pointer;"); + + sheet.commit(); + + DayPilot.Modal = function(options) { + + // default values + this.autoFocus = true; + this.focus = null; // field to be focused - field id as string or {id, value} + this.autoStretch = true; // height will be increased automatically to avoid scrollbar, until this.maxHeight is reached + this.autoStretchFirstLoadOnly = false; + this.className = null; + this.theme = "modal_default"; + this.disposeOnClose = true; + this.dragDrop = true; + this.loadingHtml = null; + this.maxHeight = null; // if not set, it will stretch until the bottom space is equal to this.top + this.scrollWithPage = true; // modal window will scroll with the page + this.useIframe = true; // only for showHtml() + this.zIndex = 99999; + + this.left = null; // will be centered if null + this.width = 600; + this.top = 20; + this.height = 200; // see also autoStretch + this.locale = null; // used for DayPilot.Modal.form() items with "date" type + + // event handler + this.closed = null; + this.onClose = null; + this.onClosed = null; + this.onShow = null; + + // internal + var This = this; + this.id = '_' + new Date().getTime() + 'n' + (Math.random() * 10); + this._registered = false; + + // drag&drop + this._start = null; + this._coords = null; + + this.showHtml = function(html) { + + if (DayPilot.ModalStatic.displayed(this)) { + throw "This modal dialog is already displayed."; + } + + if (!this.div) { + this._create(); + } + this._update(); + + if (this.useIframe) { + var delayed = function(p, innerHTML) { + return function() { + p.setInnerHTML(p.id + "iframe", innerHTML); + }; + }; + + window.setTimeout(delayed(this, html), 0); + } + else { + if (html.nodeType) { + this.div.appendChild(html); + } + else { + this.div.innerHTML = html; + } + } + + this._update(); + this._register(); + this._doShow(); + + }; + + this.showUrl = function(url) { + + if (DayPilot.ModalStatic.displayed(this)) { + throw "This modal dialog is already displayed."; + } + + //this.useIframe = true; // forced + + if (this.useIframe) { + if (!this.div) { + this._create(); + } + + var loadingHtml = this.loadingHtml; + if (loadingHtml) { + this.iframe.src = "about:blank"; + this.setInnerHTML(this.id + "iframe", loadingHtml); + } + + this.re(this.iframe, "load", this._onIframeLoad); + + this.iframe.src = url; + //this.iframe.contentWindow.modal = This; + + this._update(); + this._register(); + this._doShow(); + } + else { + This._ajax({ + "url": url, + "success": function(args) { + var html = args.request.responseText; + This.showHtml(html); + }, + "error": function(args) { + This.showHtml("Error loading the modal dialog"); + } + }); + } + + }; + + this._doShow = function() { + if (typeof This.onShow === "function") { + var args = {}; + args.root = This._body(); + args.modal = This; + This.onShow(args); + } + }; + + this._body = function() { + return This.iframe ? This.iframe.contentWindow.document : This.div; + }; + + this._ajax = function(object) { + var req = new XMLHttpRequest(); + if (!req) { + return; + } + + var method = object.method || "GET"; + var success = object.success || function() {}; + var error = object.error || function() {}; + var data = object.data; + var url = object.url; + + req.open(method, url, true); + req.setRequestHeader('Content-type', 'text/plain'); + req.onreadystatechange = function() { + if (req.readyState !== 4) + return; + if (req.status !== 200 && req.status !== 304) { + if (error) { + var args = {}; + args.request = req; + error(args); + } + else { + if (window.console) { console.log('HTTP error ' + req.status); } + } + return; + } + var args = {}; + args.request = req; + success(args); + }; + if (req.readyState === 4) { + return; + } + if (typeof data === 'object') { + data = JSON.stringify(data); + } + req.send(data); + }; + + this._update = function() { + + delete this.result; + + var win = window; + var doc = document; + + var scrollY = win.pageYOffset ? win.pageYOffset : ((doc.documentElement && doc.documentElement.scrollTop) ? doc.documentElement.scrollTop : doc.body.scrollTop); + + var height = function() { + return This._windowRect().y; + }; + + //this.hideDiv.style.height = height() + "px"; + if (this.theme) { + this.hideDiv.className = this.theme + "_background"; + } + if (this.zIndex) { + this.hideDiv.style.zIndex = this.zIndex; + } + this.hideDiv.style.display = ''; + + window.setTimeout(function() { + if (This.hideDiv) { + This.hideDiv.onclick = function() { + This.hide({"backgroundClick": true}); + }; + } + }, 500); + + if (this.theme) { + this.div.className = this.theme + "_main"; + } + else { + this.div.className = ""; + } + + if (this.className) { + this.div.className += " " + this.className; + } + if (this.left) { + this.div.style.left = this.left + "px"; + } + else { + this.div.style.marginLeft = '-' + Math.floor(this.width / 2) + "px"; // '-45%' + } + this.div.style.position = 'absolute'; + this.div.style.boxSizing = "content-box"; + this.div.style.top = (scrollY + this.top) + 'px'; + this.div.style.width = this.width + 'px'; // '90%' + if (this.zIndex) { + this.div.style.zIndex = this.zIndex; + } + + if (this.height) { + if (this.useIframe || !this.autoStretch) { + this.div.style.height = this.height + 'px'; + } + else { + this.div.style.height = ''; + } + } + if (this.useIframe && this.height) { + this.iframe.style.height = (this.height) + 'px'; + } + + this.div.style.display = ''; + + this._updateHorizontal(); + + // make sure it's there just once + DayPilot.ModalStatic.remove(this); + DayPilot.ModalStatic.list.push(this); + + /* + if (this.iframe) { + this.iframe.onload = null; + } + */ + }; + + this._onIframeLoad = function() { + This.iframe.contentWindow.modal = This; + if (This.autoStretch) { + This.stretch(); + } + }; + + this.stretch = function() { + var height = function() { + return This._windowRect().y; + }; + + var width = function() { + return This._windowRect().x; + }; + + + if (this.useIframe) { + // width first + var maxWidth = width() - 40; // fixed 20px margin + for (var w = this.width; w < maxWidth && this._hasHorizontalScrollbar(); w += 10) { + //this.iframe.style.width = (w) + 'px'; + this.div.style.width = w + 'px'; + this.div.style.marginLeft = '-' + Math.floor(w / 2) + "px"; // + } + + // height + var maxHeight = this.maxHeight || height() - 2 * this.top; + for (var h = this.height; h < maxHeight && this._hasVerticalScrollbar(); h += 10) { + this.iframe.style.height = (h) + 'px'; + this.div.style.height = h + 'px'; + } + + if (this.autoStretchFirstLoadOnly) { + this.ue(this.iframe, "load", this._onIframeLoad); + } + } + else { + this.div.style.height = ''; + } + + + }; + + this._hasHorizontalScrollbar = function() { + var document = this.iframe.contentWindow.document; + var root = document.compatMode === 'BackCompat' ? document.body : document.documentElement; + + var scrollWidth = root.scrollWidth; + var children = document.body.children; + for (var i = 0; i < children.length; i++) { + var bottom = children[i].offsetLeft + children[i].offsetWidth; + scrollWidth = Math.max(scrollWidth, bottom); + } + + var isHorizontalScrollbar = scrollWidth > root.clientWidth; + return isHorizontalScrollbar; + + }; + + this._hasVerticalScrollbar = function() { + var document = this.iframe.contentWindow.document; + var root = document.compatMode === 'BackCompat' ? document.body : document.documentElement; + + var scrollHeight = root.scrollHeight; + var children = document.body.children; + for (var i = 0; i < children.length; i++) { + var bottom = children[i].offsetTop + children[i].offsetHeight; + scrollHeight = Math.max(scrollHeight, bottom); + } + + var isVerticalScrollbar = scrollHeight > root.clientHeight; + //var isHorizontalScrollbar = root.scrollWidth > root.clientWidth; + return isVerticalScrollbar; + }; + + this._windowRect = function() { + var doc = document; + + if (doc.compatMode === "CSS1Compat" && doc.documentElement && doc.documentElement.clientWidth) { + var x = doc.documentElement.clientWidth; + var y = doc.documentElement.clientHeight; + return { x: x, y: y }; + } + else { + var x = doc.body.clientWidth; + var y = doc.body.clientHeight; + return { x: x, y: y }; + } + }; + + this._register = function() { + if (this._registered) { + return; + } + this.re(window, 'resize', this._onWindowResize); + this.re(window, 'scroll', this._onWindowScroll); + + if (this.dragDrop) { + this.re(document, 'mousemove', this._onMouseMove); + this.re(document, 'mouseup', this._onMouseUp); + } + this._registered = true; + }; + + this._unregister = function() { + this.ue(window, 'resize', this._onWindowResize); + this.ue(window, 'scroll', this._onWindowScroll); + if (this.dragDrop) { + this.ue(document, 'mousemove', this._onMouseMove); + this.ue(document, 'mouseup', this._onMouseUp); + } + this._registered = false; + }; + + this._onDragStart = function(e) { + if (e.target !== This.div) { + return; + } + e.preventDefault(); + This.div.style.cursor = "move"; + This._maskIframe(); + This._coords = This.mc(e || window.event); + This._start = { x: This.div.offsetLeft, y: This.div.offsetTop }; + + }; + + this._onMouseMove = function(e) { + if (!This._coords) { + return; + } + + var e = e || window.event; + var now = This.mc(e); + + var x = now.x - This._coords.x; + var y = now.y - This._coords.y; + + //This.iframe.style.display = 'none'; + This.div.style.marginLeft = '0px'; + This.div.style.top = (This._start.y + y) + "px"; + This.div.style.left = (This._start.x + x) + "px"; + + }; + + this._onMouseUp = function(e) { + // no drag&drop + if (!This._coords) { + return; + } + //This.iframe.style.display = ''; + This._unmaskIframe(); + This.div.style.cursor = null; + + This._coords = null; + }; + + this._maskIframe = function() { + if (!this.useIframe) { + return; + } + + var opacity = 80; + + var mask = document.createElement("div"); + mask.style.backgroundColor = "#ffffff"; + mask.style.filter = "alpha(opacity=" + opacity + ")"; + mask.style.opacity = "0." + opacity; + mask.style.width = "100%"; + mask.style.height = this.height + "px"; + mask.style.position = "absolute"; + mask.style.left = '0px'; + mask.style.top = '0px'; + + this.div.appendChild(mask); + this.mask = mask; + }; + + this._unmaskIframe = function() { + if (!this.useIframe) { + return; + } + + this.div.removeChild(this.mask); + this.mask = null; + }; + + this._onWindowResize = function() { + This._updateTop(); + This._updateHorizontal(); + }; + + this._onWindowScroll = function() { + This._updateTop(); + }; + + this._updateHorizontal = function() { + if (This.left) { + return; + } + + if (!This.div) { + return; + } + + var width = This.div.offsetWidth; + This.div.style.marginLeft = '-' + Math.floor(width / 2) + "px"; // '-45%' + }; + + this._updateTop = function() { + if (!This.hideDiv) { + return; + } + if (!This.div) { + return; + } + if (This.hideDiv.style.display === 'none') { + return; + } + if (This.div.style.display === 'none') { + return; + } + + var scrollY = This._parent.scrollY(); + + + //This.hideDiv.style.height = height() + "px"; + if (!This.scrollWithPage) { + This.div.style.top = (scrollY + This.top) + 'px'; + } + }; + + this._parent = {}; + this._parent.container = function() { + return This.container || document.body; + }; + this._parent.scrollY = function() { + var c = This._parent.container(); + if (c === document.body) { + return window.pageYOffset ? window.pageYOffset : ((document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop); + } + else { + return c.scrollTop; + } + }; + + // already available in common.js but this file should be standalone + this.re = function(el, ev, func) { + if (el.addEventListener) { + el.addEventListener(ev, func, false); + } else if (el.attachEvent) { + el.attachEvent("on" + ev, func); + } + }; + + // unregister event + this.ue = function(el, ev, func) { + if (el.removeEventListener) { + el.removeEventListener(ev, func, false); + } else if (el.detachEvent) { + el.detachEvent("on" + ev, func); + } + }; + + // mouse coords + this.mc = function(ev) { + if (ev.pageX || ev.pageY) { + return { x: ev.pageX, y: ev.pageY }; + } + return { + x: ev.clientX + document.documentElement.scrollLeft, + y: ev.clientY + document.documentElement.scrollTop + }; + }; + + // absolute element position on page + this.abs = function(element) { + var r = { + x: element.offsetLeft, + y: element.offsetTop + }; + + while (element.offsetParent) { + element = element.offsetParent; + r.x += element.offsetLeft; + r.y += element.offsetTop; + } + + return r; + }; + + this._create = function() { + + var container = This._parent.container(); + var isRoot = container === document.body; + var position = isRoot ? "fixed" : "absolute"; + + var hide = document.createElement("div"); + hide.id = this.id + "hide"; + hide.style.position = position; + hide.style.left = "0px"; + hide.style.top = "0px"; + hide.style.right = "0px"; + hide.style.bottom = "0px"; + hide.oncontextmenu = function() { return false; }; + hide.onmousedown = function() { return false; }; // prevent selecting + + container.appendChild(hide); + + var div = document.createElement("div"); + div.id = this.id + 'popup'; + div.style.position = position; + div.style.left = '50%'; + div.style.top = '0px'; + div.style.backgroundColor = 'white'; + div.style.width = "50px"; + div.style.height = "50px"; + if (this.dragDrop) { + div.onmousedown = this._onDragStart; + } + div.addEventListener("keydown", function(e) { + // prevent interaaction with the document using keyboard + e.stopPropagation(); + }); + + var defaultHeight = 50; + + var iframe = null; + if (this.useIframe) { + iframe = document.createElement("iframe"); + iframe.id = this.id + "iframe"; + iframe.name = this.id + "iframe"; + iframe.frameBorder = '0'; + iframe.style.width = '100%'; + iframe.style.height = defaultHeight + 'px'; + div.appendChild(iframe); + } + + container.appendChild(div); + + this.div = div; + this.iframe = iframe; + this.hideDiv = hide; + }; + + this.setInnerHTML = function(id, innerHTML) { + var frame = window.frames[id]; + + var doc = frame.contentWindow || frame.document || frame.contentDocument; + if (doc.document) { + doc = doc.document; + } + + if (doc.body == null) { // null in IE + doc.write(""); + } + + if (innerHTML.nodeType) { + doc.body.appendChild(innerHTML); + } + else { + doc.body.innerHTML = innerHTML; + } + + if (This.autoStretch) { + if (!This.autoStretchFirstLoadOnly || !This._stretched) { + This.stretch(); + This._stretched = true; + } + } + }; + + this.close = function(result) { + this.result = result; + this.hide(); + }; + + this.closeSerialized = function() { + var ref = This._body(); + var fields = ref.querySelectorAll("input, textarea, select"); + var result = {}; + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var name = field.name; + if (!name) { + continue; + } + var value = field.value; + /*if (field.picker) { + value = field.picker.date ? field.picker.date.toString() : null; + } + else*/ /*if (field.table) { + value = field.table.save(); + } + else*/ /*if (field.searchable) { + value = field.searchable.selected && field.searchable.selected.id; + } + else *//*if (field.tagName === "SELECT") { + var option = field.options[field.selectedIndex]; + if (option && typeof option._originalValue !== "undefined") { + value = option._originalValue; + } + } + else*/ /*if (field.type === "radio") { + if (!field.checked) { + continue; + } + value = field._originalValue; + } + else*/ /*if (field.type === "checkbox") { + value = field.checked; + }*/ + result[name] = value; + } + This.close(result); + }; + + this.hide = function(options) { + + options = options || {}; + + var args = {}; + args.backgroundClick = !!options.backgroundClick; + args.result = this.result; + args.canceled = typeof this.result === "undefined"; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof this.onClose === "function") { + this.onClose(args); + if (args.preventDefault.value) { + return; + } + } + + if (this.div) { + this.div.style.display = 'none'; + this.hideDiv.style.display = 'none'; + if (!this.useIframe) { + this.div.innerHTML = null; + } + } + + // return focus to the main window (Firefox) + window.focus(); + + //DayPilot.ModalStatic = null; + DayPilot.ModalStatic.remove(this); + + if (typeof this.onClosed === "function") { + this.onClosed(args); + } + else if (this.closed) { + this.closed(); + } + + delete this.result; + + if (this.disposeOnClose) { + + This._unregister(); + + This._de(This.div); + This._de(This.hideDiv); + + This.div = null; + This.hideDiv = null; + This.iframe = null; + } + }; + + this._de = function(e) { + if (!e) { + return; + } + e.parentNode && e.parentNode.removeChild(e); + }; + + this._applyOptions = function() { + if (!options) { + return; + } + + for (var name in options) { + this[name] = options[name]; + } + }; + + this._applyOptions(); + + }; + + DayPilot.Modal.alert = function(message, options) { + options = options || {}; + options.height = options.height || 40; + options.useIframe = false; + + var okText = options.okText || "OK"; + var cancelText = options.cancelText || "Cancel"; + + return DayPilot.getPromise(function(success, failure) { + options.onClosed = function(args) { + success(args); + /* + if (typeof args.result === "undefined") { + failure(args); + } + else { + + }*/ + }; + + var modal = new DayPilot.Modal(options); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + // div.style.padding = "10px"; + + var text = document.createElement("div"); + text.className = modal.theme + "_content"; + text.innerHTML = message; + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + // buttons.style.margin = "10px 0px"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + buttonOK.onclick = function(e) { + DayPilot.ModalStatic.close("OK"); + }; + + buttons.appendChild(buttonOK); + + div.appendChild(text); + div.appendChild(buttons); + + //var buttons = "
"; + + modal.showHtml(div); + + if (modal.autoFocus) { + buttonOK.focus(); + } + }); + + }; + + DayPilot.Modal.confirm = function(message, options) { + options = options || {}; + options.height = options.height || 40; + options.useIframe = false; + + var okText = options.okText || "OK"; + var cancelText = options.cancelText || "Cancel"; + + return DayPilot.getPromise(function(success, failure) { + options.onClosed = function(args) { + success(args); + }; + + var modal = new DayPilot.Modal(options); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + // div.style.padding = "10px"; + + var text = document.createElement("div"); + text.className = modal.theme + "_content"; + text.innerHTML = message; + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + // buttons.style.margin = "10px 0px"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + buttonOK.onclick = function(e) { + DayPilot.ModalStatic.close("OK"); + }; + + var space = document.createTextNode(" "); + + var buttonCancel = document.createElement("button"); + buttonCancel.innerText = cancelText; + buttonCancel.className = modal.theme + "_cancel"; + buttonCancel.onclick = function(e) { + DayPilot.ModalStatic.close(); + }; + + buttons.appendChild(buttonOK); + buttons.appendChild(space); + buttons.appendChild(buttonCancel); + + div.appendChild(text); + div.appendChild(buttons); + + modal.showHtml(div); + + if (modal.autoFocus) { + buttonOK.focus(); + } + + }); + }; + + + DayPilot.Modal.prompt = function(message, defaultValue, options) { + if (typeof defaultValue === "object") { + options = defaultValue; + defaultValue = ""; + } + + options = options || {}; + options.height = options.height || 40; + options.useIframe = false; + + var okText = options.okText || "OK"; + var cancelText = options.cancelText || "Cancel"; + + var inputText = defaultValue || ""; + + return DayPilot.getPromise(function(success, failure) { + options.onClosed = function(args) { + success(args); + }; + + var modal = new DayPilot.Modal(options); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + + var text = document.createElement("div"); + text.className = modal.theme + "_content"; + text.innerHTML = message; + + var inputs = document.createElement("div"); + inputs.className = modal.theme + "_input"; + //inputs.style.margin = "10px 0px"; + + var input = document.createElement("input"); + input.value = inputText; + input.style.width = "100%"; + input.onkeydown = function(e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: + modal.close(this.value); + break; + case 27: + modal.close(); + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + inputs.appendChild(input); + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + //buttons.style.margin = "10px 0px"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + buttonOK.onclick = function(e) { + modal.close(input.value); + }; + + var space = document.createTextNode(" "); + + var buttonCancel = document.createElement("button"); + buttonCancel.innerText = cancelText; + buttonCancel.className = modal.theme + "_cancel"; + buttonCancel.onclick = function(e) { + modal.close(); + }; + + buttons.appendChild(buttonOK); + buttons.appendChild(space); + buttons.appendChild(buttonCancel); + + + div.appendChild(text); + div.appendChild(inputs); + div.appendChild(buttons); + + modal.showHtml(div); + + if (modal.autoFocus) { + input.focus(); + } + + }); + }; + + var isArray = function(arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; + }; + + function setPathValue(target, path, value) { + var iodot = path.indexOf("."); + if (iodot === -1) { + if (path !== "__proto__" && path !== "constructor") { + target[path] = value; + } + return; + } + var segment = path.substring(0, iodot); + if (segment === "__proto__" || segment === "constructor") { + return; + } + var remainder = path.substring(iodot + 1); + var child = target[segment]; + if (typeof child !== "object" || child === null) { + target[segment] = {}; + child = target[segment]; + } + setPathValue(child, remainder, value); + } + + // form = array of items + // data = object with properties + // options = standard modal properties + // DayPilot.Modal.form([]); // form only - new data + // DayPilot.Modal.form({}); // data only - automatic form + // + DayPilot.Modal.form = function(form, data, options) { + if (arguments.length === 1) { + var arg = form; + var isa = isArray(arg); + + if (isa) { + data = {}; + } + else if (typeof arg === "object") { + data = form; + form = []; + for (var name in data) { + var item = {}; + item.name = name; + item.id = name; + form.push(item); + } + } + else { + throw "Invalid DayPilot.Modal.form() parameter"; + } + + } + + // make a copy + var opts = {}; + for (var name in options) { + opts[name] = options[name]; + } + + // options = options || {}; + opts.height = opts.height || 40; + opts.useIframe = false; + + /* if (typeof opts.autoFocus === "undefined") { + opts.autoFocus = false; + }*/ + + var okText = opts.okText || "OK"; + var cancelText = opts.cancelText || "Cancel"; + + // var message = opts.message || ""; + + return DayPilot.getPromise(function(success, failure) { + opts.onClosed = function(args) { + + if (args.result) { + // deep copy + var mergedResult = JSON.parse(JSON.stringify(data)); + + // unflatten + for (var name in args.result) { + setPathValue(mergedResult, name, args.result[name]); + } + args.result = mergedResult; + } + + success(args); + }; + + var modal = new DayPilot.Modal(opts); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + + var inputs = document.createElement("div"); + inputs.className = modal.theme + "_input"; + + var f = new Form({ + theme: modal.theme, + form: form, + data: data, + zIndex: modal.zIndex, + locale: modal.locale, + plugins: modal.plugins, + onKey: function(args) { + switch (args.key) { + case "Enter": + // modal.closeSerialized(); + // modal.close(f.serialize()); + if (f.validate()) { + modal.close(f.serialize()); + } + break; + case "Escape": + modal.close(); + break; + } + }, + onChange: function(args) { + if (typeof modal.onChange === "function") { + modal.onChange(args); + } + } + }); + var el = f.create(); + + inputs.append(el); + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + + if (opts.okDisabled) { + buttonOK.disabled = true; + } + buttonOK.onclick = function(e) { + if (f.validate()) { + modal.close(f.serialize()); + } + // modal.closeSerialized(); + }; + + var space = document.createTextNode(" "); + + var buttonCancel = document.createElement("button"); + buttonCancel.innerText = cancelText; + buttonCancel.className = modal.theme + "_cancel"; + buttonCancel.onclick = function(e) { + modal.close(); + }; + buttonCancel.onmousedown = function(e) { + f.canceling = true; + }; + + buttons.appendChild(buttonOK); + buttons.appendChild(space); + buttons.appendChild(buttonCancel); + + + // div.appendChild(text); + div.appendChild(inputs); + div.appendChild(buttons); + + modal.showHtml(div); + + modal.div.setAttribute("tabindex", "-1"); + modal.div.addEventListener("keydown", function(e) { + switch (e.keyCode) { + case 27: + modal.close(); + break; + case 13: + if (f.validate()) { + modal.close(f.serialize()); + } + // modal.closeSerialized(); + break; + } + }); + + if (modal.focus) { + var toBeFocused = null; + if (typeof modal.focus === "object") { + var id = modal.focus.id; + var value = modal.focus.value; + toBeFocused = f.findViewById(id, value); + } + else if (typeof modal.focus === "string") { + toBeFocused = f.findViewById(modal.focus) + } + if (toBeFocused) { + toBeFocused.focus(); + } + } + else { + var first = f.firstFocusable(); + if (modal.autoFocus && first) { + first.focus(); + } + else { + modal.div.focus(); + } + } + + }); + }; + + DayPilot.Modal.close = function(result) { + var opener = DayPilot.Modal.opener(); + if (!opener) { + return; + } + opener.close(result); + }; + + DayPilot.Modal.stretch = function(result) { + var opener = DayPilot.Modal.opener(); + if (!opener) { + throw "Unable to find the opener DayPilot.Modal instance."; + } + opener.stretch(); + }; + + DayPilot.Modal.closeSerialized = function() { + var last = DayPilot.Modal.opener() || DayPilot.ModalStatic.last(); + if (last) { + last.closeSerialized(); + } + }; + + DayPilot.Modal.opener = function() { + if (typeof DayPilot !== "undefined" && typeof DayPilot.ModalStatic !== "undefined" && DayPilot.ModalStatic.list.length > 0) { + return DayPilot.ModalStatic.list[DayPilot.ModalStatic.list.length - 1]; + } + return parent && parent.DayPilot && parent.DayPilot.ModalStatic && parent.DayPilot.ModalStatic.list[parent.DayPilot.ModalStatic.list.length - 1]; + }; + + DayPilot.Modal.Experimental = {}; + DayPilot.Modal.Experimental.Form = Form; + + if (typeof DayPilot.getPromise === "undefined") { + DayPilot.getPromise = function(f) { + if (typeof Promise !== 'undefined') { + return new Promise(f); + } + + DayPilot.Promise = function(f) { + var p = this; + + this.then = function(onFulfilled, onRejected) { + onFulfilled = onFulfilled || function() {}; + onRejected = onRejected || function() {}; + f(onFulfilled, onRejected); + return DayPilot.getPromise(f); + }; + + this['catch'] = function(onRejected) { + p.then(null, onRejected); + return DayPilot.getPromise(f); + }; + }; + + return new DayPilot.Promise(f); + + }; + } + + // end of modal.js + + // form.js -> 2877 + + var Form = function (options) { + + // properties + this.form = []; + this.data = {}; + this.theme = "form_default"; + this.zIndex = 99999; + this.locale = "en-us"; + this.plugins = {}; + + // events + this.onKey = null; + + // state + this._rows = []; + this._newRows = null; + this.canceling = false; + + this._validationTimeouts = []; + + // view + this._views = []; + this._div = null; + + options = options || {}; + + for (var name in options) { + this[name] = options[name]; + } + }; + + Form.prototype.create = function () { + this.load(); + this.render(); + + return this._div; + }; + + Form.prototype.render = function () { + var form = this; + this._div = document.createElement("div"); + this._rows.forEach(function (row) { + form.createView(row); + }); + this.applyState(); + }; + + Form.prototype.createView = function (row) { + var theme = this.theme; + var form = this; + + var div = document.createElement("div"); + div.className = theme + "_form_item " + theme + "_form_item_level" + row.level; + if (!row.interactive && row.type === "title") { + /* + if (row.type === "title") { + div.className += " " + theme + "_form_title"; + } + */ + div.className += " " + theme + "_form_title"; + } + else { + div.className += " " + theme + "_form_item_" + row.type; + } + if (row.data.cssClass) { + div.className += " " + row.data.cssClass; + } + + if (!row.isValue) { + var label = document.createElement("div"); + label.className = theme + "_form_item_label"; + label.innerText = row.text; + div.appendChild(label); + } + + var interactive = this.createInteractive(row); + interactive.onInput = function(options) { + options = options || {}; + form._validateInteractive(interactive, { + "debounce": !options.immediate + }); + if (typeof form.onChange === "function") { + var args = {}; + args.result = form.serialize(); + form.onChange(args); + } + }; + interactive.onBlur = function() { + if (!form.canceling) { + form._validateInteractive(interactive); + } + }; + interactive.apply(row); + interactive._div = div; + interactive.row = row; + + if (interactive.element) { + div.appendChild(interactive.element); + } + + this._views.push(interactive); + + this._div.appendChild(div); + + }; + + Form.prototype.validate = function() { + var form = this; + var valid = true; + this._views.forEach(function(interactive) { + var iv = form._validateInteractive(interactive); + valid = valid && iv; + }); + return valid; + }; + + Form.prototype._validateInteractive = function(interactive, options) { + options = options || {}; + var debounce = options.debounce; + var silent = options.silent; + + + var row = interactive.row; + var valid = true; + + var onValidate = typeof row.data.onValidate === "function" ? row.data.onValidate : null; + var validate = typeof row.data.validate === "function" ? row.data.validate : null; // legacy + + var validateHandler = onValidate || validate; + + if (validateHandler) { + + var args = {}; + args.valid = true; + args.value = interactive.save()[row.field]; + args.message = "Error"; + args.values = this.serialize(); // legacy + args.result = this.serialize(); + + validateHandler(args); + + var cssClassInvalid = this.theme + "_form_item_invalid"; + var cssClassMessage = this.theme + "_form_item_invalid_message"; + if (args.valid) { + clearTimeout(this._validationTimeouts[row.field]); + + if (interactive._errorMsg) { + interactive._errorMsg.remove(); + interactive._errorMsg = null; + } + interactive._div.classList.remove(cssClassInvalid); + } + else { + + function showInvalid() { + if (interactive._errorMsg) { + interactive._errorMsg.remove(); + interactive._errorMsg = null; + } + + interactive._div.classList.add(cssClassInvalid); + var msg = document.createElement("div"); + msg.classList.add(cssClassMessage); + msg.innerText = args.message; + + interactive._errorMsg = msg; + + interactive._div.appendChild(msg); + } + + if (!silent) { + if (debounce) { + + var debounceDelay = 1000; + + clearTimeout(this._validationTimeouts[row.field]); + + this._validationTimeouts[row.field] = setTimeout(function() { + showInvalid(); + }, debounceDelay); + } + else { + showInvalid(); + } + + } + + } + valid = args.valid; + } + return valid; + }; + + Form.prototype.load = function () { + // transform this.form + this.data into state (_rows) + var t = this; + this.form.forEach(function (item) { + t.processFormItem(item, 0); + }); + + var flat; + // sanity check (especially for circular references) + try { + var stringified = JSON.stringify(this.data); + var rebuilt = JSON.parse(stringified); + flat = flatten(rebuilt); + } + catch (e) { + throw new Error("The 'data' object is not serializable (it may contain circular dependencies): " + e); + } + + // set values + for (var name in flat) { + this.setValue(name, flat[name]); + } + + // set state depending on values + // this.updateDependentState(); + }; + + Form.prototype.setValue = function (name, value) { + this._rows.forEach(function (row) { + row.applyValue(name, value); + }); + }; + + Form.prototype.updateDependentState = function () { + var form = this; + var enabled = [true]; + + var source = this._newRows ? this._newRows : this._rows; + + source.forEach(function (row) { + + var updatedRow = form.updateState(row, { + enabled: enabled[row.level] && !row.data.disabled + }); + + if (updatedRow.isValue) { + enabled[updatedRow.level + 1] = updatedRow.enabled && updatedRow.checked; + } + }); + }; + + Form.prototype.processFormItem = function (item, level) { + var form = this; + var type = this.getFieldType(item); + + var rows = []; + + if (type === "radio") { + + if (item.name) { + var row = new RowModel(); + row.field = item.id; + row.data = item; + row.level = level; + row.type = "label"; + row.interactive = false; + row.text = item.name; + form._rows.push(row); + rows.push(row); + } + + item.options.forEach(function (option) { + var row = new RowModel(); + row.field = item.id; + row.data = option; + row.level = level; + row.type = type; + row.isValue = true; + row.text = option.name; + row.resolved = option.id; + form._rows.push(row); + rows.push(row); + + if (option.children) { + option.children.forEach(function (child) { + var childRows = form.processFormItem(child, level + 1); + rows = rows.concat(childRows); + }) + } + }); + } + else if (type === "title") { + var row = new RowModel(); + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = item.name; + form._rows.push(row); + rows.push(row); + } + else if (type === "image") { + var row = new RowModel(); + row.isValue = true; + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = null; + form._rows.push(row); + rows.push(row); + } + else if (type === "html") { + var row = new RowModel(); + row.isValue = true; + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = null; + form._rows.push(row); + rows.push(row); + } + else if (type === "scrollable") { + var row = new RowModel(); + row.isValue = true; + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = null; + form._rows.push(row); + rows.push(row); + } + else { + var row = new RowModel(); + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.text = item.name; + row.children = []; + form._rows.push(row); + rows.push(row); + } + + if (type === "checkbox") { + row.isValue = true; + row.resolved = true; + + if (item.children) { + item.children.forEach(function (child) { + var childRows = form.processFormItem(child, level + 1); + rows = rows.concat(childRows); + }) + } + } + + return rows; + + }; + + Form.prototype.doOnKey = function (key) { + if (typeof this.onKey === "function") { + var args = { + key: key + }; + this.onKey(args); + } + }; + + Form.prototype.createInteractive = function (row) { + var form = this; + var views = { + "label": function () { + return new Interactive(); + }, + "title": function () { + return new Interactive(); + }, + "image": function() { + var interactive = new Interactive(); + + var image = document.createElement("img"); + image.src = row.data.image; + + interactive.element = image; + + return interactive; + }, + "html": function() { + var interactive = new Interactive(); + + var div = document.createElement("div"); + if (typeof row.data.text === "string") { + div.innerText = row.data.text; + } + else if (typeof row.data.html === "string") { + div.innerHTML = row.data.html; + } + + interactive.element = div; + + return interactive; + }, + "scrollable": function() { + var interactive = new Interactive(); + + var scroll = document.createElement("div"); + scroll.className = form.theme + "_form_item_scrollable_scroll"; + + if (row.data.height) { + scroll.style.height = row.data.height + "px"; + } + + var div = document.createElement("div"); + div.className = form.theme + "_form_item_scrollable_scroll_content"; + if (typeof row.data.text === "string") { + div.innerText = row.data.text; + } + else if (typeof row.data.html === "string") { + div.innerHTML = row.data.html; + } + + scroll.appendChild(div); + + interactive.element = scroll; + + return interactive; + }, + "text": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + + var input = interactive.element; + input.value = row.value; + input.disabled = !row.enabled; + }; + + var input = document.createElement("input"); + input.name = row.field; + input.type = "text"; + input.autocomplete = "off"; + input.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: + form.doOnKey("Enter"); + break; + case 27: + form.doOnKey("Escape"); + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + input.oninput = function(e) { + interactive.onInput(); + }; + input.onblur = function(e) { + interactive.onBlur(); + } + + interactive.element = input; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + interactive.element.setSelectionRange(0, interactive.element.value.length); + }; + interactive.save = function() { + var result = {}; + result[row.field] = input.value; + return result; + }; + + return interactive; + }, + "textarea": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + + var input = interactive.element; + input.value = row.value; + input.disabled = !row.enabled; + }; + + var textarea = document.createElement("textarea"); + textarea.name = row.field; + if (row.data.height) { + textarea.style.height = row.data.height + "px"; + } + // input.type = "text"; + textarea.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: + // form.doOnKey("Enter"); + if (e.ctrlKey || e.metaKey) { + form.doOnKey("Enter"); + } + letcontinue = false; + break; + case 27: + form.doOnKey("Escape"); + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + // e.preventDefault(); + e.stopPropagation(); + } + }; + + textarea.oninput = function(e) { + interactive.onInput(); + }; + textarea.onblur = function(e) { + interactive.onBlur(); + } + + interactive.element = textarea; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + interactive.element.setSelectionRange(0, 0); + }; + interactive.save = function() { + var result = {}; + result[row.field] = textarea.value; + return result; + }; + + return interactive; + }, + "date": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var input = interactive.element; + var picker = interactive.picker; + + if (row.data.dateFormat) { + picker.pattern = row.data.dateFormat; + } + var locale = row.data.locale || form.locale; + if (locale) { + picker.locale = locale; + } + + input.disabled = !row.enabled; + + picker.date = new DayPilot.Date(row.value); + var formatted = new DayPilot.Date(row.value).toString(row.data.dateFormat || picker.pattern, picker.locale); + input.value = formatted; + }; + + var input = document.createElement("input"); + input.name = row.field; + + var picker = new DayPilot.DatePicker({ + target: input, + theme: "navigator_modal", + zIndex: form.zIndex + 1, + resetTarget: false, + targetAlignment: "left", + onTimeRangeSelect: function(args) { + interactive.onInput({"immediate": true}); + } + }); + + // required for serialization - to get the normalized value + input.picker = picker; + input.className = form.theme + "_input_date"; + input.type = "text"; + input.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: // enter + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Enter"); + } + break; + case 27: // escape + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Escape"); + } + break; + case 9: // tab + picker.close(); + letcontinue = true; + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + input.onfocus = function () { + picker.show(); + }; + + input.onclick = function () { + picker.show(); + }; + + /* + input.onblur = function () { + // input.picker.close(); + }; + */ + + input.oninput = function(e) { + interactive.onInput(); + }; + input.onblur = function(e) { + interactive.onBlur(); + } + + interactive.element = input; + interactive.picker = picker; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + }; + interactive.save = function() { + var value = picker.date ? picker.date.toString() : null; + var result = {}; + result[row.field] = value; + return result; + }; + return interactive; + }, + "time": function () { + return form._createInteractiveTime(row); + }, + "datetime": function() { + return form._createInteractiveDateTime(row); + }, + "select": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var select = interactive.element; + + select.value = row.value; + select.disabled = !row.enabled; + }; + + var select = document.createElement("select"); + select.name = row.field; + + if (row.data.options && row.data.options.forEach) { + row.data.options.forEach(function (i) { + var option = document.createElement("option"); + option.innerText = i.name || i.id; + option.value = i.id; + option._originalValue = i.id; + select.appendChild(option); + }); + } + + select.onchange = function(e) { + interactive.onInput({"immediate": true}); + }; + select.onblur = function(e) { + interactive.onBlur(); + }; + + interactive.element = select; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + }; + interactive.save = function() { + var value = null; + var option = select.options[select.selectedIndex]; + if (option && typeof option._originalValue !== "undefined") { + value = option._originalValue; + } + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + + }, + "searchable": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var searchable = interactive.searchable; + + searchable.disabled = !row.enabled; + searchable.select(row.value); + }; + + var searchable = new Searchable({ + data: row.data.options || [], + name: row.field, + theme: form.theme + "_form_item_searchable", + listZIndex: form.zIndex + 1, + // disabled: !row.enabled + onSelect: function(args) { + if (args.ui) { + interactive.onInput({"immediate": true}); + } + } + }); + + var element = searchable.create(); + + interactive.element = element; + interactive.searchable = searchable; + interactive.canFocus = function() { + return !interactive.searchable.disabled; + }; + interactive.focus = function () { + interactive.searchable.focus(); + }; + interactive.save = function() { + var value = searchable.selected && searchable.selected.id; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + }, + "radio": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var radio = interactive.radio; + + radio.checked = row.checked; + radio.disabled = !row.enabled; + }; + + var label = document.createElement("label"); + + var radio = document.createElement("input"); + radio.type = "radio"; + radio.name = row.field; + radio._originalValue = row.resolved; + + radio.onchange = function (ev) { + // activation only + + var row = interactive.row; + form.findRowsByField(row.field).forEach(function (row) { + form.updateState(row, { + checked: false + }); + }); + form.updateState(row, { + checked: true + }); + + form.applyState(); + + interactive.onInput({"immediate": true}); + }; + + radio.onblur = function(e) { + interactive.onBlur(); + }; + + label.appendChild(radio); + + var text = document.createTextNode(row.text); + label.append(text); + + interactive.element = label; + interactive.radio = radio; + interactive.canFocus = function() { + return false; + }; + interactive.focus = function () { + interactive.radio.focus(); + } + interactive.save = function() { + if (!radio.checked) { + return {}; + } + var value = radio._originalValue; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + }, + "checkbox": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var checkbox = interactive.checkbox; + + checkbox.checked = row.checked; + checkbox.disabled = !row.enabled; + }; + + var label = document.createElement("label"); + + var checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.name = row.field; + checkbox._originalValue = row.resolved; + + checkbox.onchange = function (ev) { + var row = interactive.row; + form.updateState(row, { + checked: this.checked + }); + form.applyState(); + + interactive.onInput({"immediate": true}); + }; + + checkbox.onblur = function(e) { + interactive.onBlur(); + }; + + label.appendChild(checkbox); + + var text = document.createTextNode(row.text); + label.append(text); + + interactive.element = label; + interactive.checkbox = checkbox; + interactive.canFocus = function() { + return false; + }; + interactive.focus = function () { + interactive.checkbox.focus(); + } + interactive.save = function() { + var value = checkbox.checked; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + }, + "table": function() { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var table = interactive.table; + + table.disabled = !row.enabled; + table.load(row.value || []); + + /* + if (row.value) { + table.load(row.value); + } + */ + }; + + var table = new Table({ + name: row.field, + // form: row.data.columns, + form: form, + theme: form.theme + "_form_item_tabular", + item: row.data, + onInput: function(args) { + interactive.onInput(); + } + }); + + var element = table.create(); + + interactive.element = element; + interactive.table = table; + interactive.canFocus = function() { + // return !interactive.table.disabled; + return false; + }; + interactive.focus = function () { + interactive.table.focus(); + }; + interactive.save = function() { + var value = table.save(); + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + } + }; + if (form.plugins && form.plugins[row.type]) { + return form.plugins[row.type](row); + } + return views[row.type](); + }; + + Form.prototype._createInteractiveTime = function(row) { + var form = this; + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var searchable = interactive.searchable; + + searchable.disabled = !row.enabled; + searchable.select(row.value); + }; + + var data = []; + + var interval = row.data.timeInterval || 15; // allowed values: 1, 5, 10, 15, 20, 30, 60 + var allowedIntervals = [1, 5, 10, 15, 20, 30, 60]; + if (!allowedIntervals.includes(interval)) { + interval = 15; + } + var perHour = 60 / interval; + + var localeStr = row.data.locale || form.locale; + var locale = DayPilot.Locale.find(localeStr) || DayPilot.Locale.US; + + var date = DayPilot.Date.today(); + + for (var i = 0; i < 24*perHour; i++) { + var time = date.addMinutes(interval*i); + var item = {}; + item.name = time.toString(row.data.timeFormat || locale.timePattern, locale); + item.id = time.toString("HH:mm"); + data.push(item); + } + + var searchable = new Searchable({ + data: data, + name: row.field, + theme: form.theme + "_form_item_time", + listZIndex: form.zIndex + 1, + strategy: "startsWith", + // disabled: !row.enabled + onSelect: function(args) { + if (args.ui) { + interactive.onInput({"immediate": true}); + } + } + }); + + var element = searchable.create(); + + interactive.element = element; + interactive.searchable = searchable; + interactive.canFocus = function() { + return !interactive.searchable.disabled; + }; + interactive.focus = function () { + interactive.searchable.focus(); + }; + interactive.save = function() { + var value = searchable.selected && searchable.selected.id; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + + }; + + Form.prototype._createInteractiveDateTime = function(row) { + var form = this; + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var searchable = interactive.searchable; + + searchable.disabled = !row.enabled; + + var timePart = new DayPilot.Date(row.value).toString("HH:mm"); + + searchable.select(timePart); + + var input = interactive.dateInput; + var picker = interactive.picker; + + if (row.data.dateFormat) { + picker.pattern = row.data.dateFormat; + } + var localeStr = row.data.locale || form.locale; + if (localeStr) { + var locale = DayPilot.Locale.find(localeStr) || DayPilot.Locale.US; + picker.locale = localeStr; + picker.pattern = locale.datePattern; + } + + input.disabled = !row.enabled; + + picker.date = new DayPilot.Date(row.value); + var formatted = new DayPilot.Date(row.value).toString(row.data.dateFormat || picker.pattern, picker.locale); + input.value = formatted; + + }; + + var dateElement = (function createDatePicker() { + var input = document.createElement("input"); + input.name = row.field; + + var picker = new DayPilot.DatePicker({ + target: input, + theme: "navigator_modal", + zIndex: form.zIndex + 1, + resetTarget: false, + targetAlignment: "left", + onTimeRangeSelect: function(args) { + interactive.onInput({"immediate": true}); + } + }); + + // required for serialization - to get the normalized value + input.picker = picker; + input.className = form.theme + "_input_date"; + input.type = "text"; + input.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: // enter + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Enter"); + } + break; + case 27: // escape + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Escape"); + } + break; + case 9: // tab + picker.close(); + letcontinue = true; + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + input.onfocus = function () { + picker.show(); + }; + + input.onclick = function () { + picker.show(); + }; + + input.oninput = function(e) { + interactive.onInput(); + }; + input.onblur = function(e) { + interactive.onBlur(); + } + + interactive.dateInput = input; + interactive.picker = picker; + + return input; + })(); + + + var timeElement = (function createTimePicker() { + var data = []; + + var interval = row.data.timeInterval || 15; // allowed values: 1, 5, 10, 15, 20, 30, 60 + var allowedIntervals = [1, 5, 10, 15, 20, 30, 60]; + if (!allowedIntervals.includes(interval)) { + interval = 15; + } + var perHour = 60 / interval; + + var localeStr = row.data.locale || form.locale; + var locale = DayPilot.Locale.find(localeStr) || DayPilot.Locale.US; + + var date = DayPilot.Date.today(); + + for (var i = 0; i < 24*perHour; i++) { + var time = date.addMinutes(interval*i); + var item = {}; + item.name = time.toString(row.data.timeFormat || locale.timePattern, locale); + item.id = time.toString("HH:mm"); + data.push(item); + } + + var searchable = new Searchable({ + data: data, + name: row.field, + theme: form.theme + "_form_item_time", + listZIndex: form.zIndex + 1, + strategy: "startsWith", + // disabled: !row.enabled + onSelect: function(args) { + if (args.ui) { + interactive.onInput({"immediate": true}); + } + } + }); + + interactive.searchable = searchable; + return searchable.create(); + + })(); + + + var element = document.createElement("div"); + element.className = form.theme + "_form_item_datetime_parent"; + element.appendChild(dateElement); + element.appendChild(timeElement); + + interactive.element = element; + interactive.canFocus = function() { + return !interactive.searchable.disabled; + }; + interactive.focus = function () { + interactive.dateInput.focus(); + }; + interactive.save = function() { + var timeValue = interactive.searchable.selected && interactive.searchable.selected.id; + var dateValue = interactive.picker.date ? interactive.picker.date.toString() : null; + + var date = new DayPilot.Date(dateValue).getDatePart(); + var value = DayPilot.Date.parse(date.toString("yyyy-dd-MM ") + timeValue, "yyyy-dd-MM HH:mm"); + + var result = {}; + result[row.field] = value; + return result; + + }; + + return interactive; + + }; + + Form.prototype.findRowsByField = function (field) { + return this._rows.filter(function (row) { + return row.field === field; + }); + }; + + // ooptional value param applies to radio which can have multiple views, one for each value + Form.prototype.findViewById = function (id, value) { + return this._views.find(function (v) { + if (v.row.field === id) { + if (v.row.type === "radio") { + return v.row.resolved === value; + } else { + return true; + } + } + return false; + }); + }; + + Form.prototype.firstFocusable = function () { + return this._views.find(function (v) { + return v.canFocus && v.canFocus(); + }); + }; + + Form.prototype.updateState = function (row, props) { + var source = this._newRows ? this._newRows : this._rows; + var index = source.indexOf(row); + this._newRows = source.map(function (srow) { + if (srow !== row) { + return srow; + } + // our row + if (row.propsEqual(props)) { + return row; + } + var cloned = row.clone(); + for (var name in props) { + cloned[name] = props[name]; + } + return cloned; + }); + return this._newRows[index]; + }; + + // dirty row received, a member of _newRows + Form.prototype.updateInteractive = function (row) { + var index = this._newRows.indexOf(row); + this._views[index].apply(row); + }; + + Form.prototype.applyState = function () { + var form = this; + + this.updateDependentState(); + + if (!this._newRows) { + return; + } + + var dirtyRows = this._newRows.filter(function (row, i) { + return form._rows[i] !== row; + }); + + dirtyRows.forEach(function (row) { + form.updateInteractive(row); + }); + + this._rows = this._newRows; + + this._newRows = null; + }; + + Form.prototype.getFieldType = function (item) { + + var known = ["text", "date", "select", "searchable", "radio", "checkbox", "table", "title", "image", "html", "textarea", "scrollable", "time", "datetime"]; + if (known.indexOf(item.type) !== -1) { + return item.type; + } + + if (item.type && this.plugins && this.plugins[item.type]) { + return item.type; + } + + if (item.image) { + return "image"; + } + + if (item.html || item.text) { + return "html"; + } + + if (!item.id) { + return "title"; + } + + if (item.options) { + return "searchable"; + } + + if (item.dateFormat) { + return "date"; + } + + if (item.columns) { + return "table"; + } + + return "text"; + }; + + Form.prototype.serialize = function() { + var result = {}; + + this._views.forEach(function(interactive) { + var out = interactive.save(); + for (var name in out) { + result[name] = out[name]; + } + }); + + return result; + }; + + var RowModel = function () { + this.id = this.guid(); + this.field = null; + this.data = null; + this.type = null; + this.level = 0; + this.enabled = true; + this.value = null; + this.text = null; + + this.interactive = true; + + this.isValue = false; + this.checked = false; + this.resolved = null; // value resolves to + }; + + RowModel.prototype.clone = function () { + var rm = new RowModel(); + for (var name in this) { + if (name === "id") { + continue; + } + rm[name] = this[name]; + } + return rm; + }; + + RowModel.prototype.propsEqual = function (props) { + for (var name in props) { + if (this[name] !== props[name]) { + return false; + } + } + return true; + }; + + RowModel.prototype.guid = function () { + var S4 = function () { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + }; + return ("" + S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); + }; + + RowModel.prototype.applyValue = function (name, value) { + if (this.field !== name) { + return; + } + this.value = value; + if (this.isValue && value === this.resolved) { + this.checked = true; + } + }; + + var Interactive = function () { + // this.row = row; + this.element = null; + + // only used for autofocus + this.canFocus = function() { + return false; + }; + this.apply = function (row) { + }; + this.focus = function () { + }; + this.save = function() { + return {}; + } + }; + + function flatten(object, result, prefix) { + result = result || {}; + prefix = prefix || ""; + for (var name in object) { + var src = object[name]; + if (typeof src === "object") { + if (Object.prototype.toString.call(src) === '[object Array]') { + result[prefix + name] = src; + } + else if (src && src.toJSON) { + result[prefix + name] = src.toJSON(); + } + else { + flatten(src, result, prefix + name + "."); + } + } + else { + result[prefix + name] = src; + } + } + return result; + } + + // end of form.js + + // searchable.js -> 3265 + var Searchable = function(options) { + + // properties + this.data = []; + this.name = null; + this.theme = "searchable_default"; + this._disabled = false; + this.listZIndex = 100000; + + + // events + this.onSelect = null; + + // state + this._selected = null; + this._highlighted = null; + this._collapsed = false; + // this._focused = false; + // this._filter = null; + + // view + this._input = null; + this._list = null; + this._options = []; + this._hidden = null; + + options = options || {}; + + var t = this; + + var specialHandling = { + "selected": { + post: function(val) { + if (typeof val === "object" && val.id) { + t._selected = val; + } + else if (typeof val === "string" || typeof val === "number") { + t.select(val); + } + } + } + }; + + Object.defineProperty(this, "selected", { + get: function() { + return this._selected; + }, + }); + + Object.defineProperty(this, "disabled", { + get: function() { + return this._disabled; + }, + set: function(val) { + this._disabled = val; + if (this._input) { + this._input.disabled = val; + if (val) { + // verify + this._cancel(); + } + } + } + }); + + for (var name in options) { + if (!specialHandling[name]) { + this[name] = options[name]; + } + } + + for (var name in options) { + if (specialHandling[name]) { + specialHandling[name].post(options[name]); + } + } + + }; + + Searchable.prototype.select = function(id) { + this._selected = this.data.find(function(item) { return item.id === id }); + this._doOnSelect(false); + return this; + }; + + + Searchable.prototype.create = function() { + var component = this; + var t = this; + + var div = document.createElement("div"); + div.className = this.theme + "_main"; + div.style.position = "relative"; + + var icon = document.createElement("div"); + icon.className = this.theme + "_icon"; + icon.style.position = "absolute"; + icon.style.right = "0"; + icon.style.top = "0"; + icon.style.bottom = "0"; + icon.style.width = "20px"; + icon.addEventListener("mousedown", function(ev) { + ev.preventDefault(); + if (component._collapsed) { + component.focus(); + expand(); + } + else { + cancel(); + collapse(); + } + }); + + var list = document.createElement("div"); + list.className = this.theme + "_list"; + list.style.display = "none"; + list.style.position = "absolute"; + list.style.zIndex = this.listZIndex; + + var hidden = document.createElement("input"); + hidden.type = "hidden"; + hidden.name = this.name; + hidden.searchable = t; + this._hidden = hidden; + + var input = document.createElement("input"); + input.type = "text"; + input.className = this.theme + "_input"; + input.disabled = this._disabled; + input.addEventListener("click", function(ev) { + // console.log("click"); + expand(); + }); + input.addEventListener("focus", function(ev) { + // do not call expand() here, the readonly status has to stay + // input.value = ""; + // console.log("focus"); + filter("all"); + }); + input.addEventListener("input", function(ev) { + filter(); + }); + input.addEventListener("blur", function(ev) { + input.removeAttribute("readonly"); + cancel(); + }); + + input.addEventListener("keydown", function(ev) { + if (component._collapsed) { + if (ev.key === "Enter") { + return; + } + if (ev.key === "Esc" || ev.key === "Escape") { + return; + } + expand(); + } + + if (ev.key === "ArrowDown") { + var index = t._options.indexOf(t._highlighted); + if (index + 1 < t._options.length) { + t._highlighted = t._options[index + 1]; + } + updateHiglight(); + } else if (ev.key === "ArrowUp") { + var index = t._options.indexOf(t._highlighted); + if (index - 1 >= 0) { + t._highlighted = t._options[index - 1]; + } + updateHiglight(); + } else if (ev.key === "Enter") { + if (component._highlighted) { + ev.stopPropagation(); + selectOption(component._highlighted); + } + else { + ev.stopPropagation(); + // t._cancel(); + cancel(); + collapse(); + } + } else if (ev.key === "Esc" || ev.key === "Escape") { + ev.stopPropagation(); + cancel(); + collapse(); + } + }); + this._input = input; + this._list = list; + + if (!this._selected) { + this._selected = this.data[0]; + if (this._selected) { + input.value = this._selected.name; + } + } + + function filter(strategy) { + // component._collapsed = false; + + var defaultStrategy = component.strategy; + if (component.strategy !== "includes" && component.strategy !== "startsWith") { + defaultStrategy = "includes"; + } + + strategy = strategy || defaultStrategy || "includes"; + + list.style.display = ""; + list.style.top = input.offsetHeight + "px"; + list.style.left = "0px"; + list.style.width = input.offsetWidth + "px"; + list.innerHTML = ""; + + // allow scrollbar access + list.addEventListener("mousedown", function(ev) { + ev.preventDefault(); + }); + + component._highlighted = null; + + component._options = []; + + var first = null; + + component.data.forEach(function(item) { + + var name = item.name || item.id; + + if (strategy === "includes") { + if (name.toLowerCase().indexOf(input.value.toLowerCase()) === -1) { + return; + } + } + else if (strategy === "startsWith") { + if (name.toLowerCase().indexOf(input.value.toLowerCase()) !== 0) { + return; + } + } + else if (strategy === "all") { + // don't skip + } + + + var option = document.createElement("div"); + option.className = component.theme + "_list_item"; + option.innerText = name; + + option.item = item; + + if (item === component._selected) { + component._highlighted = option; + } + if (!first) { + first = option; + } + + // "mousedown" goes before blur, "click" goes after + option.addEventListener("mousedown", function(ev) { + selectOption(option); + ev.preventDefault(); + }); + + option.addEventListener("mousemove", function(ev) { + if (component._highlighted === option) { + return; + } + component._highlighted = option; + updateHiglight({dontScroll: true}); + }); + + list.appendChild(option); + + component._options.push(option); + }); + + if (!component._highlighted) { + component._highlighted = first; + } + updateHiglight(); + } + + function updateHiglight(options) { + options = options || {}; + var scrollIntoView = !options.dontScroll; + + // redo, avoid selectors + var previous = document.querySelectorAll("." + component.theme + "_list_item_highlight"); + previous.forEach(function(p) { + p.className = p.className.replace(component.theme + "_list_item_highlight", ""); + }); + + if (component._highlighted) { + component._highlighted.className += " " + component.theme + "_list_item_highlight"; + + if (scrollIntoView && !isScrolledIntoView(component._highlighted, list)) { + component._highlighted.scrollIntoView(); + } + } + } + + function isScrolledIntoView(target, viewport) { + var tRect = target.getBoundingClientRect(); + var vRect = viewport.getBoundingClientRect(); + return tRect.top >= vRect.top && tRect.bottom <= vRect.bottom; + } + + function selectOption(option) { + var item = option.item; + + // input.value = option.innerText; + component._selected = item; + component._doOnSelect(true); + hide(); + collapse(); + } + + function cancel() { + component._cancel(); + } + + function hide() { + component._hide(); + } + + function collapse() { + component._collapsed = true; + input.setAttribute("readonly", "readonly"); + input.focus(); + } + + function expand() { + component._collapsed = false; + input.removeAttribute("readonly"); + // input.value = ""; + input.select(); + filter("all"); + } + + div.appendChild(input); + div.appendChild(icon); + div.appendChild(hidden); + div.appendChild(list); + return div; + }; + + Searchable.prototype._cancel = function() { + this._hide(); + if (!this._selected) { + this._input.value = ""; + // not sure about this: + this._doOnSelect(true); + } else { + this._input.value = this._selected.name; + } + // collapse(); + } + + Searchable.prototype.focus = function() { + // this._input.focus(); + + this._collapsed = true; + this._input.setAttribute("readonly", "readonly"); + this._input.focus(); + this._cancel(); + }; + + Searchable.prototype._hide = function() { + this._list.style.display = "none"; + }; + + Searchable.prototype._doOnSelect = function(byUser) { + this._hidden.value = this.selected ? this.selected.id : null; + if (this._selected) { + this._input.value = this._selected.name; + } + else { + this._input.value = ""; + } + + if (typeof this.onSelect === "function") { + var args = { + control: this, + ui: byUser + }; + this.onSelect(args); + } + }; + + // end of searchable.js + + // table.js -> 3641 + var Table = function(options) { + + this.form = null; // Form instance + this.item = null; // table def from form + this.data = null; + this.name = null; + this.theme = "edit_table_default"; + this.onInput = null; + + this.nav = {}; + + this._activeEdit = null; + this._rows = []; + + options = options || {}; + + for (var name in options) { + this[name] = options[name]; + } + + }; + + Table.prototype.create = function() { + var table = this; + + var div = document.createElement("div"); + div.className = this.theme + "_main"; + div.style.position = "relative"; + + var hidden = document.createElement("input"); + hidden.type = "hidden"; + hidden.name = table.name; + hidden.table = this; + div.appendChild(hidden); + + var tableElement = document.createElement("div"); + tableElement.className = this.theme + "_table"; + var header = this._createHeader(); + tableElement.appendChild(header); + + var spacerRow = table._createRowState({}); + spacerRow.spacer = true; + var spacer = this._renderRow(spacerRow); + // spacer.style.visibility = "hidden"; + spacer.classList.add(table.theme + "_spacer"); + tableElement.appendChild(spacer); + + var body = document.createElement("div"); + body.className = table.theme + "_tbody"; + tableElement.appendChild(body); + + div.appendChild(tableElement); + + var after = document.createElement("div"); + div.appendChild(after); + + this.nav.body = body; + this.nav.table = tableElement; + this.nav.main = div; + this.nav.after = after; + + var add = document.createElement("div"); + var plus = document.createElement("span"); + plus.className = this.theme + "_plus"; + + plus.addEventListener("click", function(ev) { + if (table.disabled) { + return; + } + + var generate = table.item.onNewRow; + var value = {}; + if (typeof generate === "function") { + var args = {}; + args.result = table.form.serialize(); + args.value = {}; + generate(args); + value = args.value; + } + + var row = table._createRowState(value); + table._rows.push(row); + table._render(); + table._doOnInput(); + }); + + this.nav.plus = plus; + + add.appendChild(plus); + div.appendChild(add); + + return div; + }; + + Table.prototype._createHeader = function() { + var table = this; + var row = document.createElement("div"); + row.classList.add(this.theme + "_row"); + row.classList.add(this.theme + "_header"); + this.item.columns.forEach(function(item) { + var cell = document.createElement("div"); + cell.classList.add(table.theme + "_cell"); + cell.innerText = item.name; + row.appendChild(cell); + }); + return row; + }; + + Table.prototype._maxRowsReached = function() { + var max = this.item.max || 0; + if (max && this._rows.length >= max) { + return true; + } + return false; + }; + + Table.prototype.save = function() { + var table = this; + var data = []; + + table._rows.forEach(function(row) { + var item = {}; + row.cells.forEach(function(cell) { + item[cell.id] = cell.value; + }); + data.push(item); + }); + + return data; + }; + + Table.prototype.load = function(data) { + var table = this; + + var isArray = Object.prototype.toString.call(data) === '[object Array]'; + if (!isArray) { + throw new Error("Array expected"); + } + + this.data = data; + + this._createState(); + this._render(); + }; + + Table.prototype._updateCss = function() { + if (this.disabled) { + this.nav.main.classList.add(this.theme + "_disabled"); + } + else { + this.nav.main.classList.remove(this.theme + "_disabled"); + } + + var maxReached = this._maxRowsReached(); + if (maxReached) { + this.nav.plus.classList.add(this.theme + "_plus_max"); + } + else { + this.nav.plus.classList.remove(this.theme + "_plus_max"); + } + }; + + Table.prototype._createState = function() { + var table = this; + this._rows = []; + this.data.forEach(function(dataRow) { + var row = table._createRowState(dataRow); + table._rows.push(row); + }); + }; + + Table.prototype._removeRow = function(row) { + var table = this; + + var index = table._rows.indexOf(row); + table._rows.splice(index, 1); + }; + + Table.prototype._createRowState = function(dataRow) { + var table = this; + + var row = {}; + row.data = dataRow; + row.cells = []; + + table.item.columns.forEach(function(formItem) { + var id = formItem.id; + var value = dataRow[id]; + + var type = table._formItemType(formItem); + if (typeof value === "undefined") { + if (type === "text") { + value = ""; + } + else if (type === "number") { + value = 0; + } + else if (type === "select") { + var options = formItem.options; + value = options && options[0].id; + } + } + + var cell = {}; + cell.id = id; + cell.value = value; + cell.type = type; + cell.data = formItem; + row.cells.push(cell); + }); + + return row; + }; + + Table.prototype._formItemType = function(formItem) { + var type = formItem.type; + if (!type) { + if (formItem.options) { + type = "select"; + } + else { + type = "text"; + } + } + return type; + }; + + Table.prototype._render = function() { + + var table = this; + this.nav.body.innerHTML = ""; + this.nav.after.innerHTML = ""; + + this._rows.forEach(function(row) { + var el = table._renderRow(row); + table.nav.body.appendChild(el); + }); + + if (this._rows.length === 0) { + var el = table._renderEmpty(); + table.nav.after.appendChild(el); + } + + this._updateCss(); + }; + + Table.prototype._renderEmpty = function() { + var div = document.createElement("div"); + div.className = this.theme + "_empty"; + + return div; + }; + + Table.prototype._renderRow = function(row) { + var table = this; + var el = document.createElement("div"); + el.className = table.theme + "_row"; + + row.cells.forEach(function(cell) { + + var cellEl = document.createElement("div"); + cellEl.className = table.theme + "_cell"; + var interactive = table._renderCell(cell); + + if (row.spacer) { + var wrap = document.createElement("div"); + wrap.style.height = "0px"; + wrap.style.overflow = "hidden"; + wrap.appendChild(interactive); + + cellEl.appendChild(wrap); + } + else { + cellEl.appendChild(interactive); + + } + + el.appendChild(cellEl); + }); + + var cell = document.createElement("div"); + cell.classList.add(table.theme + "_cell"); + cell.classList.add(table.theme + "_rowaction"); + + var span = document.createElement("span"); + span.className = this.theme + "_delete"; + + span.addEventListener("click", function(ev) { + if (table.disabled) { + return; + } + table._removeRow(row); + table._render(); + table._doOnInput(); + }); + + if (!row.spacer) { + cell.appendChild(span); + } + + + el.appendChild(cell); + + return el; + }; + + Table.prototype._doOnInput = function() { + var table = this; + if (typeof table.onInput === "function") { + var args = {} + table.onInput(args); + } + }; + + Table.prototype._renderCell = function(cell) { + var table = this; + var type = cell.type; + if (type === "text" || type === "number") { + var input = document.createElement("input"); + input.type = type; + if (table.disabled) { + input.disabled = true; + } + if (cell.value) { + input.value = cell.value; + } + input.addEventListener("keyup", function(ev) { + if (type === "number") { + cell.value = Number(this.value); + } + else { + cell.value = this.value; + } + table._doOnInput(); + }); + return input; + } + else if (type === "select") { + var select = document.createElement("select"); + if (table.disabled) { + select.disabled = true; + } + + cell.data.options.forEach(function(item) { + var option = document.createElement("option"); + option.innerText = item.name; + option.value = item.id; + option._originalValue = item.id; + + select.appendChild(option); + + if (cell.value === item.id) { + option.setAttribute("selected", true); + } + }); + + select.addEventListener("change", function(ev) { + var option = select.options[select.selectedIndex]; + if (option && typeof option._originalValue !== "undefined") { + cell.value = option._originalValue; + } + table._doOnInput(); + }); + + return select; + } + + throw new Error("Unsupported item type: " + type); + }; + + Table.prototype.focus = function() { + }; + + // end of table.js + +})(DayPilot); +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function() { + + var doNothing = function() { }; + + if (typeof DayPilot.Month !== 'undefined' && DayPilot.Month.events) { + return; + } + + var DayPilotMonth = {}; + + DayPilotMonth.Month = function(placeholder, options) { + this.v = '2024.3.539-lite'; + this.nav = {}; + + var calendar = this; + + this.id = placeholder; + this.isMonth = true; + + // this.angularAutoApply = false; + this.api = 2; + this.backendUrl = null; + this.cellHeaderHeight = 24; + this.cellHeight = 100; // default cell height is 100 pixels (it's a minCellHeight, it will be extended if needed) + this.cellMarginBottom = 0; + this.contextMenu = null; + this.cssClassPrefix = "month_default"; + this.eventBarVisible = true; + this.eventHeight = 25; + this.eventsLoadMethod = "GET"; + this.headerHeight = 30; + this.hideUntilInit = true; + this.lineSpace = 1; + this.locale = "en-us"; + this.showToolTip = true; + this.startDate = new DayPilot.Date(); // today + this.theme = null; + this.visible = true; + this.weekStarts = "Auto"; + this.width = '100%'; // default width is 100% + this.xssProtection = "Enabled"; + + this.afterRender = function() { }; + + this.cellHeaderClickHandling = "Enabled"; + this.eventClickHandling = "Enabled"; + this.eventDeleteHandling = "Disabled"; + this.eventMoveHandling = "Update"; + this.eventResizeHandling = "Update"; + this.eventRightClickHandling = "ContextMenu"; + this.headerClickHandling = "Enabled"; + this.timeRangeSelectedHandling = "Enabled"; + + this.onCellHeaderClick = null; + this.onCellHeaderClicked = null; + this.onEventClick = null; + this.onEventClicked = null; + this.onEventDelete = null; + this.onEventDeleted = null; + this.onEventMove = null; + this.onEventMoved = null; + this.onEventResize = null; + this.onEventResized = null; + this.onEventRightClick = null; + this.onEventRightClicked = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + + this.onBeforeEventRender = null; + this.onBeforeCellRender = null; + + this.cellEvents = []; + + this.elements = {}; + this.elements.events = []; + + this.cache = {}; + + this._disposed = false; + + this._updateView = function(result, context) { + + var result = JSON.parse(result); + + if (result.CallBackRedirect) { + document.location.href = result.CallBackRedirect; + return; + } + + if (result.UpdateType === "None") { + calendar.fireAfterRenderDetached(result.CallBackData, true); + return; + } + + calendar.events.list = result.Events; + + if (result.UpdateType === "Full") { + + // properties + calendar.startDate = result.StartDate; + // calendar.headerBackColor = result.HeaderBackColor ? result.HeaderBackColor : calendar.headerBackColor; + // calendar.backColor = result.BackColor ? result.BackColor : calendar.backColor; + // calendar.nonBusinessBackColor = result.NonBusinessBackColor ? result.NonBusinessBackColor : calendar.nonBusinessBackColor; + calendar.timeFormat = result.TimeFormat ? result.TimeFormat : calendar.timeFormat; + if (typeof result.WeekStarts !== 'undefined') { calendar.weekStarts = result.WeekStarts; } // number, can be 0 + + calendar.hashes = result.Hashes; + } + + calendar._deleteEvents(); + calendar._prepareRows(); + calendar._loadEvents(); + + if (result.UpdateType === "Full") { + calendar._clearTable(); + calendar._drawTable(); + } + calendar._updateHeight(); + + calendar.show(); + + calendar._drawEvents(); + + calendar.fireAfterRenderDetached(result.CallBackData, true); + + }; + + this.fireAfterRenderDetached = function(data, isCallBack) { + var afterRenderDelayed = function(data, isc) { + return function() { + if (calendar.afterRender) { + calendar.afterRender(data, isc); + } + }; + }; + + window.setTimeout(afterRenderDelayed(data, isCallBack), 0); + }; + + this.lineHeight = function() { + return this.eventHeight + this.lineSpace; + }; + + this.events = {}; + //this.events.list = []; + + this.events.add = function(e) { + + var data = null; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + data = e; + } + else { + throw "DayPilot.Month.events.add() expects an object or DayPilot.Event instance."; + } + + // e.calendar = calendar; + + if (!calendar.events.list) { + calendar.events.list = []; + } + + calendar.events.list.push(data); + calendar.update(); + calendar._angular.notify(); + }; + + this.events.find = function(id) { + if (!calendar.events.list) { + return null; + } + + if (typeof id === "function") { + var fn = id; + for (var i = 0; i < calendar.events.list.length; i++) { + var e = new DayPilot.Event(calendar.events.list[i], calendar); + if (fn(e)) { + return e; + } + } + return null; + } + + for (var i = 0; i < calendar.events.list.length; i++) { + var data = calendar.events.list[i]; + if (data.id === id) { + return new DayPilot.Event(data, calendar); + } + } + return null; + }; + + this.events.update = function(e) { + if (e instanceof DayPilot.Event) { + e.commit(); + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + var index = DayPilot.indexOf(calendar.events.list, target.data); + calendar.events.list.splice(index, 1, e); + } + } + + calendar.update(); + calendar._angular.notify(); + }; + + this.events.remove = function(e) { + var data; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + data = target.data; + } + } + else if (typeof e === "string" || typeof e === "number") { + var target = calendar.events.find(e); + if (target) { + data = target.data; + } + } + + var index = DayPilot.indexOf(calendar.events.list, data); + calendar.events.list.splice(index, 1); + calendar.update(); + calendar._angular.notify(); + }; + + this.events.load = function(url, success, error) { + var onError = function (args) { + var largs = {}; + largs.exception = args.exception; + largs.request = args.request; + + if (typeof error === 'function') { + error(largs); + } + }; + + var onSuccess = function (args) { + var r = args.request; + var data; + + // it's supposed to be JSON + try { + data = JSON.parse(r.responseText); + } + catch (e) { + var fargs = {}; + fargs.exception = e; + onError(fargs); + return; + } + + if (DayPilot.isArray(data)) { + var sargs = {}; + sargs.preventDefault = function () { + this.preventDefault.value = true; + }; + sargs.data = data; + if (typeof success === "function") { + success(sargs); + } + + if (sargs.preventDefault.value) { + return; + } + + calendar.events.list = data; + if (calendar._initialized) { + calendar.update(); + } + } + }; + + var usePost = calendar.eventsLoadMethod && calendar.eventsLoadMethod.toUpperCase() === "POST"; + + if (usePost) { + DayPilot.Http.ajax({ + "method": "POST", + "data": {"start": calendar.visibleStart().toString(), "end": calendar.visibleEnd().toString()}, + "url": url, + "success": onSuccess, + "error": onError + }); + } + else { + var fullUrl = url; + var queryString = "start=" + calendar.visibleStart().toString() + "&end=" + calendar.visibleEnd().toString(); + if (fullUrl.indexOf("?") > -1) { + fullUrl += "&" + queryString; + } + else { + fullUrl += "?" + queryString; + } + + DayPilot.Http.ajax({ + "method": "GET", + "url": fullUrl, + "success": onSuccess, + "error": onError + }); + } + }; + + this.update = function(options) { + + calendar._loadOptions(options); + + if (!this._initialized) { + return; + } + + if (calendar._disposed) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Month instance that has been disposed."); + } + + if (!this.cells) { + return; + } + + var full = true; + + calendar._deleteEvents(); + calendar._prepareRows(); + calendar._loadEvents(); + + if (full) { + calendar._clearTable(); + calendar._drawTable(); + } + calendar._updateHeight(); + calendar._show(); + calendar._drawEvents(); + + if (this.visible) { + this.show(); + } + else { + this.hide(); + } + }; + + this._specialHandling = null; + this._loadOptions = function(options) { + if (!options) { + return; + } + var specialHandling = { + "events": { + "preInit": function() { + var events = this.data || []; + if (DayPilot.isArray(events.list)) { + calendar.events.list = events.list; + } + else { + calendar.events.list = events; + } + } + } + }; + this._specialHandling = specialHandling; + + for (var name in options) { + if (specialHandling[name]) { + var item = specialHandling[name]; + item.data = options[name]; + if (item.preInit) { + item.preInit(); + } + } + else { + calendar[name] = options[name]; + } + } + + }; + + this._postInit = function() { + var specialHandling = this._specialHandling; + for (var name in specialHandling) { + var item = specialHandling[name]; + if (item.postInit) { + item.postInit(); + } + } + }; + + this._cache = {}; + this._cache.events = []; + + this._doBeforeEventRender = function(i) { + var cache = this._cache.events; + var data = this.events.list[i]; + var evc = {}; + + // make a copy + for (var name in data) { + evc[name] = data[name]; + } + + if (typeof this.onBeforeEventRender === 'function') { + var args = {}; + args.control = calendar; + args.data = evc; + this.onBeforeEventRender(args); + } + + cache[i] = evc; + + }; + + this._loadEvents = function() { + var events = this.events.list; + + if (!events) { + return; + } + + if (!DayPilot.isArray(events)) { + throw new DayPilot.Exception("DayPilot.Month.events.list expects an array object. You supplied: " + (typeof events)); + } + + if (typeof this.onBeforeEventRender === 'function') { + for (var i = 0; i < events.length; i++) { + this._doBeforeEventRender(i); + } + } + + // prepare rows and columns + for (var x = 0; x < events.length; x++) { + var data = events[x]; + + if (typeof data !== "object") { + throw new DayPilot.Exception("Event data item must be an object"); + } + if (!data.start) { + throw new DayPilot.Exception("Event data item must specify 'start' property"); + } + if (!data.end) { + throw new DayPilot.Exception("Event data item must specify 'end' property"); + } + + var start = new DayPilot.Date(data.start); + var end = new DayPilot.Date(data.end); + if (start.getTime() > end.getTime()) { // skip invalid events, zero duration allowed + continue; + } + for (var i = 0; i < this.rows.length; i++) { + var row = this.rows[i]; + var ep = new DayPilot.Event(data, this); + if (row.belongsHere(ep)) { + row.events.push(ep); + + if (typeof this.onBeforeEventRender === 'function') { + ep.cache = this._cache.events[x]; + } + } + } + } + + // arrange events into lines + for (var ri = 0; ri < this.rows.length; ri++) { + var row = this.rows[ri]; + row.events.sort(this._eventComparer); + + for (var ei = 0; ei < this.rows[ri].events.length; ei++) { + var ev = row.events[ei]; + var colStart = row.getStartColumn(ev); + var colWidth = row.getWidth(ev); + var line = row.putIntoLine(ev, colStart, colWidth, ri); + } + } + }; + + + this._deleteEvents = function() { + for (var i = 0; i < this.elements.events.length; i++) { + var e = this.elements.events[i]; + e.event = null; + e.click = null; + e.parentNode.removeChild(e); + } + + this.elements.events = []; + + }; + + this._drawEvents = function() { + //this.cache.events = {}; // reset DayPilotMonth.Event object cache + + this._drawEventsRows(); + }; + + this._drawEventsRows = function() { + this.elements.events = []; + + // draw events + for (var ri = 0; ri < this.rows.length; ri++) { + var row = this.rows[ri]; + + for (var li = 0; li < row.lines.length; li++) { + var line = row.lines[li]; + + for (var pi = 0; pi < line.length; pi++) { + this._drawEvent(line[pi]); + } + } + } + + }; + + this._eventComparer = function(a, b) { + if (!a || !b || !a.start || !b.start) { + return 0; // no sorting, invalid arguments + } + + var byStart = a.start().getTime() - b.start().getTime(); + if (byStart !== 0) { + return byStart; + } + + var byEnd = b.end().getTime() - a.end().getTime(); // desc + return byEnd; + }; + + this.drawShadow = function(x, y, line, width, offset, e) { + + if (!offset) { + offset = 0; + } + + var remains = width; + + this.shadow = {}; + this.shadow.list = []; + this.shadow.start = { x: x, y: y }; + this.shadow.width = width; + + // something before the first day + var hidden = y * 7 + x - offset; + if (hidden < 0) { + //document.title = hidden + ' ' + new Date(); + remains += hidden; + x = 0; + y = 0; + } + + var remainingOffset = offset; + while (remainingOffset >= 7) { + y--; + remainingOffset -= 7; + } + if (remainingOffset > x) { + var plus = 7 - this.getColCount(); + if (remainingOffset > (x + plus)) { + y--; + x = x + 7 - remainingOffset; + } + else { + remains = remains - remainingOffset + x; + x = 0; + } + } + else { + x -= remainingOffset; + } + + if (y < 0) { + y = 0; + x = 0; + } + + var cursor = null; + if (DayPilotMonth.resizingEvent) { + cursor = 'w-resize'; + } + else if (DayPilotMonth.movingEvent) { + cursor = "move"; + } + + this.nav.top.style.cursor = cursor; + + while (remains > 0 && y < this.rows.length) { + var drawNow = Math.min(this.getColCount() - x, remains); + var row = this.rows[y]; + + + var top = this.getRowTop(y); + var height = row.getHeight(); + + var shadow = document.createElement("div"); + shadow.setAttribute("unselectable", "on"); + shadow.style.position = 'absolute'; + shadow.style.left = (this.getCellWidth() * x) + '%'; + shadow.style.width = (this.getCellWidth() * drawNow) + '%'; + shadow.style.top = (top) + 'px'; + shadow.style.height = (height) + 'px'; + shadow.style.cursor = cursor; + shadow.classList.add(calendar._prefixCssClass("_shadow")); + + var inside = document.createElement("div"); + inside.setAttribute("unselectable", "on"); + shadow.appendChild(inside); + + inside.style.position = "absolute"; + inside.style.top = "0px"; + inside.style.right = "0px"; + inside.style.left = "0px"; + inside.style.bottom = "0px"; + inside.classList.add(calendar._prefixCssClass("_shadow_inner")); + + // inside.style.backgroundColor = "#aaaaaa"; + // inside.style.opacity = 0.5; + // inside.style.filter = "alpha(opacity=50)"; + //inside.style.border = '2px solid #aaaaaa'; + /* + if (e) { + inside.style.overflow = 'hidden'; + inside.style.fontSize = this.eventFontSize; + inside.style.fontFamily = this.eventFontFamily; + inside.style.color = this.eventFontColor; + inside.innerHTML = e.client.html(); + } + */ + + this.nav.top.appendChild(shadow); + this.shadow.list.push(shadow); + + remains -= (drawNow + 7 - this.getColCount()); + x = 0; + y++; + } + + }; + + this.clearShadow = function() { + if (this.shadow) { + for (var i = 0; i < this.shadow.list.length; i++) { + this.nav.top.removeChild(this.shadow.list[i]); + } + this.shadow = null; + this.nav.top.style.cursor = ''; + } + }; + + this.getEventTop = function(row, line) { + var top = this.headerHeight; + for (var i = 0; i < row; i++) { + top += this.rows[i].getHeight(); + } + top += this.cellHeaderHeight; // space on top + top += line * this.lineHeight(); + return top; + }; + + this.getDateFromCell = function(x, y) { + //return DayPilot.Date.addDays(this.firstDate, y * 7 + x); + return this.firstDate.addDays(y * 7 + x); + }; + + this._drawEvent = function(e) { + /* + + supported properties: + * cssClass + * backColor + * borderColor + * barColor + * barHidden + * fontColor + * html + * toolTip + * + * clickEnabled + */ + + var data = e.cache || e.data; + + //var ev = eventPart.event; + var row = e.part.row; + var line = e.part.line; + var colStart = e.part.colStart; + var colWidth = e.part.colWidth; + + var left = this.getCellWidth() * (colStart); + var width = this.getCellWidth() * (colWidth); + var top = this.getEventTop(row, line); + + var div = document.createElement("div"); + div.setAttribute("unselectable", "on"); + div.style.height = this.eventHeight + 'px'; + div.className = this._prefixCssClass("_event"); + + if (data.cssClass) { + DayPilot.Util.addClass(div, data.cssClass); + } + + if (!e.part.startsHere) { + DayPilot.Util.addClass(div, this._prefixCssClass("_event_continueleft")); + } + + if (!e.part.endsHere) { + DayPilot.Util.addClass(div, this._prefixCssClass("_event_continueright")); + } + + div.event = e; + + div.style.width = width + '%'; + div.style.position = 'absolute'; + div.style.left = left + '%'; + div.style.top = top + 'px'; // plus space on top + + if (this.showToolTip && e.client.toolTip()) { + div.title = e.client.toolTip(); + } + + div.onclick = calendar._eventClickDispatch; + div.oncontextmenu = calendar._onEventContextMenu; + div.onmousedown = function(ev) { + ev = ev || window.event; + var button = ev.which || ev.button; + + ev.cancelBubble = true; + if (ev.stopPropagation) { + ev.stopPropagation(); + } + + if (button === 1) { + + DayPilotMonth.movingEvent = null; + if (this.style.cursor === 'w-resize' || this.style.cursor === 'e-resize') { + var resizing = {}; + resizing.start = {}; + resizing.start.x = colStart; + resizing.start.y = row; + resizing.event = div.event; + resizing.width = DayPilot.DateUtil.daysSpan(resizing.event.start(), resizing.event.end()) + 1; + resizing.direction = this.style.cursor; + DayPilotMonth.resizingEvent = resizing; + } + else if (this.style.cursor === 'move' || e.client.moveEnabled()) { + calendar.clearShadow(); + + var coords = DayPilot.mo3(calendar.nav.top, ev); + if (!coords) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + + var hidden = DayPilot.DateUtil.daysDiff(e.start(), calendar.rows[row].start); + var offset = (cell.y * 7 + cell.x) - (row * 7 + colStart); + if (hidden) { + offset += hidden; + } + + var moving = {}; + moving.start = {}; + moving.start.x = colStart; + moving.start.y = row; + moving.start.line = line; + moving.offset = calendar.eventMoveToPosition ? 0 : offset; + moving.colWidth = colWidth; + moving.event = div.event; + moving.coords = coords; + DayPilotMonth.movingEvent = moving; + + } + + } + }; + + div.onmousemove = function(ev) { + if (typeof (DayPilotMonth) === 'undefined') { + return; + } + + if (DayPilotMonth.movingEvent || DayPilotMonth.resizingEvent) { + return; + } + + // position + var offset = DayPilot.mo3(div, ev); + if (!offset) { + return; + } + + if (div.deleteIcon) { + div.deleteIcon.style.display = ""; + } + + var resizeMargin = 6; + + if (offset.x <= resizeMargin && e.client.resizeEnabled()) { + if (e.part.startsHere) { + div.style.cursor = "w-resize"; + div.dpBorder = 'left'; + } + else { + div.style.cursor = 'not-allowed'; + } + } + else if (div.clientWidth - offset.x <= resizeMargin && e.client.resizeEnabled()) { + if (e.part.endsHere) { + div.style.cursor = "e-resize"; + div.dpBorder = 'right'; + } + else { + div.style.cursor = 'not-allowed'; + } + } + else if (e.client.clickEnabled()) { + div.style.cursor = "pointer"; + } + else { + div.style.cursor = 'default'; + } + + }; + + div.onmouseleave = function(ev) { + if (div.deleteIcon) { + div.deleteIcon.style.display = "none"; + } + div.style.cursor = ''; + }; + + div.onmouseenter = function(ev) { + if (div.deleteIcon) { + div.deleteIcon.style.display = ""; + } + }; + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = this._prefixCssClass("_event_inner"); + + if (data.borderColor === "darker" && data.backColor) { + inner.style.borderColor = DayPilot.ColorUtil.darker(data.backColor, 2); + } + else { + inner.style.borderColor = data.borderColor; + } + + if (data.backColor) { + inner.style.background = data.backColor; + } + + if (data.fontColor) { + inner.style.color = data.fontColor; + } + + + inner.innerHTML = e.client.html(); + + div.appendChild(inner); + + if (e.client.barVisible()) { + + var bar = document.createElement("div"); + bar.setAttribute("unselectable", "on"); + bar.className = this._prefixCssClass("_event_bar"); + bar.style.position = "absolute"; + + var barInner = document.createElement("div"); + barInner.setAttribute("unselectable", "on"); + barInner.className = this._prefixCssClass("_event_bar_inner"); + barInner.style.top = "0%"; + barInner.style.height = "100%"; + + if (data.barColor) { + barInner.style.backgroundColor = data.barColor; + } + + bar.appendChild(barInner); + div.appendChild(bar); + } + + + if (e.client.deleteEnabled()) { + var dheight = 18; + var dwidth = 18; + var dtop = Math.floor(calendar.eventHeight / 2 - dheight / 2); + + var del = document.createElement("div"); + del.style.position = "absolute"; + del.style.right = "2px"; + del.style.top = dtop + "px"; + del.style.width = dwidth + "px"; + del.style.height = dheight + "px"; + del.className = calendar._prefixCssClass("_event_delete"); + del.onmousedown = function(ev) { + ev.stopPropagation(); + }; + del.onclick = function(ev) { + ev.stopPropagation(); + var e = this.parentNode.event; + if (e) { + calendar._eventDeleteDispatch(e); + } + }; + del.style.display = "none"; + div.deleteIcon = del; + div.appendChild(del); + } + + // areas + var areas = data.areas ? DayPilot.Areas.copy(data.areas) : []; + DayPilot.Areas.attach(div, e, {"areas": areas}); + + if (typeof calendar.onAfterEventRender === 'function') { + var args = {}; + args.e = div.event; + args.div = div; + + calendar.onAfterEventRender(args); + } + + this.elements.events.push(div); + + this.nav.events.appendChild(div); + }; + + + // returns DayPilot.Date object + this.lastVisibleDayOfMonth = function() { + return this.startDate.lastDayOfMonth(); + }; + + this._prepareRows = function() { + + if (typeof this.startDate === 'string') { + this.startDate = new DayPilot.Date(this.startDate); + } + this.startDate = this.startDate.firstDayOfMonth(); + + this.firstDate = this.startDate.firstDayOfWeek(this.getWeekStart()); + + var firstDayOfMonth = this.startDate; + + var rowCount; + + var lastVisibleDayOfMonth = this.lastVisibleDayOfMonth(); + var count = DayPilot.DateUtil.daysDiff(this.firstDate, lastVisibleDayOfMonth) + 1; + rowCount = Math.ceil(count / 7); + + this.days = rowCount * 7; + + this.rows = []; + for (var x = 0; x < rowCount; x++) { + var r = {}; + r.start = this.firstDate.addDays( x * 7); // start point + r.end = r.start.addDays(this.getColCount()); // end point + r.events = []; // collection of events + r.lines = []; // collection of lines + r.index = x; // row index + r.minHeight = this.cellHeight; // default, can be extended during events loading + r.calendar = this; + + r.belongsHere = function(ev) { + if (ev.end().getTime() === ev.start().getTime() && ev.start().getTime() === this.start.getTime()) { + return true; + } + return !(ev.end().getTime() <= this.start.getTime() || ev.start().getTime() >= this.end.getTime()); + }; + + r.getPartStart = function(ev) { + return DayPilot.DateUtil.max(this.start, ev.start()); + }; + + r.getPartEnd = function(ev) { + return DayPilot.DateUtil.min(this.end, ev.end()); + }; + + r.getStartColumn = function(ev) { + var partStart = this.getPartStart(ev); + return DayPilot.DateUtil.daysDiff(this.start, partStart); + }; + + r.getWidth = function(ev) { + return DayPilot.DateUtil.daysSpan(this.getPartStart(ev), this.getPartEnd(ev)) + 1; + }; + + r.putIntoLine = function(ev, colStart, colWidth, row) { + var thisRow = this; + + for (var i = 0; i < this.lines.length; i++) { + var line = this.lines[i]; + if (line.isFree(colStart, colWidth)) { + line.addEvent(ev, colStart, colWidth, row, i); + return i; + } + } + + var line = []; + line.isFree = function(colStart, colWidth) { + var free = true; + + for (var i = 0; i < this.length; i++) { + if (!(colStart + colWidth - 1 < this[i].part.colStart || colStart > this[i].part.colStart + this[i].part.colWidth - 1)) { + free = false; + } + } + + return free; + }; + + line.addEvent = function(ep, colStart, colWidth, row, index) { + //var eventPart = {}; + //eventPart.event = ev; + ep.part.colStart = colStart; + ep.part.colWidth = colWidth; + ep.part.row = row; + ep.part.line = index; + ep.part.startsHere = thisRow.start.getTime() <= ep.start().getTime(); + //if (confirm('r.start: ' + thisRow.start + ' ev.Start: ' + ev.Start)) thisRow = null; + ep.part.endsHere = thisRow.end.getTime() >= ep.end().getTime(); + + this.push(ep); + }; + + line.addEvent(ev, colStart, colWidth, row, this.lines.length); + + this.lines.push(line); + + return this.lines.length - 1; + }; + + r.getStart = function() { + var start = 0; + for (var i = 0; i < calendar.rows.length && i < this.index; i++) { + start += calendar.rows[i].getHeight(); + } + }; + + r.getHeight = function() { + return Math.max(this.lines.length * calendar.lineHeight() + calendar.cellHeaderHeight + calendar.cellMarginBottom, this.calendar.cellHeight); + }; + + this.rows.push(r); + } + + //this.endDate = DayPilot.Date.addDays(this.firstDate, rowCount * 7); + this.endDate = this.firstDate.addDays(rowCount * 7); + }; + + this.visibleStart = function() { + return calendar.firstDate; + }; + + this.visibleEnd = function() { + return calendar.endDate; + }; + + this.getHeight = function() { + var height = this.headerHeight; + for (var i = 0; i < this.rows.length; i++) { + height += this.rows[i].getHeight(); + } + return height; + }; + + this.getWidth = function(start, end) { + var diff = (end.y * 7 + end.x) - (start.y * 7 + start.x); + return diff + 1; + }; + + this.getMinCoords = function(first, second) { + if ((first.y * 7 + first.x) < (second.y * 7 + second.x)) { + return first; + } + else { + return second; + } + }; + + this._prefixCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + if (prefix) { + return prefix + part; + } + else { + return ""; + } + }; + + this._drawTop = function() { + var relative = this.nav.top; + //this.nav.top = relative; + relative.setAttribute("unselectable", "on"); + relative.style.MozUserSelect = 'none'; + relative.style.KhtmlUserSelect = 'none'; + relative.style.WebkitUserSelect = 'none'; + relative.style.position = 'relative'; + if (this.width) { + relative.style.width = this.width; + } + relative.style.height = this.getHeight() + 'px'; + relative.onselectstart = function(e) { return false; }; // prevent text cursor in Chrome during drag&drop + + + if (this.hideUntilInit) { + relative.style.visibility = 'hidden'; + } + + if (!this.visible) { + relative.style.display = "none"; + } + + relative.className = this._prefixCssClass("_main"); + + var cells = document.createElement("div"); + this.nav.cells = cells; + cells.style.position = "absolute"; + cells.style.left = "0px"; + cells.style.right = "0px"; + cells.setAttribute("unselectable", "on"); + relative.appendChild(cells); + + var events = document.createElement("div"); + this.nav.events = events; + events.style.position = "absolute"; + events.style.left = "0px"; + events.style.right = "0px"; + events.setAttribute("unselectable", "on"); + relative.appendChild(events); + + relative.onmousemove = function(ev) { + + if (DayPilotMonth.resizingEvent) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + if (!coords) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + calendar.clearShadow(); + var resizing = DayPilotMonth.resizingEvent; + + var original = resizing.start; + var width, start; + + if (resizing.direction === 'w-resize') { + start = cell; + + var endDate = resizing.event.end(); + //if (DayPilot.Date.getDate(endDate).getTime() === endDate.getTime()) { + if (endDate.getDatePart() === endDate) { + endDate = endDate.addDays(-1); + } + + var end = calendar.getCellFromDate(endDate); + width = calendar.getWidth(cell, end); + } + else { + start = calendar.getCellFromDate(resizing.event.start()); + width = calendar.getWidth(start, cell); + } + + if (width < 1) { + width = 1; + } + + calendar.drawShadow(start.x, start.y, 0, width); + + } + else if (DayPilotMonth.movingEvent) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + if (!coords) { + return; + } + + // not actually moved, Chrome bug + if (coords.x === DayPilotMonth.movingEvent.coords.x && coords.y === DayPilotMonth.movingEvent.coords.y) { + return; + } + + var minDistance = 3; + var distance = Math.abs(coords.x - DayPilotMonth.movingEvent.coords.x) + Math.abs(coords.y - DayPilotMonth.movingEvent.coords.y); + if (distance <= minDistance) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + + calendar.clearShadow(); + + var event = DayPilotMonth.movingEvent.event; + var offset = DayPilotMonth.movingEvent.offset; + var width = calendar.cellMode ? 1 : DayPilot.DateUtil.daysSpan(event.start(), event.end()) + 1; + + if (width < 1) { + width = 1; + } + calendar.drawShadow(cell.x, cell.y, 0, width, offset, event); + } + else if (DayPilotMonth.timeRangeSelecting) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + if (!coords) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + + calendar.clearShadow(); + + var start = DayPilotMonth.timeRangeSelecting; + + var startIndex = start.y * 7 + start.x; + var cellIndex = cell.y * 7 + cell.x; + + var width = Math.abs(cellIndex - startIndex) + 1; + + if (width < 1) { + width = 1; + } + + var shadowStart = startIndex < cellIndex ? start : cell; + + DayPilotMonth.timeRangeSelecting.from = { x: shadowStart.x, y: shadowStart.y }; + DayPilotMonth.timeRangeSelecting.width = width; + DayPilotMonth.timeRangeSelecting.moved = true; + + calendar.drawShadow(shadowStart.x, shadowStart.y, 0, width, 0, null); + + } + + }; + + //this.nav.top.appendChild(this.vsph); + }; + + this._updateHeight = function() { + this.nav.top.style.height = this.getHeight() + 'px'; + + for (var x = 0; x < this.cells.length; x++) { + for (var y = 0; y < this.cells[x].length; y++) { + this.cells[x][y].style.top = this.getRowTop(y) + 'px'; + this.cells[x][y].style.height = this.rows[y].getHeight() + 'px'; + } + } + }; + + this.getCellBelowPoint = function(x, y) { + var columnWidth = Math.floor(this.nav.top.clientWidth / this.getColCount()); + var column = Math.min(Math.floor(x / columnWidth), this.getColCount() - 1); + + var row = null; + + var height = this.headerHeight; + var relativeY = 0; + for (var i = 0; i < this.rows.length; i++) { + var baseHeight = height; + height += this.rows[i].getHeight(); + if (y < height) { + relativeY = y - baseHeight; + row = i; + break; + } + } + if (row === null) { + row = this.rows.length - 1; // might be a pixel below the last line + } + + var cell = {}; + cell.x = column; + cell.y = row; + cell.relativeY = relativeY; + + return cell; + }; + + this.getCellFromDate = function(date) { + var width = DayPilot.DateUtil.daysDiff(this.firstDate, date); + var cell = { x: 0, y: 0 }; + while (width >= 7) { + cell.y++; + width -= 7; + } + cell.x = width; + return cell; + }; + + this._drawTable = function() { + + var table = document.createElement("div"); + table.oncontextmenu = function() { return false; }; + this.nav.cells.appendChild(table); + + this.cells = []; + + for (var x = 0; x < this.getColCount(); x++) { + + this.cells[x] = []; + var headerProperties = null; + + var header = document.createElement("div"); + header.setAttribute("unselectable", "on"); + header.style.position = 'absolute'; + + header.style.left = (this.getCellWidth() * x) + '%'; + header.style.width = (this.getCellWidth()) + '%'; + header.style.top = '0px'; + header.style.height = (this.headerHeight) + 'px'; + + var dayIndex = x + this.getWeekStart(); + if (dayIndex > 6) { + dayIndex -= 7; + } + + header.className = this._prefixCssClass("_header"); + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.innerHTML = resolved.locale().dayNames[dayIndex]; + + header.appendChild(inner); + + inner.style.position = "absolute"; + inner.style.top = "0px"; + inner.style.bottom = "0px"; + inner.style.left = "0px"; + inner.style.right = "0px"; + inner.className = this._prefixCssClass("_header_inner"); + + inner.innerHTML = resolved.locale().dayNames[dayIndex]; + + table.appendChild(header); + + for (var y = 0; y < this.rows.length; y++) { + this._drawCell(x, y, table); + } + + } + + }; + + this._clearTable = function() { + + // clear event handlers + for (var x = 0; x < this.cells.length; x++) { + for (var y = 0; y < this.cells[x].length; y++) { + this.cells[x][y].onclick = null; + } + } + + this.nav.cells.innerHTML = ''; + + }; + + this._api2 = function() { + return calendar.api === 2; + }; + this._drawCell = function(x, y, table) { + + var row = this.rows[y]; + var d = this.firstDate.addDays(y * 7 + x); + + var date = d.getDay(); + var headerHtml = null; + if (date === 1) { + headerHtml = resolved.locale().monthNames[d.getMonth()] + ' ' + date; + } + else { + headerHtml = "" + date; + } + var business = !calendar.isWeekend(d); + + var args = {}; + args.control = calendar; + args.cell = {}; + args.cell.start = d; + args.cell.end = d.addDays(1); + args.cell.properties = { + "headerHtml": headerHtml, + "backColor": null, + "business": business, + "html": null + }; + if (typeof calendar.onBeforeCellRender === "function") { + calendar.onBeforeCellRender(args); + } + + var props = args.cell.properties; + + var cell = document.createElement("div"); + cell.setAttribute("unselectable", "on"); + cell.style.position = 'absolute'; + cell.style.cursor = 'default'; + cell.style.left = (this.getCellWidth() * x) + '%'; + cell.style.width = (this.getCellWidth()) + '%'; + cell.style.top = (this.getRowTop(y)) + 'px'; + cell.style.height = (row.getHeight()) + 'px'; + cell.className = this._prefixCssClass("_cell"); + + if (props.business) { + var business = this._prefixCssClass("_cell_business"); + DayPilot.Util.addClass(cell, business); + } + + var previousMonth = this.startDate.addMonths(-1).getMonth(); + var nextMonth = this.startDate.addMonths(1).getMonth(); + + var thisMonth = this.startDate.getMonth(); + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + cell.appendChild(inner); + + inner.style.position = "absolute"; + inner.style.left = "0px"; + inner.style.right = "0px"; + inner.style.top = "0px"; + inner.style.bottom = "0px"; + inner.className = this._prefixCssClass("_cell_inner"); + + if (props.backColor) { + inner.style.backgroundColor = args.cell.properties.backColor; + } + + cell.onmousedown = function(e) { + if (calendar.timeRangeSelectedHandling !== 'Disabled') { + calendar.clearShadow(); + DayPilotMonth.timeRangeSelecting = { "root": calendar, "x": x, "y": y, "from": { x: x, y: y }, "width": 1 }; + } + }; + + cell.onclick = function() { + + var single = function(d) { + var start = new DayPilot.Date(d); + var end = start.addDays(1); + calendar._timeRangeSelectedDispatch(start, end); + }; + + if (calendar.timeRangeSelectedHandling !== 'Disabled') { + single(d); + return; + } + + }; + + var day = document.createElement("div"); + day.setAttribute("unselectable", "on"); + day.style.height = this.cellHeaderHeight + "px"; + day.className = this._prefixCssClass("_cell_header"); + + day.onclick = function(ev) { + + if (calendar.cellHeaderClickHandling !== "Enabled") { + return; + } + + ev.stopPropagation(); + + var args = {}; + args.control = calendar; + args.start = d; + args.end = d.addDays(1); + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onCellHeaderClick === "function") { + calendar.onCellHeaderClick(args); + if (args.preventDefault.value) { + return; + } + } + + if (typeof calendar.onCellHeaderClicked === "function") { + calendar.onCellHeaderClicked(args); + } + + }; + + day.innerHTML = props.headerHtml; + + inner.appendChild(day); + + if (props.html) { + var html = document.createElement("div"); + html.style.height = (row.getHeight() - this.cellHeaderHeight) + 'px'; + html.style.overflow = 'hidden'; + html.innerHTML = props.html; + inner.appendChild(html); + } + + this.cells[x][y] = cell; + + table.appendChild(cell); + }; + + this.getWeekStart = function() { + if (calendar.weekStarts === 'Auto') { + var locale = resolved.locale(); + if (locale) { + return locale.weekStarts; + } + else { + return 0; // Sunday + } + } + else { + return calendar.weekStarts || 0; + } + return resolved.locale().weekStarts; + }; + + this.getColCount = function() { + return 7; + }; + + this.getCellWidth = function() { + return 14.285; + }; + + this.getRowTop = function(index) { + var top = this.headerHeight; + for (var i = 0; i < index; i++) { + top += this.rows[i].getHeight(); + } + return top; + }; + + this._callBack2 = function(action, data, parameters) { + + var envelope = {}; + + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); + + if (this.backendUrl) { + DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this.ajaxError); + } + }; + + this._callBackResponse = function(response) { + calendar._updateView(response.responseText); + }; + + this._getCallBackHeader = function() { + var h = {}; + h.control = "dpm"; + h.id = this.id; + h.v = this.v; + + h.visibleStart = new DayPilot.Date(this.firstDate); + h.visibleEnd = h.visibleStart.addDays(this.days); + + h.startDate = calendar.startDate; + // h.headerBackColor = this.headerBackColor; + // h.backColor = this.backColor; + // h.nonBusinessBackColor = this.nonBusinessBackColor; + h.timeFormat = this.timeFormat; + h.weekStarts = this.weekStarts; + + return h; + }; + + this.eventClickCallBack = function(e, data) { + this._callBack2('EventClick', data, e); + }; + + this._eventClickDispatch = function(e) { + + DayPilotMonth.movingEvent = null; + DayPilotMonth.resizingEvent = null; + + var div = this; + + var e = e || window.event; + var ctrlKey = e.ctrlKey; + + e.cancelBubble = true; + if (e.stopPropagation) { + e.stopPropagation(); + } + + calendar.eventClickSingle(div, e); + }; + + + this.eventClickSingle = function(div, ev) { + var e = div.event; + if (!e) { + return; + } + if (!e.client.clickEnabled()) { + return; + } + + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.control = calendar; + args.div = div; + args.originalEvent = ev; + args.meta = ev.metaKey; + args.ctrl = ev.ctrlKey; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventClick === 'function') { + calendar._angular.apply(function() { + calendar.onEventClick(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventClickHandling) { + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(e); + } + } + break; } + + if (typeof calendar.onEventClicked === 'function') { + calendar._angular.apply(function() { + calendar.onEventClicked(args); + }); + } + } + else { + switch (calendar.eventClickHandling) { + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'JavaScript': + calendar.onEventClick(e); + break; + } + } + }; + + this._onEventContextMenu = function() { + var e = this; + calendar._eventRightClickDispatch(e.event); + return false; + }; + + this._eventRightClickDispatch = function(e) { + + this.event = e; + + if (!e.client.rightClickEnabled()) { + return false; + } + + var args = {}; + args.e = e; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventRightClick === 'function') { + calendar.onEventRightClick(args); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventRightClickHandling) { + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(this.event); + } + } + break; + } + + if (typeof calendar.onEventRightClicked === 'function') { + calendar.onEventRightClicked(args); + } + + + return false; + }; + + + this._eventDeleteDispatch = function (e) { + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventDelete === 'function') { + calendar._angular.apply(function() { + calendar.onEventDelete(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventDeleteHandling) { + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'Update': + calendar.events.remove(e); + break; + } + + if (typeof calendar.onEventDeleted === 'function') { + calendar._angular.apply(function() { + calendar.onEventDeleted(args); + }); + } + } + else { + switch (calendar.eventDeleteHandling) { + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'JavaScript': + calendar.onEventDelete(e); + break; + } + } + + }; + + this.eventDeleteCallBack = function(e, data) { + this._callBack2('EventDelete', data, e); + }; + + this.eventDeletePostBack = function(e, data) { + this._postBack2('EventDelete', data, e); + }; + + this.eventMoveCallBack = function(e, newStart, newEnd, data, position) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + params.position = position; + + this._callBack2('EventMove', data, params); + }; + + this._eventMoveDispatch = function(e, x, y, offset, ev, position) { + + var startOffset = e.start().getTimePart(); + + var endDate = e.end().getDatePart(); + if (endDate.getTime() !== e.end().getTime()) { + endDate = endDate.addDays(1); + } + var endOffset = DayPilot.DateUtil.diff(e.end(), endDate); + + var boxStart = this.getDateFromCell(x, y); + boxStart = boxStart.addDays(-offset); + var width = DayPilot.DateUtil.daysSpan(e.start(), e.end()) + 1; + + var boxEnd = boxStart.addDays(width); + + var newStart = boxStart.addTime(startOffset); + var newEnd = boxEnd.addTime(endOffset); + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.control = calendar; + args.newStart = newStart; + args.newEnd = newEnd; + args.ctrl = ev.ctrlKey; + args.shift = ev.shiftKey; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventMove === 'function') { + calendar._angular.apply(function() { + calendar.onEventMove(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventMoveHandling) { + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventMoved === 'function') { + calendar._angular.apply(function() { + calendar.onEventMoved(args); + }); + } + } + else { + switch (calendar.eventMoveHandling) { + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd); + break; + case 'JavaScript': + calendar.onEventMove(e, newStart, newEnd); + break; + } + } + }; + + this.eventResizeCallBack = function(e, newStart, newEnd, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._callBack2('EventResize', data, params); + }; + + this._eventResizeDispatch = function(e, start, width) { + var startOffset = e.start().getTimePart(); + + var endDate = e.end().getDatePart(); + if (endDate.getTime() !== e.end().getTime()) { + endDate = endDate.addDays(1); + } + var endOffset = DayPilot.DateUtil.diff(e.end(), endDate); + + var boxStart = this.getDateFromCell(start.x, start.y); + //var width = DayPilot.Date.daysSpan(e.start(), e.end()) + 1; + var boxEnd = boxStart.addDays(width); + + var newStart = boxStart.addTime(startOffset); + var newEnd = boxEnd.addTime(endOffset); + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.control = calendar; + args.newStart = newStart; + args.newEnd = newEnd; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventResize === 'function') { + calendar._angular.apply(function() { + calendar.onEventResize(args); + }); + + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventResizeHandling) { + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventResized === 'function') { + calendar._angular.apply(function() { + calendar.onEventResized(args); + }); + } + } + else { + switch (calendar.eventResizeHandling) { + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'JavaScript': + calendar.onEventResize(e, newStart, newEnd); + break; + } + } + + }; + + + this.timeRangeSelectedCallBack = function(start, end, data) { + + var range = {}; + range.start = start; + range.end = end; + + this._callBack2('TimeRangeSelected', data, range); + }; + + this._timeRangeSelectedDispatch = function(start, end) { + if (this._api2()) { + var args = {}; + args.control = calendar; + args.start = start; + args.end = end; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onTimeRangeSelect === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelect(args); + }); + + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (calendar.timeRangeSelectedHandling) { + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + } + + if (typeof calendar.onTimeRangeSelected === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelected(args); + }); + } + } + else { + switch (calendar.timeRangeSelectedHandling) { + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + case 'JavaScript': + calendar.onTimeRangeSelected(start, end); + break; + } + } + }; + + this._angular = {}; + this._angular.scope = null; + this._angular.notify = function() { + if (calendar._angular.scope) { + calendar._angular.scope["$apply"](); + } + }; + this._angular.apply = function(f) { + f(); + + /* + if (calendar.angularAutoApply && calendar._angular.scope) { + calendar._angular.scope["$apply"](f); + } + else { + f(); + }*/ + }; + + this.clearSelection = function() { + calendar.clearShadow(); + }; + + this.commandCallBack = function(command, data) { + + var params = {}; + params.command = command; + + this._callBack2('Command', data, params); + }; + + this.isWeekend = function(date) { + date = new DayPilot.Date(date); + + var sunday = 0; + var saturday = 6; + + if (date.dayOfWeek() === sunday) { + return true; + } + if (date.dayOfWeek() === saturday) { + return true; + } + return false; + }; + + this._resolved = {}; + this._resolved.locale = function() { + var found = DayPilot.Locale.find(calendar.locale); + if (!found) { + return DayPilot.Locale.US; + } + return found; + }; + + this._resolved._xssProtectionEnabled = function() { + return calendar.xssProtection !== "Disabled"; + }; + + + var resolved = this._resolved; + + this.debug = function(msg, append) { + if (!this.debuggingEnabled) { + return; + } + + if (!calendar.debugMessages) { + calendar.debugMessages = []; + } + calendar.debugMessages.push(msg); + + if (typeof console !== 'undefined') { + console.log(msg); + } + }; + + this.dispose = function() { + var c = calendar; + + if (c._disposed) { + return; + } + c._disposed = true; + + c._deleteEvents(); + + c.nav.top.removeAttribute("style"); + c.nav.top.removeAttribute("class"); + c.nav.top.innerHTML = ''; + c.nav.top.dp = null; + + c.nav.top.onmousemove = null; + c.nav.top = null; + + }; + + this.disposed = function() { + return this._disposed; + }; + + this._registerGlobalHandlers = function() { + if (!DayPilotMonth.globalHandlers) { + DayPilotMonth.globalHandlers = true; + DayPilot.re(document, 'mouseup', DayPilotMonth.gMouseUp); + } + }; + + this.loadFromServer = function() { + // make sure it has a place to ask + if (this.backendUrl || typeof WebForm_DoCallback === 'function') { + return (typeof calendar.events.list === 'undefined') || (!calendar.events.list); + } + else { + return false; + } + + }; + + this._show = function() { + if (this.nav.top.style.visibility === 'hidden') { + this.nav.top.style.visibility = 'visible'; + } + }; + + this.show = function() { + calendar.visible = true; + calendar.nav.top.style.display = ''; + }; + + this.hide = function() { + calendar.visible = false; + calendar.nav.top.style.display = 'none'; + }; + + this._loadTop = function() { + if (this.id && this.id.tagName) { + this.nav.top = this.id; + } + else if (typeof this.id === "string") { + this.nav.top = document.getElementById(this.id); + if (!this.nav.top) { + throw "DayPilot.Month: The placeholder element not found: '" + id + "'."; + } + } + else { + throw "DayPilot.Month() constructor requires the target element or its ID as a parameter"; + } + }; + + this._initShort = function() { + + this._prepareRows(); + this._drawTop(); + this._drawTable(); + this._registerGlobalHandlers(); + this._callBack2('Init'); // load events + }; + + this._xssTextHtml = function(text, html) { + + if (calendar._resolved._xssProtectionEnabled()) { + return DayPilot.Util.escapeTextHtml(text, html); + } + + if (!DayPilot.Util.isNullOrUndefined(html)) { + return html; + } + if (DayPilot.Util.isNullOrUndefined(text)) { + return ""; + } + return text; + }; + + this.internal = {}; + this.internal.loadOptions = this._loadOptions; + this.internal.xssTextHtml = calendar._xssTextHtml; + + this.init = function() { + this._loadTop(); + + var loadFromServer = this.loadFromServer(); + + if (loadFromServer) { + this._initShort(); + return; + } + + this._prepareRows(); + this._loadEvents(); + this._drawTop(); + this._drawTable(); + this._show(); + this._drawEvents(); + + this._registerGlobalHandlers(); + + this.fireAfterRenderDetached(null, false); + + this._initialized = true; + + return this; + }; + + this.Init = this.init; + + // API compatibility (common) + Object.defineProperty(this, 'durationBarVisible', { get: function() { return calendar.eventBarVisible; } }); + + this._loadOptions(options); + }; + + DayPilotMonth.gMouseUp = function(ev) { + + if (DayPilotMonth.movingEvent) { + var src = DayPilotMonth.movingEvent; + + if (!src.event) { + return; + } + if (!src.event.calendar) { + return; + } + if (!src.event.calendar.shadow) { + return; + } + if (!src.event.calendar.shadow.start) { + return; + } + + // load ref + var calendar = DayPilotMonth.movingEvent.event.calendar; + var e = DayPilotMonth.movingEvent.event; + var start = calendar.shadow.start; + var position = calendar.shadow.position; + var offset = DayPilotMonth.movingEvent.offset; + + // cleanup + calendar.clearShadow(); + DayPilotMonth.movingEvent = null; + + var ev = ev || window.event; + + // fire the event + calendar._eventMoveDispatch(e, start.x, start.y, offset, ev, position); + + ev.cancelBubble = true; + if (ev.stopPropagation) { + ev.stopPropagation(); + } + DayPilotMonth.movingEvent = null; + return false; + } + else if (DayPilotMonth.resizingEvent) { + var src = DayPilotMonth.resizingEvent; + + if (!src.event) { + return; + } + if (!src.event.calendar) { + return; + } + if (!src.event.calendar.shadow) { + return; + } + if (!src.event.calendar.shadow.start) { + return; + } + + // load ref + var calendar = DayPilotMonth.resizingEvent.event.calendar; + + var e = DayPilotMonth.resizingEvent.event; + var start = calendar.shadow.start; + var width = calendar.shadow.width; + + // cleanup + calendar.clearShadow(); + DayPilotMonth.resizingEvent = null; + + // fire the event + calendar._eventResizeDispatch(e, start, width); + + ev.cancelBubble = true; + DayPilotMonth.resizingEvent = null; + return false; + } + else if (DayPilotMonth.timeRangeSelecting) { + if (DayPilotMonth.timeRangeSelecting.moved) { + var sel = DayPilotMonth.timeRangeSelecting; + var calendar = sel.root; + + var start = new DayPilot.Date(calendar.getDateFromCell(sel.from.x, sel.from.y)); + var end = start.addDays(sel.width); + calendar._timeRangeSelectedDispatch(start, end); + + calendar.clearShadow(); + } + DayPilotMonth.timeRangeSelecting = null; + } + }; + + // publish the API + + // current + DayPilot.Month = DayPilotMonth.Month; + + // experimental jQuery bindings + if (typeof jQuery !== 'undefined') { + (function($) { + $.fn.daypilotMonth = function(options) { + var first = null; + var j = this.each(function() { + if (this.daypilot) { // already initialized + return; + }; + + var daypilot = new DayPilot.Month(this.id); + this.daypilot = daypilot; + for (name in options) { + daypilot[name] = options[name]; + } + daypilot.Init(); + if (!first) { + first = daypilot; + } + }); + if (this.length === 1) { + return first; + } + else { + return j; + } + }; + })(jQuery); + } + + (function registerAngularModule() { + + var app = DayPilot.am(); + + if (!app) { + return; + } + + app.directive("daypilotMonth", ['$parse', function($parse) { + return { + "restrict": "E", + "template": "
", + "replace": true, + "link": function (scope, element, attrs) { + + var calendar = new DayPilot.Month(element[0]); + calendar._angular.scope = scope; + calendar.init(); + + var oattr = attrs["id"]; + if (oattr) { + scope[oattr] = calendar; + } + + // save DayPilot.Calendar object in the specified variable + var pas = attrs["publishAs"]; + if (pas) { + var getter = $parse(pas); + var setter = getter.assign; + setter(scope, calendar); + } + + // bind event handlers from attributes starting with "on" + for (var name in attrs) { + if (name.indexOf("on") === 0) { // event handler + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + scope["$apply"](function() { + f(scope, {"args": args}); + }); + }; + })(name); + } + } + + var watch = scope["$watch"]; + var config = attrs["config"] || attrs["daypilotConfig"]; + var events = attrs["events"] || attrs["daypilotEvents"]; + + //var watch = scope["$watch"]; + + watch.call(scope, config, function (value) { + for (var name in value) { + calendar[name] = value[name]; + } + calendar.update(); + }, true); + + watch.call(scope, events, function(value) { + calendar.events.list = value; + calendar.update(); + }, true); + + } + }; + }]); + })(); + + + if (typeof Sys !== 'undefined' && Sys.Application && Sys.Application.notifyScriptLoaded) { + Sys.Application.notifyScriptLoaded(); + } + + +})(); +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function() { + + if (typeof DayPilot.Navigator !== 'undefined' && DayPilot.Navigator.nav) { + return; + } + + var DayPilotNavigator = {}; + DayPilot.Navigator = function(id, options) { + this.v = '2024.3.539-lite'; + var calendar = this; + this.id = id; + this.api = 2; + this.isNavigator = true; + + this.autoFocusOnClick = true; + this.weekStarts = 'Auto'; // 0 = Sunday, 1 = Monday, ... 'Auto' = according to locale + this.selectMode = 'Day'; // day/week/month/none + this.titleHeight = 30; + this.dayHeaderHeight = 30; + this.bound = null; + this.cellWidth = 30; + this.cellHeight = 30; + this.cssClassPrefix = "navigator_default"; + this.freeHandSelectionEnabled = false; + this.selectionStart = new DayPilot.Date().getDatePart(); // today + this.selectionEnd = null; + this.selectionDay = null; + this.showMonths = 1; + this.skipMonths = 1; + this.command = "navigate"; + this.year = new DayPilot.Date().getYear(); + this.month = new DayPilot.Date().getMonth() + 1; + this.showWeekNumbers = false; + this.weekNumberAlgorithm = 'Auto'; + this.rowsPerMonth = 'Six'; // Six, Auto + this.orientation = "Vertical"; + this.locale = "en-us"; + this.rtl = false; + this.visible = true; + + this.timeRangeSelectedHandling = "Bind"; + this.visibleRangeChangedHandling = "Enabled"; + + this.onVisibleRangeChange = null; + this.onVisibleRangeChanged = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + + this.nav = {}; + + this._cache = {}; + + this._prepare = function() { + + this.root.dp = this; + + this.root.className = this._prefixCssClass('_main'); + + if (this.orientation === "Horizontal") { + this.root.style.width = this.showMonths * (resolved.cellWidth() * 7 + this._weekNumberWidth()) + 'px'; + this.root.style.height = (this.cellHeight*6 + this.titleHeight + this.dayHeaderHeight) + 'px'; + } + else { + this.root.style.width = (resolved.cellWidth() * 7 + this._weekNumberWidth()) + 'px'; + } + //this.root.style.height = (this.showMonths*(this.cellHeight*6 + this.titleHeight + this.dayHeaderHeight)) + 'px'; + + if (this.rtl) { + this.root.style.direction = "rtl"; + } + + this.root.style.position = "relative"; + + if (!this.visible) { + this.root.style.display = "none"; + } + + var vsph = document.createElement("input"); + vsph.type = 'hidden'; + vsph.name = calendar.id + "_state"; + vsph.id = vsph.name; + //vsph.value = result.VsUpdate; + this.root.appendChild(vsph); + this.state = vsph; + + if (!this.startDate) { + this.startDate = DayPilot.Date.fromYearMonthDay(this.year, this.month); + } + else { // make sure it's the first day + this.startDate = new DayPilot.Date(this.startDate).firstDayOfMonth(); + } + + this.calendars = []; + this.selected = []; + this.months = []; + }; + + this._api2 = function() { + return calendar.api === 2; + }; + + this._clearTable = function() { + // TODO do something smarter here + this.root.innerHTML = ''; + }; + + this._prefixCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + if (prefix) { + return prefix + part; + } + else { + return ""; + } + }; + + this._addClass = function(object, name) { + var fullName = this._prefixCssClass("_" + name); + DayPilot.Util.addClass(object, fullName); + }; + + this._removeClass = function(object, name) { + var fullName = this._prefixCssClass("_" + name); + DayPilot.Util.removeClass(object, fullName); + }; + + this._drawTable = function(j, showLinks) { + var month = {}; + month.cells = []; + month.days = []; + month.weeks = []; + + var startDate = this.startDate.addMonths(j); + + var showBefore = showLinks.before; + var showAfter = showLinks.after; + + var firstOfMonth = startDate.firstDayOfMonth(); + var first = firstOfMonth.firstDayOfWeek(resolved.weekStarts()); + + var last = firstOfMonth.addMonths(1); + var days = DayPilot.DateUtil.daysDiff(first, last); + + var rowCount = (this.rowsPerMonth === "Auto") ? Math.ceil(days / 7) : 6; + month.rowCount = rowCount; + var today = (new DayPilot.Date()).getDatePart(); + + var width = resolved.cellWidth() * 7 + this._weekNumberWidth(); + month.width = width; + var height = this.cellHeight * rowCount + this.titleHeight + this.dayHeaderHeight; + month.height = height; + + var main = document.createElement("div"); + main.style.width = (width) + 'px'; + main.style.height = (height) + 'px'; + + + if (this.orientation === "Horizontal") { + main.style.position = "absolute"; + main.style.left = (width * j) + "px"; + main.style.top = "0px"; + + month.top = 0; + month.left = width * j; + } + else { + main.style.position = 'relative'; + + var above = j > 0 ? calendar.months[j - 1].top + calendar.months[j - 1].height : 0; + month.top = above; + + month.left = 0; + } + + main.className = this._prefixCssClass('_month'); + main.style.cursor = 'default'; + main.style.MozUserSelect = 'none'; + main.style.KhtmlUserSelect = 'none'; + main.style.WebkitUserSelect = 'none'; + + main.month = month; + + this.root.appendChild(main); + + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + + // title left + var tl = document.createElement("div"); + tl.style.position = 'absolute'; + tl.style.left = '0px'; + tl.style.right = '0px'; // rtl + tl.style.top = '0px'; + tl.style.width = resolved.cellWidth() + 'px'; + tl.style.height = this.titleHeight + 'px'; + tl.style.lineHeight = this.titleHeight + 'px'; + //tl.style.textAlign = 'left'; + tl.setAttribute("unselectable", "on"); + tl.className = this._prefixCssClass('_titleleft'); + if (showLinks.left) { + tl.style.cursor = 'pointer'; + tl.innerHTML = "<"; + tl.onclick = this._clickLeft; + } + main.appendChild(tl); + this.tl = tl; + + // title center + var ti = document.createElement("div"); + ti.style.position = 'absolute'; + ti.style.left = resolved.cellWidth() + 'px'; + ti.style.top = '0px'; + ti.style.width = (resolved.cellWidth() * 5 + this._weekNumberWidth()) + 'px'; + ti.style.height = this.titleHeight + 'px'; + ti.style.lineHeight = this.titleHeight + 'px'; + //ti.style.textAlign = 'center'; + ti.setAttribute("unselectable", "on"); + ti.className = this._prefixCssClass('_title'); + ti.innerHTML = resolved.locale().monthNames[startDate.getMonth()] + ' ' + startDate.getYear(); + main.appendChild(ti); + this.ti = ti; + + // title right + var tr = document.createElement("div"); + tr.style.position = 'absolute'; + tr.style.left = (resolved.cellWidth() * 6 + this._weekNumberWidth()) + 'px'; + tr.style.right = (resolved.cellWidth() * 6 + this._weekNumberWidth()) + 'px'; // rtl + tr.style.top = '0px'; + tr.style.width = resolved.cellWidth() + 'px'; + tr.style.height = this.titleHeight + 'px'; + tr.style.lineHeight = this.titleHeight + 'px'; + //tr.style.textAlign = 'right'; + tr.setAttribute("unselectable", "on"); + tr.className = this._prefixCssClass('_titleright'); + if (showLinks.right) { + tr.style.cursor = 'pointer'; + tr.innerHTML = ">"; + tr.onclick = this._clickRight; + } + main.appendChild(tr); + this.tr = tr; + + + var xOffset = this._weekNumberWidth(); + if (this.showWeekNumbers) { + for (var y = 0; y < rowCount; y++) { + var day = first.addDays(y * 7); + var weekNumber = null; + switch (this.weekNumberAlgorithm) { + case "Auto": + weekNumber = (resolved.weekStarts() === 1) ? day.weekNumberISO() : day.weekNumber(); + break; + case "US": + weekNumber = day.weekNumber(); + break; + case "ISO8601": + weekNumber = day.weekNumberISO(); + break; + default: + throw "Unknown weekNumberAlgorithm value."; + } + + var dh = document.createElement("div"); + dh.style.position = 'absolute'; + dh.style.left = (0) + 'px'; + dh.style.right = (0) + 'px'; + dh.style.top = (y * this.cellHeight + totalHeaderHeight) + 'px'; + dh.style.width = resolved.cellWidth() + 'px'; + dh.style.height = this.cellHeight + 'px'; + dh.style.lineHeight = this.cellHeight + 'px'; + //dh.style.textAlign = 'right'; + dh.setAttribute("unselectable", "on"); + dh.className = this._prefixCssClass('_weeknumber'); + //dh.innerHTML = "" + weekNumber + ""; + dh.innerHTML = "" + weekNumber + ""; + main.appendChild(dh); + month.weeks.push(dh); + } + } + + + for (var x = 0; x < 7; x++) { + month.cells[x] = []; + + // day header + var dh = document.createElement("div"); + dh.style.position = 'absolute'; + dh.style.left = (x * resolved.cellWidth() + xOffset) + 'px'; + dh.style.right = (x * resolved.cellWidth() + xOffset) + 'px'; // rtl + dh.style.top = this.titleHeight + 'px'; + dh.style.width = resolved.cellWidth() + 'px'; + dh.style.height = this.dayHeaderHeight + 'px'; + dh.style.lineHeight = this.dayHeaderHeight + 'px'; + //dh.style.textAlign = 'right'; + dh.setAttribute("unselectable", "on"); + dh.className = this._prefixCssClass('_dayheader'); + dh.innerHTML = "" + this._getDayName(x) + ""; + main.appendChild(dh); + month.days.push(dh); + + for (var y = 0; y < rowCount; y++) { + var day = first.addDays(y * 7 + x); + + var isSelected = this._isSelected(day) && this._selectModeLowerCase() !== 'none'; + var isCurrentMonth = day.firstDayOfMonth() === startDate; + var isPrevMonth = day < startDate; + var isNextMonth = day >= startDate.addMonths(1); + + if (this._selectModeLowerCase() === "month") { + isSelected = isSelected && isCurrentMonth; + } + else if (this._selectModeLowerCase() === "day") { + isSelected = isSelected && (isCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)); + } + else if (this._selectModeLowerCase() === "week") { + //var sd = this.selectionDay || this.selectionStart; + var isSelectionCurrentMonth = day.firstDayOfMonth() === startDate; + isSelected = isSelected && (isSelectionCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)); + } + + var dc = document.createElement("div"); + month.cells[x][y] = dc; + + var cellPos = calendar._cellRelativeCoords(x, y); + var left = cellPos.x; + var top = cellPos.y; + + dc.day = day; + dc.x = x; + dc.y = y; + dc.left = left; + dc.top = top; + dc.isCurrentMonth = isCurrentMonth; + dc.isNextMonth = isNextMonth; + dc.isPrevMonth = isPrevMonth; + dc.showBefore = showBefore; + dc.showAfter = showAfter; + dc.className = this._prefixCssClass((isCurrentMonth ? '_day' : '_dayother')); + calendar._addClass(dc, "cell"); + if (day.getTime() === today.getTime() && isCurrentMonth) { + this._addClass(dc, 'today'); + } + if (day.dayOfWeek() === 0 || day.dayOfWeek() === 6) { + this._addClass(dc, 'weekend'); + } + + dc.style.position = 'absolute'; + dc.style.left = (left) + 'px'; + dc.style.right = (left) + 'px'; // rtl + dc.style.top = (top) + 'px'; + dc.style.width = resolved.cellWidth() + 'px'; + dc.style.height = this.cellHeight + 'px'; + dc.style.lineHeight = this.cellHeight + 'px'; // vertical alignment + //dc.style.textAlign = 'right'; + //dc.style.border = '1px solid white'; + + var inner = document.createElement("div"); + inner.style.position = 'absolute'; + inner.className = (day.getTime() === today.getTime() && isCurrentMonth) ? this._prefixCssClass('_todaybox') : this._prefixCssClass('_daybox'); + calendar._addClass(inner, "cell_box"); + //inner.style.boxSizing = "border-box"; + inner.style.left = '0px'; + inner.style.top = '0px'; + inner.style.right = '0px'; + inner.style.bottom = '0px'; + //inner.style.width = (this.cellWidth - 2) + 'px'; + //inner.style.height = (this.cellHeight - 2) + 'px'; + dc.appendChild(inner); + + /* + if (isCurrentMonth) { + dc.style.cursor = 'pointer'; + } + */ + + var cell = null; + if (this.cells && this.cells[day.toStringSortable()]) { + cell = this.cells[day.toStringSortable()]; + } + + if (typeof calendar.onBeforeCellRender === "function") { + var args = {}; + args.cell = cell || {}; + args.cell.day = day; + args.cell.isCurrentMonth = isCurrentMonth; + args.cell.isToday = day.getTime() === today.getTime() && isCurrentMonth; + args.cell.isWeekend = day.dayOfWeek() === 0 || day.dayOfWeek() === 6; + if (cell) { + args.cell.html = cell.html || day.getDay(); + args.cell.cssClass = cell.css; + } + else { + args.cell.html = day.getDay(); + args.cell.cssClass = null; + } + + calendar.onBeforeCellRender(args); + + cell = args.cell; + } + + if (cell) { + DayPilot.Util.addClass(dc, cell.cssClass || cell.css); + } + + //var span = null; + if (isCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)) { + var text = document.createElement("div"); + text.innerHTML = day.getDay(); + text.style.position = "absolute"; + text.style.left = '0px'; + text.style.top = '0px'; + text.style.right = '0px'; + text.style.bottom = '0px'; + calendar._addClass(text, "cell_text"); + + // dc.style.cursor = 'pointer'; + dc.isClickable = true; + + if (cell && cell.html) { + text.innerHTML = cell.html; + } + + dc.appendChild(text); + } + + + dc.setAttribute("unselectable", "on"); + + dc.onclick = this._cellClick; + + main.appendChild(dc); + + if (isSelected) { + calendar._cellSelect(main, x, y); + this.selected.push(dc); + } + + } + } + + var line = document.createElement("div"); + line.style.position = 'absolute'; + line.style.left = '0px'; + line.style.top = (totalHeaderHeight - 2) + 'px'; + line.style.width = (resolved.cellWidth() * 7 + this._weekNumberWidth()) + 'px'; + line.style.height = '1px'; + line.style.fontSize = '1px'; + line.style.lineHeight = '1px'; + line.className = this._prefixCssClass("_line"); + + main.appendChild(line); + this.months.push(month); + }; + + this._cellRelativeCoords = function(x, y) { + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + var xOffset = this._weekNumberWidth(); + var left = x * resolved.cellWidth() + xOffset; + var top = y * this.cellHeight + totalHeaderHeight; + + return { + "x": left, + "y": top + }; + + }; + + this._cellSelect = function(main, x, y) { + var div = main.month.cells[x][y]; + + calendar._addClass(div, 'select'); + + /* + if (div.selectDiv) { + return; + } + + var xOffset = this._weekNumberWidth(); + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + + // overlay select + var od = document.createElement("div"); + od.style.position = 'absolute'; + od.style.left = (x * this.cellWidth + xOffset) + 'px'; + od.style.top = (y * this.cellHeight + totalHeaderHeight) + 'px'; + od.style.width = this.cellWidth + 'px'; + od.style.height = this.cellHeight + 'px'; + od.className = calendar._prefixCssClass("_selected_overlay"); + + div.selectDiv = od; + + main.appendChild(od); + */ + }; + + this._cellUnselect = function(main, x, y) { + var div = main.month.cells[x][y]; + + calendar._removeClass(div, 'select'); + + /* + DayPilot.de(div.selectDiv); + div.selectDiv = null; + */ + }; + + this._weekNumberWidth = function() { + if (this.showWeekNumbers) { + return resolved.cellWidth(); + } + return 0; + }; + + this._updateFreeBusy = function() { + if (!this.items) { + return; + } + + for (var j = 0; j < this.showMonths; j++) { + for (var x = 0; x < 7; x++) { + for (var y = 0; y < 6; y++) { + var cell = this.months[j].cells[x][y]; + if (!cell) { + continue; + } + if (this.items[cell.day.toStringSortable()] === 1) { + this._addClass(cell, 'busy'); + this._removeClass(cell, 'free'); + } + else { + this._removeClass(cell, 'busy'); + this._addClass(cell, 'free'); + } + } + } + } + }; + + this._saveState = function() { + var s = {}; + s.startDate = calendar.startDate; + s.selectionStart = calendar.selectionStart; + s.selectionEnd = calendar.selectionEnd.addDays(1); + calendar.state.value = JSON.stringify(s); + }; + + this._selectModeLowerCase = function() { + var selectMode = this.selectMode || ""; + return selectMode.toLowerCase(); + }; + + this._adjustSelection = function() { + + var input = this.selectionDay || this.selectionStart; // selectionDay is preferred + if (!input) { + input = DayPilot.Date.today(); + } + input = new DayPilot.Date(input); // make sure it's DayPilot.Date + + // ignores selectionEnd + // uses selectMode + switch (this._selectModeLowerCase()) { + case 'day': + this.selectionStart = input; + this.selectionDay = input; + this.selectionEnd = input; + break; + case 'week': + this.selectionDay = input; + this.selectionStart = input.firstDayOfWeek(resolved.weekStarts()); + this.selectionEnd = this.selectionStart.addDays(6); + break; + case 'month': + this.selectionDay = input; + this.selectionStart = input.firstDayOfMonth(); + this.selectionEnd = this.selectionStart.lastDayOfMonth(); + break; + case 'none': + this.selectionEnd = input; + break; + default: + throw "Unknown selectMode value."; + } + + }; + + this._postponedSelect = null; + + // options.dontFocus, options.dontNotify + this.select = function(a1, a2, a3) { + + var a2IsDate = a2 && (a2 instanceof DayPilot.Date || typeof a2 === "string"); + var a2IsOptions = (a2 && typeof a2 === "object") || typeof a2 === "boolean"; + + var date1 = a1; + var date2 = a2IsDate ? a2 : null; + var options = a2IsOptions ? a2 : a3; + + if (!this._initialized) { + this._postponedSelect = { + "date1": date1, + "date2": date2, + "options": options + }; + return; + } + + var focus = true; + var notify = true; // fire the timeRangeSelected event + + if (options && typeof options === "object") { + if (options.dontFocus) { + focus = false; + } + if (options.dontNotify) { + notify = false; + } + } + else if (typeof options === "boolean") { + focus = !options; + } + + var originalStart = this.selectionStart; + var originalEnd = this.selectionEnd; + + this.selectionStart = new DayPilot.Date(date1).getDatePart(); + this.selectionDay = this.selectionStart; + + var startChanged = false; + if (focus) { + + var newStart = this.startDate; + if (this.selectionStart < this._activeStart() || this.selectionStart >= this._activeEnd()) { + newStart = this.selectionStart.firstDayOfMonth(); + } + + if (newStart.toStringSortable() !== this.startDate.toStringSortable()) { + startChanged = true; + } + + this.startDate = newStart; + } + + if (date2 && calendar.freeHandSelectionEnabled) { + calendar.selectionEnd = new DayPilot.Date(date2); + } + else { + this._adjustSelection(); + } + + // redraw + this._clearTable(); + this._prepare(); + this._drawMonths(); + this._updateFreeBusy(); + this._saveState(); + + if (notify && (!originalStart.equals(this.selectionStart) || !originalEnd.equals(this.selectionEnd))) { + //alert('time range'); + this._timeRangeSelectedDispatch(); + } + + if (startChanged) { + //alert('visible range'); + this._visibleRangeChangedDispatch(); + } + }; + + this.update = function(options) { + + calendar._loadOptions(options); + +/* + if (!calendar._initialized) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Navigator instance that hasn't been initialized yet."); + } +*/ + if (!this._initialized) { + return; + } + + if (calendar._disposed) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Navigator instance that has been disposed."); + } + + calendar._clearCache(); + + var os = { + "day": calendar.selectionDay, + "start": calendar.selectionStart, + "end": calendar.selectionEnd + }; + + calendar._update(); + + if (os.start !== calendar.selectionStart || os.end != calendar.selectionEnd || os.day !== calendar.selectionDay) { + calendar._timeRangeSelectedDispatch(); + } + }; + + this._update = function () { + // redraw + this._clearTable(); + this._prepare(); + this._adjustSelection(); + this._drawMonths(); + this._loadEvents(); + this._updateFreeBusy(); + this._saveState(); + + if (this.visible) { + this.show(); + } + else { + this.hide(); + } + }; + + this._clearCache = function() { + calendar._cache = {}; + }; + + this._specialHandling = null; + this._loadOptions = function(options) { + if (!options) { + return; + } + var specialHandling = { + "events": { + "preInit": function() { + var events = this.data || []; + if (DayPilot.isArray(events.list)) { + calendar.events.list = events.list; + } + else { + calendar.events.list = events; + } + } + } + }; + this._specialHandling = specialHandling; + + for (var name in options) { + if (specialHandling[name]) { + var item = specialHandling[name]; + item.data = options[name]; + if (item.preInit) { + item.preInit(); + } + } + else { + calendar[name] = options[name]; + } + } + + }; + + this._postInit = function() { + var specialHandling = this._specialHandling; + for (var name in specialHandling) { + var item = specialHandling[name]; + if (item.postInit) { + item.postInit(); + } + } + }; + + + this._callBack2 = function(action, data, parameters) { + var envelope = {}; + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + JSON.stringify(envelope); + + var context = null; + if (this.backendUrl) { + DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this._ajaxError); + } + else { + WebForm_DoCallback(this.uniqueID, commandstring, this._updateView, context, this.callbackError, true); + } + + }; + + this._ajaxError = function(req) { + if (typeof calendar.onAjaxError === 'function') { + var args = {}; + args.request = req; + calendar.onAjaxError(args); + } + else if (typeof calendar.ajaxError === 'function') { // backwards compatibility + calendar.ajaxError(req); + } + }; + + this._callBackResponse = function(response) { + calendar._updateView(response.responseText); + }; + + this._postBack2 = function(action, data, parameters) { + var envelope = {}; + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + JSON.stringify(envelope); + __doPostBack(calendar.uniqueID, commandstring); + }; + + this._getCallBackHeader = function() { + var h = {}; + h.v = this.v; + h.startDate = this.startDate; + h.selectionStart = this.selectionStart; + h.showMonths = this.showMonths; + return h; + }; + + this._listen = function(action, data) { + if (action === 'refresh') { + this._visibleRangeChangedDispatch(); + } + }; + + this._getDayName = function(i) { + var x = i + resolved.weekStarts(); + if (x > 6) { + x -= 7; + } + return resolved.locale().dayNamesShort[x]; + + }; + + this._isSelected = function(date) { + if (this.selectionStart === null || this.selectionEnd === null) { + return false; + } + + if (this.selectionStart.getTime() <= date.getTime() && date.getTime() <= this.selectionEnd.getTime()) { + return true; + } + + return false; + }; + + this._getMonthFromCoords = function(coords) { + var month = 0; + //debugger; + for (var i = 0; i < calendar.months.length; i++) { + var m = calendar.months[i]; + if (!m) { + return null; + } + if (coords.x < m.left || m.width < coords.x ) { + return null; + } + + var height = calendar.months[i].height; + if (m.top <= coords.y && coords.y < m.top + m.height) { + return i; + } + } + return null; + + }; + + this._getPosition = function(ev) { + + var coords = DayPilot.mo3(calendar.nav.top, ev); + + var monthIndex = calendar._getMonthFromCoords(coords); + if (monthIndex === null) { + return null; + } + var month = calendar.months[monthIndex]; + + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + if (month.top <= coords.y && coords.y < month.top + totalHeaderHeight) { + return { + "month": monthIndex, + "x": 0, + "y": 0, + "coords": coords, + "header": true + }; + } + + for (var x = 0; x < month.cells.length; x++) { + for (var y = 0; y < month.cells[x].length; y++) { + var cell = month.cells[x][y]; + var top = cell.top + month.top; + var left = cell.left + month.left; + if (left <= coords.x && coords.x < left + calendar.cellWidth) { + if (top <= coords.y && coords.y < top + calendar.cellHeight) { + return { + "month": monthIndex, + "x": x, + "y": y, + "coords": coords + }; + } + } + } + } + + return null; + }; + + this._onTopMouseDown = function(ev) { + var freeHandSelection = calendar.freeHandSelectionEnabled; + if (!freeHandSelection) { + return; + } + var start = calendar._getPosition(ev); + if (start && !start.header) { + ps.start = start; + } + var cell = calendar.months[start.month].cells[start.x][start.y]; + + ev.preventDefault(); + + }; + + this._onTopMouseMove = function(ev) { + if (!ps.start) { + return; + } + var end = calendar._getPosition(ev); + if (ps.end) { + ps.end = end; + } + else if (end) { + var requiredDistance = 3; + var distance = DayPilot.distance(ps.start.coords, end.coords); + + if (distance > requiredDistance) { + ps.end = end; + } + } + + if (ps.end) { + ps.clear(); + ps.draw(); + } + //ps.end = end; + }; + + this._preselection = {}; + var ps = this._preselection; + ps.start = null; + + ps.drawCell = function(pos) { + var month = calendar.months[pos.month]; + + var cellPos = calendar._cellRelativeCoords(pos.x, pos.y); + + var top = month.top + cellPos.y; + var left = month.left + cellPos.x; + + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.left = left + "px"; + div.style.top = top + "px"; + div.style.height = calendar.cellHeight + "px"; + div.style.width = calendar.cellWidth + "px"; + div.style.backgroundColor = "#ccc"; + div.style.opacity = 0.5; + div.style.cursor = "default"; + + calendar.nav.preselection.appendChild(div); + ps.cells.push(div); + }; + + ps.clear = function() { + if (!ps.cells) { + return; + } + + for(var i = 0; i < ps.cells.length; i++) { + calendar.nav.preselection.removeChild(ps.cells[i]); + } + ps.cells = []; + }; + + ps.draw = function() { + var ordered = ps.ordered(); + + var position = new Position(ordered.start); + var end = ordered.end; + + if (!end) { + return; + } + + if (end === ps.end && end.header) { + if (end.month > 0) { + end.month -= 1; + var month = calendar.months[end.month]; + end.x = 6; + end.y = month.rowCount - 1; + } + } + + ps.cells = []; + + while (!position.is(end)) { + ps.drawCell(position); + var next = new Position(position).next(); + if (!next) { + return; + } + position.month = next.month; + position.x = next.x; + position.y = next.y; + } + + // the last one + ps.drawCell(position); + + }; + + ps.ordered = function() { + //var position = new Position(start); + var start = ps.start; + var end = ps.end; + + var result = {}; + if (!end || new Position(start).before(end)) { + result.start = start; + result.end = end; + } + else { + result.start = end; + result.end = start; + } + return result; + }; + + var Position = function(month, x, y) { + + if (month instanceof Position) { + return month; + } + if (typeof month === "object") { + var ref = month; + this.month = ref.month; + this.x = ref.x; + this.y = ref.y; + } + else { + this.month = month; + this.x = x; + this.y = y; + } + this.is = function(ref) { + return this.month === ref.month && this.x === ref.x && this.y === ref.y; + }; + + this.next = function() { + var start = this; + if (start.x < 6) { + return { + "month": start.month, + "x": start.x + 1, + "y": start.y + }; + } + var month = calendar.months[start.month]; + if (start.y < month.rowCount - 1) { + return { + "month": start.month, + "x": 0, + "y": start.y + 1 + }; + } + if (start.month < calendar.months.length - 1) { + return { + "month": start.month + 1, + "x": 0, + "y": 0 + }; + } + return null; + }; + + this.visible = function() { + var cell = this.cell(); + if (cell.isCurrentMonth) { + return true; + } + if (cell.isPrevMonth && cell.showBefore) { + return true; + } + if (cell.isNextMonth && cell.showAfter) { + return true; + } + return false; + }; + + this.nextVisible = function() { + var pos = this; + while (!pos.visible()) { + var next = pos.next(); + if (!next) { + return null; + } + pos = new Position(next); + } + return pos; + }; + + this.previous = function() { + var start = this; + if (start.x > 0) { + return { + "month": start.month, + "x": start.x - 1, + "y": start.y + }; + } + var month = calendar.months[start.month]; + if (start.y > 0) { + return { + "month": start.month, + "x": 6, + "y": start.y - 1 + }; + } + if (start.month > 0) { + var m = calendar.months[start.month - 1]; + return { + "month": start.month - 1, + "x": 6, + "y": m.rowCount - 1 + }; + } + return null; + + }; + + this.previousVisible = function() { + var pos = this; + while (!pos.visible()) { + var previous = pos.previous(); + if (!previous) { + return null; + } + pos = new Position(previous); + } + return pos; + }; + + this.cell = function() { + return calendar.months[this.month].cells[this.x][this.y]; + }; + + this.date = function() { + return this.cell().day; + }; + + this.before = function(ref) { + var thisDate = this.date(); + var refDate = new Position(ref).date(); + return thisDate < refDate; + }; + }; + + + this._cellClick = function(ev) { + var main = this.parentNode; + var month = this.parentNode.month; + + var x = this.x; + var y = this.y; + var day = month.cells[x][y].day; + + if (!month.cells[x][y].isClickable) { + return; + } + + calendar.clearSelection(); + + calendar.selectionDay = day; + + var day = calendar.selectionDay; + switch (calendar._selectModeLowerCase()) { + case 'none': + //var s = month.cells[x][y]; + calendar.selectionStart = day; + calendar.selectionEnd = day; + break; + case 'day': + if (calendar.autoFocusOnClick) { + var start = day; + if (day < calendar._activeStart() || + day >= calendar._activeEnd()) { + calendar.select(day); + return; + } + } + + var s = month.cells[x][y]; + calendar._cellSelect(main, x, y); + //calendar._addClass(s, 'select'); + calendar.selected.push(s); + calendar.selectionStart = s.day; + calendar.selectionEnd = s.day; + + break; + case 'week': + if (calendar.autoFocusOnClick) { + var start = month.cells[0][y].day; + var end = month.cells[6][y].day; + if (start.firstDayOfMonth() === end.firstDayOfMonth()) { + if (start < calendar._activeStart() || + end >= calendar._activeEnd()) { + calendar.select(day); + return; + } + } + } + for (var j = 0; j < 7; j++) { + calendar._cellSelect(main, j, y); + //calendar._addClass(month.cells[j][y], 'select'); + calendar.selected.push(month.cells[j][y]); + } + calendar.selectionStart = month.cells[0][y].day; + calendar.selectionEnd = month.cells[6][y].day; + + break; + case 'month': + if (calendar.autoFocusOnClick) { + var start = day; + if (day < calendar._activeStart() || + day >= calendar._activeEnd()) { + calendar.select(day); + return; + } + } + + var start = null; + var end = null; + for (var y = 0; y < 6; y++) { + for (var x = 0; x < 7; x++) { + var s = month.cells[x][y]; + if (!s) { + continue; + } + if (s.day.getYear() === day.getYear() && s.day.getMonth() === day.getMonth()) { + calendar._cellSelect(main, x, y); + //calendar._addClass(s, 'select'); + calendar.selected.push(s); + if (start === null) { + start = s.day; + } + end = s.day; + } + } + } + calendar.selectionStart = start; + calendar.selectionEnd = end; + break; + default: + throw 'unknown selectMode'; + } + + calendar._saveState(); + + calendar._timeRangeSelectedDispatch(); + }; + + this._timeRangeSelectedDispatch = function(options) { + var start = calendar.selectionStart; + var end = calendar.selectionEnd.addDays(1); + var days = DayPilot.DateUtil.daysDiff(start, end); + var day = calendar.selectionDay; + + options = options || {}; + + + if (calendar._api2()) { + + var args = {}; + args.start = start; + args.end = end; + args.day = day; + args.days = days; + args.mode = options.mode || calendar.selectMode; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onTimeRangeSelect === 'function') { + calendar.onTimeRangeSelect(args); + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (calendar.timeRangeSelectedHandling) { + case 'Bind': + if (typeof bound === "object") { + var selection = {}; + selection.start = start; + selection.end = end; + selection.days = days; + selection.day = day; + bound.commandCallBack(calendar.command, selection); + } + break; + case 'None': + break; + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end, day); + break; + } + + if (typeof calendar.onTimeRangeSelected === 'function') { + calendar.onTimeRangeSelected(args); + } + + } + else { + switch (calendar.timeRangeSelectedHandling) { + case 'Bind': + if (typeof bound === "object") { + var selection = {}; + selection.start = start; + selection.end = end; + selection.days = days; + selection.day = day; + bound.commandCallBack(calendar.command, selection); + } + break; + case 'JavaScript': + calendar.onTimeRangeSelected(start, end, day); + break; + case 'None': + break; + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end, day); + break; + } + } + + + }; + + this.timeRangeSelectedPostBack = function(start, end, data, day) { + var params = {}; + params.start = start; + params.end = end; + params.day = day; + + this._postBack2('TimeRangeSelected', data, params); + }; + + this._clickRight = function(ev) { + calendar._moveMonth(calendar.skipMonths); + }; + + this._clickLeft = function(ev) { + calendar._moveMonth(-calendar.skipMonths); + }; + + this._moveMonth = function(i) { + this.startDate = this.startDate.addMonths(i); + this._clearTable(); + this._prepare(); + this._drawMonths(); + + this._saveState(); + + this._visibleRangeChangedDispatch(); + this._updateFreeBusy(); + }; + + this._activeStart = function() { + return calendar.startDate.firstDayOfMonth(); + }; + + this._activeEnd = function() { + return calendar.startDate.firstDayOfMonth().addMonths(this.showMonths); + }; + + this.visibleStart = function() { + return calendar.startDate.firstDayOfMonth().firstDayOfWeek(resolved.weekStarts()); + }; + + this.visibleEnd = function() { + return calendar.startDate.firstDayOfMonth().addMonths(this.showMonths - 1).firstDayOfWeek(resolved.weekStarts()).addDays(42); + }; + + this._visibleRangeChangedDispatch = function() { + var start = this.visibleStart(); + var end = this.visibleEnd(); + + if (calendar._api2()) { + + var args = {}; + args.start = start; + args.end = end; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onVisibleRangeChange === 'function') { + calendar.onVisibleRangeChange(args); + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (this.visibleRangeChangedHandling) { + case "CallBack": + this.visibleRangeChangedCallBack(null); + break; + case "PostBack": + this.visibleRangeChangedPostBack(null); + break; + case "Disabled": + break; + } + + if (typeof calendar.onVisibleRangeChanged === 'function') { + calendar.onVisibleRangeChanged(args); + } + + } + else { + switch (this.visibleRangeChangedHandling) { + case "CallBack": + this.visibleRangeChangedCallBack(null); + break; + case "PostBack": + this.visibleRangeChangedPostBack(null); + break; + case "JavaScript": + this.onVisibleRangeChanged(start, end); + break; + case "Disabled": + break; + } + } + + /* + switch (this.visibleRangeChangedHandling) { + case "CallBack": + this.visibleRangeChangedCallBack(null); + break; + case "PostBack": + this.visibleRangeChangedPostBack(null); + break; + case "JavaScript": + this.onVisibleRangeChanged(start, end); + break; + case "Disabled": + break; + } + */ + }; + + + this.visibleRangeChangedCallBack = function(data) { + var parameters = {}; + this._callBack2("Visible", data, parameters); + }; + + this.visibleRangeChangedPostBack = function(data) { + var parameters = {}; + this._postBack2("Visible", data, parameters); + }; + + this._updateView = function(result, context) { + var result = JSON.parse(result); + calendar.items = result.Items; + calendar.cells = result.Cells; + + if (calendar.cells) { + calendar.update(); + } + else { + calendar._updateFreeBusy(); + } + }; + + this._drawMonths = function() { + for (var j = 0; j < this.showMonths; j++) { + var showLinks = this._getShowLinks(j); + this._drawTable(j, showLinks); + } + + this.root.style.height = this._getHeight() + "px"; + + this.nav.preselection = document.createElement("div"); + this.nav.preselection.style.position = "absolute"; + this.nav.preselection.style.left = "0px"; + this.nav.preselection.style.top = "0px"; + this.root.appendChild(this.nav.preselection); + + /* + var div = document.createElement("div"); + div.style.clear = "left"; + div.style.height = "0px"; + div.style.width = "0px"; + this.root.appendChild(div); + */ + + }; + + + this._getHeight = function() { + if (this.orientation === "Horizontal") { + var max = 0; + for (var i = 0; i < this.months.length; i++) { + var month = this.months[i]; + if (month.height > max) { + max = month.height; + } + } + return max; + } + else { + var total = 0; + for (var i = 0; i < this.months.length; i++) { + var month = this.months[i]; + //total += this.showMonths*(this.cellHeight*month.rowCount + this.titleHeight + this.dayHeaderHeight); + total += month.height; + } + return total; + } + }; + + this._getShowLinks = function(j) { + if (this.internal.showLinks) { + return this.internal.showLinks; + } + + var showLinks = {}; + showLinks.left = (j === 0); + showLinks.right = (j === 0); + showLinks.before = j === 0; + showLinks.after = j === this.showMonths - 1; + + if (this.orientation === "Horizontal") { + showLinks.right = (j === this.showMonths - 1); + } + + return showLinks; + }; + + // not used at the moment - no internal changes to data + + this._angular = {}; + this._angular.scope = null; + this._angular.notify = function() { + if (calendar._angular.scope) { + calendar._angular.scope["$apply"](); + } + }; + + this.internal = {}; + this.internal.loadOptions = calendar._loadOptions; + // ASP.NET + this.internal.initialized = function() { + return calendar._initialized; + }; + + this._resolved = {}; + var resolved = this._resolved; + + resolved.locale = function() { + return DayPilot.Locale.find(calendar.locale); + }; + + resolved.weekStarts = function() { + if (calendar.weekStarts === 'Auto') { + var locale = resolved.locale(); + if (locale) { + return locale.weekStarts; + } + else { + return 0; // Sunday + } + } + else { + return calendar.weekStarts; + } + }; + + resolved.cellWidth = function() { + if (calendar._cache.cellWidth) { + return calendar._cache.cellWidth; + } + var width = calendar._getDimensionsFromCss("_cell_dimensions").width; + if (!width) { + width = calendar.cellWidth; + } + calendar._cache.cellWidth = width; + return width; + }; + + this.clearSelection = function() { + for (var j = 0; j < this.selected.length; j++) { + //this._removeClass(this.selected[j], 'select'); + var div = this.selected[j]; + calendar._cellUnselect(div.parentNode, div.x, div.y); + } + this.selected = []; + }; + + this._isShortInit = function() { + // make sure it has a place to ask + if (this.backendUrl) { + return (typeof calendar.items === 'undefined') || (!calendar.items); + } + else { + return false; + } + }; + + this.events = {}; + + this._loadEvents = function() { + if (!DayPilot.isArray(this.events.list)) { + return; + } + + this.items = {}; + + for(var i = 0; i < this.events.list.length; i++) { + var e = this.events.list[i]; + if (e.hidden) { + continue; + } + var days = this._eventDays(e); + for(var name in days) { + this.items[name] = 1; + } + } + }; + + this._getDimensionsFromCss = function(className) { + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.top = "-2000px"; + div.style.left = "-2000px"; + div.className = this._prefixCssClass(className); + + var container = calendar.root || document.body; + + container.appendChild(div); + var height = div.offsetHeight; + var width = div.offsetWidth; + container.removeChild(div); + + var result = {}; + result.height = height; + result.width = width; + return result; + }; + + this._eventDays = function(e) { + var start = new DayPilot.Date(e.start); + var end = new DayPilot.Date(e.end); + + var days = {}; + + var d = start.getDatePart(); + while (d.getTime() <= end.getTime()) { + days[d.toStringSortable()] = 1; + d = d.addDays(1); + } + + return days; + }; + + this.show = function() { + calendar.visible = true; + calendar.root.style.display = ''; + }; + + this.hide = function() { + calendar.visible = false; + calendar.root.style.display = 'none'; + }; + + this._loadTop = function() { + if (this.id && this.id.tagName) { + this.nav.top = this.id; + } + else if (typeof this.id === "string") { + this.nav.top = document.getElementById(this.id); + if (!this.nav.top) { + throw "DayPilot.Navigator: The placeholder element not found: '" + id + "'."; + } + } + else { + throw "DayPilot.Navigator() constructor requires the target element or its ID as a parameter"; + } + + this.root = this.nav.top; + + }; + + this.init = function() { + this._loadTop(); + + if (this.root.dp) { // already initialized + return; + } + + this._adjustSelection(); + this._prepare(); + this._drawMonths(); + this._loadEvents(); + this._updateFreeBusy(); + this._registerDispose(); + this._registerTopHandlers(); + this._registerGlobalHandlers(); + + //this.select(this.selectionStart); + + var loadFromServer = this._isShortInit(); + if (loadFromServer) { + this._visibleRangeChangedDispatch(); // TODO change to "Init"? + } + this._initialized = true; + this._postInit(); + + if (this._postponedSelect) { + var params = this._postponedSelect; + this.select(params.date1, params.date2, params.options); + this._postponedSelect = null; + } + + return this; + }; + + this._registerTopHandlers = function() { + calendar.nav.top.onmousedown = this._onTopMouseDown; + calendar.nav.top.onmousemove = this._onTopMouseMove; + }; + + this._registerGlobalHandlers = function() { + DayPilot.re(document, 'mouseup', calendar._gMouseUp); + }; + + this._gMouseUp = function(ev) { + if (ps.start && ps.end) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + // click, cancel + if (coords.x === ps.start.coords.x && coords.y === ps.start.coords.y) { + ps.start = null; + ps.clear(); + return; + } + + ps.clear(); + + var ordered = ps.ordered(); + + ordered.start = new Position(ordered.start).nextVisible(); + ordered.end = new Position(ordered.end).previousVisible(); + + + calendar.selectionDay = new Position(ordered.start).date(); + calendar.selectionStart = calendar.selectionDay; + calendar.selectionEnd = new Position(ordered.end).date(); + + ps.start = null; + ps.end = null; + + // redraw + calendar._clearTable(); + calendar._prepare(); + calendar._drawMonths(); + calendar._updateFreeBusy(); + calendar._saveState(); + + var notify = true; + if (notify) { + calendar._timeRangeSelectedDispatch({"mode": "FreeHand"}); + } + + } + + // clear in either case + ps.start = null; + ps.end = null; + + }; + + this.dispose = function() { + var c = calendar; + + if (!c.root) { + return; + } + + c.root.removeAttribute("style"); + c.root.removeAttribute("class"); + c.root.dp = null; + c.root.innerHTML = null; + c.root = null; + + c._disposed = true; + + }; + + this._registerDispose = function() { + //var root = document.getElementById(id); + this.root.dispose = this.dispose; + }; + + this.Init = this.init; + + this._loadOptions(options); + }; + + // jQuery plugin + if (typeof jQuery !== 'undefined') { + (function($) { + $.fn.daypilotNavigator = function(options) { + var first = null; + var j = this.each(function() { + if (this.daypilot) { // already initialized + return; + }; + + var daypilot = new DayPilot.Navigator(this.id); + this.daypilot = daypilot; + for (var name in options) { + daypilot[name] = options[name]; + } + daypilot.Init(); + if (!first) { + first = daypilot; + } + }); + if (this.length === 1) { + return first; + } + else { + return j; + } + }; + })(jQuery); + } + + // AngularJS plugin + (function registerAngularModule() { + var app = DayPilot.am(); + + if (!app) { + return; + } + + + app.directive("daypilotNavigator", ['$parse', function($parse) { + return { + "restrict": "E", + "template": "
", + "compile": function compile(element, attrs) { + element.replaceWith(this["template"].replace("{{id}}", attrs["id"])); + + return function link(scope, element, attrs) { + var calendar = new DayPilot.Navigator(element[0]); + calendar._angular.scope = scope; + calendar.init(); + + var oattr = attrs["id"]; + if (oattr) { + scope[oattr] = calendar; + } + + // save DayPilot.Calendar object in the specified variable + var pas = attrs["publishAs"]; + if (pas) { + var getter = $parse(pas); + var setter = getter.assign; + setter(scope, calendar); + } + + // bind event handlers from attributes starting with "on" + for (var name in attrs) { + if (name.indexOf("on") === 0) { // event handler + var apply = DayPilot.Util.shouldApply(name); + + if (apply) { + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + scope["$apply"](function() { + f(scope, {"args": args}); + }); + }; + })(name); + } + else { + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + f(scope, {"args": args}); + }; + })(name); + } + + } + } + + var watch = scope["$watch"]; + var config = attrs["config"] || attrs["daypilotConfig"]; + var events = attrs["events"] || attrs["daypilotEvents"]; + + watch.call(scope, config, function (value, oldVal) { + for (var name in value) { + calendar[name] = value[name]; + } + calendar.update(); + }, true); + + watch.call(scope, events, function(value) { + calendar.events.list = value; + calendar._loadEvents(); + calendar._updateFreeBusy(); + }, true); + + }; + } + }; + }]); + + })(); + + if (typeof Sys !== 'undefined' && Sys.Application && Sys.Application.notifyScriptLoaded) { + Sys.Application.notifyScriptLoaded(); + } + + +})(); diff --git a/static/src/js/src/daypilot-calendar.src.js b/static/src/js/src/daypilot-calendar.src.js new file mode 100644 index 0000000..553a6ba --- /dev/null +++ b/static/src/js/src/daypilot-calendar.src.js @@ -0,0 +1,3979 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function() { + + var doNothing = function() {}; + + if (typeof DayPilot.Calendar !== 'undefined' && DayPilot.Calendar.events) { + return; + } + + var DayPilotCalendar = {}; + + // internal selecting + DayPilotCalendar.selectedCells = []; + DayPilotCalendar.topSelectedCell = null; + DayPilotCalendar.bottomSelectedCell = null; + DayPilotCalendar.selecting = false; + DayPilotCalendar.column = null; + DayPilotCalendar.firstSelected = null; + DayPilotCalendar.firstMousePos = null; + + // internal resizing + DayPilotCalendar.originalMouse = null; + DayPilotCalendar.originalHeight = null; + DayPilotCalendar.originalTop = null; + DayPilotCalendar.resizing = null; + DayPilotCalendar.globalHandlers = false; + + // internal moving + DayPilotCalendar.moving = null; + + // helpers + DayPilotCalendar.register = function(calendar) { + if (!DayPilotCalendar.registered) { + DayPilotCalendar.registered = []; + } + var r = DayPilotCalendar.registered; + + for (var i = 0; i < r.length; i++) { + if (r[i] === calendar) { + return; + } + } + r.push(calendar); + }; + + DayPilotCalendar.unregister = function (calendar) { + var a = DayPilotCalendar.registered; + if (!a) { + return; + } + + var i = DayPilot.indexOf(a, calendar); + if (i === -1) { + return; + } + a.splice(i, 1); + }; + + DayPilotCalendar.getCellsAbove = function(cell) { + var array = []; + var c = DayPilotCalendar.getColumn(cell); + + var tr = cell.parentNode; + + var select = null; + while (tr && select !== DayPilotCalendar.firstSelected) { + select = tr.getElementsByTagName("td")[c]; + array.push(select); + tr = tr.previousSibling; + while (tr && tr.tagName !== "TR") { + tr = tr.previousSibling; + } + } + return array; + }; + + DayPilotCalendar.getCellsBelow = function(cell) { + var array = []; + var c = DayPilotCalendar.getColumn(cell); + var tr = cell.parentNode; + + var select = null; + while (tr && select !== DayPilotCalendar.firstSelected) { + select = tr.getElementsByTagName("td")[c]; + array.push(select); + tr = tr.nextSibling; + while (tr && tr.tagName !== "TR") { + tr = tr.nextSibling; + } + } + return array; + }; + + DayPilotCalendar.getColumn = function(cell) { + var i = 0; + while (cell.previousSibling) { + cell = cell.previousSibling; + if (cell.tagName === "TD") { + i++; + } + } + return i; + }; + + DayPilotCalendar.gUnload = function (ev) { + + if (!DayPilotCalendar.registered) { + return; + } + var r = DayPilotCalendar.registered; + + for (var i = 0; i < r.length; i++) { + var c = r[i]; + c.dispose(); + + DayPilotCalendar.unregister(c); + } + + }; + + DayPilotCalendar.gMouseUp = function (ev){ + + if (DayPilotCalendar.resizing) { + if (!DayPilotCalendar.resizingShadow) { + DayPilotCalendar.resizing.style.cursor = 'default'; + document.body.style.cursor = 'default'; + DayPilotCalendar.resizing = null; + DayPilot.Global.resizing = null; + return; + } + + var dpEvent = DayPilotCalendar.resizing.event; + var height = DayPilotCalendar.resizingShadow.clientHeight + 4; + var top = DayPilotCalendar.resizingShadow.offsetTop; + var border = DayPilotCalendar.resizing.dpBorder; + + // stop resizing on the client + DayPilotCalendar.deleteShadow(DayPilotCalendar.resizingShadow); + DayPilotCalendar.resizingShadow = null; + DayPilotCalendar.resizing.style.cursor = 'default'; + dpEvent.calendar.nav.top.style.cursor = 'auto'; + //document.body.style.cursor = 'default'; + DayPilotCalendar.resizing.onclick = null; // will be re-created anyway + + DayPilotCalendar.resizing = null; + DayPilot.Global.resizing = null; + + dpEvent.calendar._eventResizeDispatch(dpEvent, height, top, border); + } + else if (DayPilotCalendar.moving) { + if (!DayPilotCalendar.movingShadow) { + DayPilotCalendar.moving = null; + DayPilot.Global.moving = null; + document.body.style.cursor = 'default'; + return; + } + + var top = DayPilotCalendar.movingShadow.offsetTop; + var dpEvent = DayPilotCalendar.moving.event; + + DayPilotCalendar.deleteShadow(DayPilotCalendar.movingShadow); + DayPilot.Util.removeClass(DayPilotCalendar.moving, dpEvent.calendar._prefixCssClass("_event_moving_source")); + + var newColumnIndex = DayPilotCalendar.movingShadow.column; + + // stop moving on the client + DayPilotCalendar.moving = null; + DayPilot.Global.moving = null; + DayPilotCalendar.movingShadow = null; + //document.body.style.cursor = 'default'; + dpEvent.calendar.nav.top.style.cursor = 'auto'; + + dpEvent.calendar._eventMoveDispatch(dpEvent, newColumnIndex, top, ev); + } + else if (DayPilotCalendar.selecting && DayPilotCalendar.topSelectedCell !== null) { + var calendar = DayPilotCalendar.selecting.calendar; + DayPilotCalendar.selecting = false; + + var sel = calendar.getSelection(); + + calendar._timeRangeSelectedDispatch(sel.start, sel.end, sel.resource); + if (calendar.timeRangeSelectedHandling !== "Hold" && calendar.timeRangeSelectedHandling !== "HoldForever") { + doNothing(); + } + } + else { + DayPilotCalendar.selecting = false; + } + + + }; + + DayPilotCalendar.deleteShadow = function(shadow) { + if (!shadow) { + return; + } + if (!shadow.parentNode) { + return; + } + + shadow.parentNode.removeChild(shadow); + }; + + DayPilotCalendar.moveShadow = function(column) { + var shadow = DayPilotCalendar.movingShadow; + var parent = shadow.parentNode; + + parent.style.display = 'none'; + + shadow.parentNode.removeChild(shadow); + column.firstChild.appendChild(shadow); + shadow.style.left = '0px'; + + parent.style.display = ''; + + shadow.style.width = (DayPilotCalendar.movingShadow.parentNode.offsetWidth + 1) + 'px'; + }; + + DayPilotCalendar.Calendar = function(id, options) { + + var isConstructor = false; + if (this instanceof DayPilotCalendar.Calendar && !this.__constructor) { + isConstructor = true; + this.__constructor = true; + } + + if (!isConstructor) { + throw "DayPilot.Calendar() is a constructor and must be called as 'var c = new DayPilot.Calendar(id);'"; + } + + var calendar = this; + this.uniqueID = null; + this.isCalendar = true; + + this.v = '2024.3.539-lite'; + this.id = id; + this.clientName = id; + + this.cache = {}; + this.cache.pixels = {}; + + this.elements = {}; + this.elements.events = []; + this.elements.selection = []; + + this.nav = {}; + + this.afterRender = function() {}; + + this.fasterDispose = true; + + this.angularAutoApply = false; + this.api = 2; + this.businessBeginsHour = 9; + this.businessEndsHour = 18; + this.cellHeight = 30; + this.columnMarginRight = 5; + this.columnsLoadMethod = "GET"; + this.contextMenu = null; + this.days = 1; + this.durationBarVisible = true; + this.eventsLoadMethod = "GET"; + this.headerDateFormat = null; // uses locale.dateFormat by default + this.headerHeight = 30; + this.headerTextWrappingEnabled = false; + this.height = 300; + this.heightSpec = 'BusinessHours'; + this.hideUntilInit = true; + this.hourWidth = 60; + this.initScrollPos = 'Auto'; + this.loadingLabelHtml = null; + this.loadingLabelText = "Loading..."; + this.loadingLabelVisible = true; + this.locale = "en-us"; + this.showToolTip = true; + this.startDate = new DayPilot.Date().getDatePart(); + this.cssClassPrefix = "calendar_default"; + this.theme = null; + this.timeFormat = 'Auto'; + this.viewType = "Days"; + this.visible = true; + this.xssProtection = "Enabled"; + + this.headerClickHandling = "Enabled"; + this.eventClickHandling = 'Enabled'; + this.eventResizeHandling = 'Update'; + this.eventRightClickHandling = 'ContextMenu'; + this.eventMoveHandling = 'Update'; + this.eventDeleteHandling = "Disabled"; + this.timeRangeSelectedHandling = 'Enabled'; + + this.onBeforeCellRender = null; + this.onBeforeEventRender = null; + + this.onEventClick = null; + this.onEventClicked = null; + this.onEventDelete = null; + this.onEventDeleted = null; + this.onEventMove = null; + this.onEventMoved = null; + this.onEventResize = null; + this.onEventResized = null; + this.onEventRightClick = null; + this.onEventRightClicked = null; + this.onHeaderClick = null; + this.onHeaderClicked = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + + this._disposed = false; + + this.clearSelection = function() { + DayPilotCalendar.topSelectedCell = null; + DayPilotCalendar.bottomSelectedCell = null; + this._hideSelection(); + }; + + this._hideSelection = function() { + DayPilot.de(calendar.elements.selection); + calendar.elements.selection = []; + calendar.nav.activeSelection = null; + }; + + this.cleanSelection = this.clearSelection; + + this._postBack2 = function(action, data, parameters) { + var envelope = {}; + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); + __doPostBack(calendar.uniqueID, commandstring); + }; + + this._callBack2 = function(action, data, parameters) { + + if (this.callbackTimeout) { + window.clearTimeout(this.callbackTimeout); + } + + this.callbackTimeout = window.setTimeout(function() { + calendar.loadingStart(); + }, 100); + + var envelope = {}; + + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); + if (this.backendUrl) { + DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this.ajaxError); + } + else if (typeof WebForm_DoCallback === 'function') { + WebForm_DoCallback(this.uniqueID, commandstring, this._updateView, this.clientName, this.onCallbackError, true); + } + }; + + this.onCallbackError = function(result, context) { + alert("Error!\r\nResult: " + result + "\r\nContext:" + context); + }; + + this.dispose = function() { + + + var c = calendar; + + if (c._disposed) { + return; + } + c._disposed = true; + + clearInterval(c._visibilityInterval); + + c._deleteEvents(); + c.nav.scroll.root = null; + + DayPilot.pu(c.nav.loading); + + c._disposeMain(); + c._disposeHeader(); + + c.nav.select = null; + c.nav.cornerRight = null; + c.nav.scrollable = null; + c.nav.zoom = null; + c.nav.loading = null; + c.nav.header = null; + c.nav.hourTable = null; + c.nav.scrolltop = null; + c.nav.scroll.onscroll = null; + c.nav.scroll = null; + c.nav.main = null; + c.nav.message = null; + c.nav.messageClose = null; + c.nav.top = null; + + DayPilotCalendar.unregister(c); + }; + + this.disposed = function() { + return this._disposed; + }; + + this._registerDispose = function() { + this.nav.top.dispose = this.dispose; + }; + + this._callBackResponse = function(response) { + calendar._updateView(response.responseText); + }; + + this._getCallBackHeader = function() { + var h = {}; + + h.control = "dpc"; + h.id = this.id; + h.v = this.v; + + h.days = calendar.days; + h.startDate = calendar.startDate; + h.heightSpec = calendar.heightSpec; + h.businessBeginsHour = calendar.businessBeginsHour; + h.businessEndsHour = calendar.businessEndsHour; + h.hashes = calendar.hashes; + + // h.backColor = calendar.cellBackColor; + h.timeFormat = calendar.timeFormat; + h.viewType = calendar.viewType; + h.locale = calendar.locale; + + return h; + }; + + this._createShadow = function(object, copyText) { + var parentTd = object.parentNode; + while (parentTd && parentTd.tagName !== "TD") { + parentTd = parentTd.parentNode; + } + + var shadow = document.createElement('div'); + shadow.setAttribute('unselectable', 'on'); + shadow.style.position = 'absolute'; + shadow.style.width = (object.offsetWidth) + 'px'; + shadow.style.height = (object.offsetHeight) + 'px'; + shadow.style.left = (object.offsetLeft) + 'px'; + shadow.style.top = (object.offsetTop) + 'px'; + shadow.style.boxSizing = "border-box"; + shadow.style.zIndex = 101; + + // shadow.style.backgroundColor = "#aaaaaa"; + // shadow.style.opacity = 0.5; + // shadow.style.filter = "alpha(opacity=50)"; + // shadow.style.border = '2px solid #aaaaaa'; + + shadow.className = calendar._prefixCssClass("_shadow"); + + var inner = document.createElement("div"); + inner.className = calendar._prefixCssClass("_shadow_inner"); + shadow.appendChild(inner); + + if (copyText && false) { // disabled + shadow.style.overflow = 'hidden'; + shadow.style.fontSize = object.style.fontSize; + shadow.style.fontFamily = object.style.fontFamily; + shadow.style.color = object.style.color; + shadow.innerHTML = object.data.client.html(); + } + + /* + shadow.style.MozBorderRadius = "5px"; + shadow.style.webkitBorderRadius = "5px"; + shadow.style.borderRadius = "5px"; + */ + + parentTd.firstChild.appendChild(shadow); + + return shadow; + }; + + + this._resolved = {}; + this._resolved.locale = function() { + var found = DayPilot.Locale.find(calendar.locale); + if (!found) { + return DayPilot.Locale.US; + } + return found; + }; + + this._resolved.timeFormat = function() { + if (calendar.timeFormat !== 'Auto') { + return calendar.timeFormat; + } + return this.locale().timeFormat; + }; + + this._resolved._xssProtectionEnabled = function() { + return calendar.xssProtection !== "Disabled"; + }; + + this._resolved._weekStarts = function() { + if (calendar.weekStarts === 'Auto') { + var locale = resolved.locale(); + if (locale) { + return locale.weekStarts; + } + else { + return 0; // Sunday + } + } + else { + return calendar.weekStarts || 0; + } + }; + + var resolved = this._resolved; + + this._updateView = function(result, context) { + + if (result && result.indexOf("$$$") === 0) { + if (window.console) { + console.log("Error received from the server side: " + result); + } + else { + throw "Error received from the server side: " + result; + } + return; + } + + var result = JSON.parse(result); + + if (result.CallBackRedirect) { + document.location.href = result.CallBackRedirect; + return; + } + + if (result.UpdateType === "None") { + calendar.loadingStop(); + calendar._show(); + return; + } + + calendar._deleteEvents(); + + if (result.UpdateType === "Full") { + + calendar.columns = result.Columns; + + // properties + calendar.days = result.Days; + calendar.startDate = new DayPilot.Date(result.StartDate); + calendar.heightSpec = result.HeightSpec ? result.HeightSpec : calendar.heightSpec; + calendar.businessBeginsHour = result.BusinessBeginsHour ? result.BusinessBeginsHour : calendar.businessBeginsHour; + calendar.businessEndsHour = result.BusinessEndsHour ? result.BusinessEndsHour : calendar.businessEndsHour; + calendar.headerDateFormat = result.HeaderDateFormat ? result.HeaderDateFormat : calendar.headerDateFormat; + calendar.viewType = result.ViewType; // + calendar.backColor = result.BackColor ? result.BackColor : calendar.backColor; + calendar.eventHeaderVisible = result.EventHeaderVisible ? result.EventHeaderVisible : calendar.eventHeaderVisible; + calendar.timeFormat = result.TimeFormat ? result.TimeFormat : calendar.timeFormat; + calendar.locale = result.Locale ? result.Locale : calendar.locale; + + calendar._prepareColumns(); + } + + // hashes + if (result.Hashes) { + for (var key in result.Hashes) { + calendar.hashes[key] = result.Hashes[key]; + } + } + + calendar.events.list = result.Events; + calendar._loadEvents(); + calendar._updateHeaderHeight(); + + if (result.UpdateType === "Full") { + calendar._drawHeader(); + calendar._drawMain(); + calendar._drawHourTable(); + calendar._updateHeight(); + } + + calendar._show(); + + calendar._drawEvents(); + calendar.clearSelection(); + + calendar.afterRender(result.CallBackData, true); + + calendar.loadingStop(); + + }; + + this._durationHours = function() { + return this._duration() / (3600 * 1000); + }; + + this._businessHoursSpan = function() { + if (this.businessBeginsHour > this.businessEndsHour) { + return 24 - this.businessBeginsHour + this.businessEndsHour; + } + else { + return this.businessEndsHour - this.businessBeginsHour; + } + }; + + this._rowCount = function() { + return this._duration() / (60 * 60 * 1000 / 2); + }; + + // in ticks + this._duration = function() { + var dHours = 0; + + if (this.heightSpec === 'BusinessHoursNoScroll') { + dHours = this._businessHoursSpan(); + } + else { + dHours = 24; + } + return dHours * 60 * 60 * 1000; // return ticks + }; + + this._visibleStart = function() { + if (this.heightSpec === 'BusinessHoursNoScroll') { + return this.businessBeginsHour; + } + return 0; + }; + + + + this._api2 = function() { + return calendar.api === 2; + }; + + this.eventClickCallBack = function(e, data) { + this._callBack2('EventClick', data, e); + }; + + this.eventClickPostBack = function(e, data) { + this._postBack2('EventClick', data, e); + }; + + this._eventClickDispatch = function (ev) { + var thisDiv = this; + + var e = thisDiv.event; + + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.originalEvent = ev; + args.meta = ev.metaKey; + args.ctrl = ev.ctrlKey; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventClick === 'function') { + calendar._angular.apply(function() { + calendar.onEventClick(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventClickHandling) { + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'PostBack': + calendar.eventClickPostBack(e); + break; + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(e); + } + } + break; + } + + if (typeof calendar.onEventClicked === 'function') { + calendar._angular.apply(function() { + calendar.onEventClicked(args); + }); + } + } + else { + switch (calendar.eventClickHandling) { + case 'PostBack': + calendar.eventClickPostBack(e); + break; + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'JavaScript': + calendar.onEventClick(e); + break; + } + } + + }; + + this._eventRightClickDispatch = function(ev) { + + var e = this.event; + + if (ev.stopPropagation) { + ev.stopPropagation(); + } + + if (!e.client.rightClickEnabled()) { + return false; + } + + var args = {}; + args.e = e; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventRightClick === 'function') { + calendar.onEventRightClick(args); + if (args.preventDefault.value) { + return false; + } + } + + switch (calendar.eventRightClickHandling) { + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(this.event); + } + } + break; + } + + if (typeof calendar.onEventRightClicked === 'function') { + calendar.onEventRightClicked(args); + } + + + if (ev.preventDefault) { + ev.preventDefault(); + } + return false; + }; + + + this.eventDeleteCallBack = function(e, data) { + this._callBack2('EventDelete', data, e); + }; + + this.eventDeletePostBack = function(e, data) { + this._postBack2('EventDelete', data, e); + }; + + this._eventDeleteDispatch = function (e) { + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventDelete === 'function') { + calendar._angular.apply(function() { + calendar.onEventDelete(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventDeleteHandling) { + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'Update': + calendar.events.remove(e); + break; + } + + if (typeof calendar.onEventDeleted === 'function') { + calendar._angular.apply(function() { + calendar.onEventDeleted(args); + }); + } + } + else { + switch (calendar.eventDeleteHandling) { + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'JavaScript': + calendar.onEventDelete(e); + break; + } + } + + }; + + this.eventResizeCallBack = function(e, newStart, newEnd, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._callBack2('EventResize', data, params); + }; + + this.eventResizePostBack = function(e, newStart, newEnd, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._postBack2('EventResize', data, params); + }; + + this._eventResizeDispatch = function (e, shadowHeight, shadowTop, border ) { + var _startOffset = 1; + + var newStart = new Date(); + var newEnd = new Date(); + + var start = e.start(); + var end = e.end(); + + if (border === 'top') { + var day = start.getDatePart(); + var step = Math.floor((shadowTop - _startOffset) / calendar.cellHeight); + var minutes = step * 30; + var ts = minutes * 60 * 1000; + var visibleStartOffset = calendar._visibleStart() * 60 * 60 * 1000; + + newStart = day.addTime(ts + visibleStartOffset); + newEnd = e.end(); + + } + else if (border === 'bottom') { + var day = end.getDatePart(); + var step = Math.floor((shadowTop + shadowHeight - _startOffset) / calendar.cellHeight); + var minutes = step * 30; + var ts = minutes * 60 * 1000; + var visibleStartOffset = calendar._visibleStart() * 60 * 60 * 1000; + + newStart = start; + newEnd = day.addTime(ts + visibleStartOffset); + } + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.control = calendar; + args.newStart = newStart; + args.newEnd = newEnd; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventResize === 'function') { + calendar._angular.apply(function() { + calendar.onEventResize(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventResizeHandling) { + case 'PostBack': + calendar.eventResizePostBack(e, newStart, newEnd); + break; + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventResized === 'function') { + calendar._angular.apply(function() { + calendar.onEventResized(args); + }); + } + } + else { + switch (calendar.eventResizeHandling) { + case 'PostBack': + calendar.eventResizePostBack(e, newStart, newEnd); + break; + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'JavaScript': + calendar.onEventResize(e, newStart, newEnd); + break; + } + } + }; + + this.eventMovePostBack = function(e, newStart, newEnd, newResource, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._postBack2('EventMove', data, params); + }; + + this.eventMoveCallBack = function(e, newStart, newEnd, newResource, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._callBack2('EventMove', data, params); + }; + + this._eventMoveDispatch = function (e, newColumnIndex, shadowTop, ev) { + var _startOffset = 1; + var step = Math.floor((shadowTop - _startOffset) / calendar.cellHeight); + + var boxStart = step * 30 * 60 * 1000; + var start = e.start(); + var end = e.end(); + var day = new Date(); + + if (start instanceof DayPilot.Date) { + start = start.toDate(); + } + day.setTime(Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate())); + + var startOffset = start.getTime() - (day.getTime() + start.getUTCHours() * 3600 *1000 + Math.floor(start.getUTCMinutes()/30)*30*60*1000 ); + var length = end.getTime() - start.getTime(); + + var newColumn = this._columns[newColumnIndex]; + var newResource = newColumn.id; + + var date = newColumn.start.getTime(); + var newStartUTC = new Date(); + newStartUTC.setTime(date + boxStart + startOffset); + + var newStart = new DayPilot.Date(newStartUTC); + + var newEnd = newStart.addTime(length); + + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.newStart = newStart; + args.newEnd = newEnd; + args.newResource = newResource; + args.ctrl = ev.ctrlKey; + args.shift = ev.shiftKey; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventMove === 'function') { + calendar._angular.apply(function() { + calendar.onEventMove(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventMoveHandling) { + case 'PostBack': + calendar.eventMovePostBack(e, newStart, newEnd, newColumn.id); + break; + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd, newColumn.id); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + e.resource(newResource); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventMoved === 'function') { + calendar._angular.apply(function() { + calendar.onEventMoved(args); + }); + } + } + else { + switch (calendar.eventMoveHandling) { + case 'PostBack': + calendar.eventMovePostBack(e, newStart, newEnd, newColumn.id); + break; + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd, newColumn.id); + break; + case 'JavaScript': + calendar.onEventMove(e, newStart, newEnd, newColumn.id, false); + break; + } + } + + }; + + this.timeRangeSelectedPostBack = function(start, end, resource, data) { + + var range = {}; + range.start = start; + range.end = end; + + this._postBack2('TimeRangeSelected', data, range); + }; + + this.timeRangeSelectedCallBack = function(start, end, resource, data) { + + var range = {}; + range.start = start; + range.end = end; + + this._callBack2('TimeRangeSelected', data, range); + }; + + this._timeRangeSelectedDispatch = function (start, end, resource) { + + // make sure it's DayPilot.Date + start = new DayPilot.Date(start); + end = new DayPilot.Date(end); + + if (this._api2()) { + var args = {}; + args.start = start; + args.end = end; + args.resource = resource; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onTimeRangeSelect === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelect(args); + }); + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (calendar.timeRangeSelectedHandling) { + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end); + break; + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + } + + if (typeof calendar.onTimeRangeSelected === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelected(args); + }); + } + } + else { + switch (calendar.timeRangeSelectedHandling) { + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end); + break; + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + case 'JavaScript': + calendar.onTimeRangeSelected(start, end); + break; + } + } + }; + + this._onCellMousedown = function(ev) { + + if (DayPilotCalendar.selecting) { + return; + } + + if (calendar.timeRangeSelectedHandling === "Disabled") { + return; + } + + var button = ev.which; + if (button !== 1 && button !== 0) { // Khtml says first button is 0 + return; + } + + DayPilotCalendar.firstMousePos = DayPilot.mc(ev); + DayPilotCalendar.selecting = {}; + DayPilotCalendar.selecting.calendar = calendar; + if (DayPilotCalendar.selectedCells) { + calendar.clearSelection(); + DayPilotCalendar.selectedCells = []; + } + DayPilotCalendar.column = DayPilotCalendar.getColumn(this); + DayPilotCalendar.selectedCells.push(this); + DayPilotCalendar.firstSelected = this; + + DayPilotCalendar.topSelectedCell = this; + DayPilotCalendar.bottomSelectedCell = this; + + calendar._activateSelection(); + + return false; + }; + + this._activateSelection = function() { + var selection = this.getSelection(); + + (function activateSelectionNew() { + + var first = DayPilotCalendar.topSelectedCell; + var last = DayPilotCalendar.bottomSelectedCell; + + // var columnIndex = first.parentNode.cells.indexOf(first); + + var columnIndex = (function() { + // it's the new div cell + if (first.data) { + return first.data.x; + } + + var cells = first.parentNode.cells; + for (var i = 0; i < cells.length; i++) { + if (cells[i] === first) { + return i; + } + } + return -1; + })(); + + var col = calendar._columns[columnIndex]; + + if (!col) { + return; + } + + var colStart = col.start; + + var top = calendar.getPixels(first.start, colStart).boxTop; + var bottom = calendar.getPixels(last.end, colStart).boxBottom; + var height = bottom - top; + + var div = (function() { + if (calendar.nav.activeSelection) { + return calendar.nav.activeSelection; + } + var div = document.createElement("div"); + div.setAttribute("unselectable", "on"); + // div.style.zIndex = calendar._shadowZindex; + div.style.position = "absolute"; + div.style.left = "0px"; + div.style.width = "100%"; + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = calendar._prefixCssClass("_shadow_inner"); + + div.appendChild(inner); + + calendar.nav.events.rows[0].cells[columnIndex].selection.appendChild(div); + calendar.elements.selection.push(div); + calendar.nav.activeSelection = div; + + return div; + })(); + + // reset + div.className = calendar._prefixCssClass("_shadow"); + div.firstChild.innerHTML = ""; + + // position + div.style.top = top + "px"; + div.style.height = height + "px"; + + })(); + }; + + this._mousemove = function(ev) { + + if (typeof (DayPilotCalendar) === 'undefined') { + return; + } + + if (!DayPilotCalendar.selecting) { + return; + } + + var mousePos = DayPilot.mc(ev); + + var thisColumn = DayPilotCalendar.getColumn(this); + if (thisColumn !== DayPilotCalendar.column) { + return; + } + + // clean + calendar.clearSelection(); + + // new selected cells + if (mousePos.y < DayPilotCalendar.firstMousePos.y) { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsBelow(this); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.selectedCells[0]; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.firstSelected; + } + else { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsAbove(this); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.firstSelected; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.selectedCells[0]; + } + + calendar._activateSelection(); + }; + + this.getSelection = function() { + var start = DayPilotCalendar.topSelectedCell.start; + var end = DayPilotCalendar.bottomSelectedCell.end; + var resource = DayPilotCalendar.topSelectedCell.resource; + + return new DayPilot.Selection(start, end, resource, calendar); + }; + + this._getColumnForPixels = function(x) { + + if (x < 0) { + return null; + } + + var i = 0; + var cells = calendar.nav.events.rows[0].cells; + + for (var j = 0; j < cells.length; j++) { + var cell = cells[j]; + var width = cell.offsetWidth; + i += width; + if (x < i) { + return j; + } + } + return null; + }; + + this._table = {}; + this._table.getCellCoords = function() { + var result = {}; + result.x = 0; + result.y = 0; + + if (!calendar.coords) { + return null; + } + + result.x = calendar._getColumnForPixels(calendar.coords.x); + + var _startOffset = 0; + var row = Math.floor((calendar.coords.y - _startOffset) / calendar.cellHeight); + result.y = row; + + if (result.x < 0) { + return null; + } + + return result; + }; + + this.columns = {}; + this.columns.list = []; + + this.columns.load = function(url, success, error) { + + if (!url) { + throw new DayPilot.Exception("columns.load(): 'url' parameter required"); + } + + var onError = function(args) { + var largs = {}; + largs.exception = args.exception; + largs.request = args.request; + + if (typeof error === 'function') { + error(largs); + } + }; + + var onSuccess = function(args) { + var r = args.request; + var data; + + // it's supposed to be JSON + try { + data = JSON.parse(r.responseText); + } + catch (e) { + var fargs = {}; + fargs.exception = e; + onError(fargs); + return; + } + + if (DayPilot.isArray(data)) { + var sargs = {}; + sargs.preventDefault = function() { + this.preventDefault.value = true; + }; + sargs.data = data; + if (typeof success === "function") { + success(sargs); + } + + if (sargs.preventDefault.value) { + return; + } + + calendar.columns.list = data; + if (calendar._initialized) { + calendar.update(); + } + } + }; + + var usePost = calendar.columnsLoadMethod && calendar.columnsLoadMethod.toUpperCase() === "POST"; + + if (usePost) { + DayPilot.ajax({ + "method": "POST", + "url": url, + "success": onSuccess, + "error": onError + }); + } + else { + DayPilot.ajax({ + "method": "GET", + "url": url, + "success": onSuccess, + "error": onError + }); + } + }; + + + this._prepareColumns = function() { + var columns; + if (calendar.viewType !== "Resources") { + columns = this._createDaysViewColumns(); + } + else { + columns = calendar.columns.list; + } + + this._columns = []; + for (var i = 0; i < columns.length; i++) { + var c = this._activateColumn(columns[i]); + this._columns.push(c); + } + }; + + this._activateColumn = function(column) { + +/* + if (column.Start) { + column.start = column.Start; + column.html = column.InnerHTML; + column.name = column.Name; + } +*/ + var result = {}; + result.name = column.name; + result.html = column.html; + result.id = column.id; + result.toolTip = column.toolTip; + result.data = column; + + if (column.start) { + result.start = new DayPilot.Date(column.start); + } + else { + result.start = new DayPilot.Date(calendar.startDate); + } + + result.putIntoBlock = function(ep) { + + for (var i = 0; i < this.blocks.length; i++) { + var block = this.blocks[i]; + if (block.overlapsWith(ep.part.top, ep.part.height)) { + block.events.push(ep); + block.min = Math.min(block.min, ep.part.top); + block.max = Math.max(block.max, ep.part.top + ep.part.height); + return i; + } + } + + // no suitable block found, create a new one + var block = []; + block.lines = []; + block.events = []; + + block.overlapsWith = function(start, width) { + var end = start + width - 1; + + if (!(end < this.min || start > this.max - 1)) { + return true; + } + + return false; + }; + block.putIntoLine = function (ep) { + var thisCol = this; + + for (var i = 0; i < this.lines.length; i++) { + var line = this.lines[i]; + if (line.isFree(ep.part.top, ep.part.height)) { + line.push(ep); + return i; + } + } + + var line = []; + line.isFree = function(start, width) { + var end = start + width - 1; + var max = this.length; + + for (var i = 0; i < max; i++) { + var e = this[i]; + if (!(end < e.part.top || start > e.part.top + e.part.height - 1)) { + return false; + } + } + + return true; + }; + + line.push(ep); + + this.lines.push(line); + + return this.lines.length - 1; + + }; + + block.events.push(ep); + block.min = ep.part.top; + block.max = ep.part.top + ep.part.height; + + this.blocks.push(block); + + return this.blocks.length - 1; + + }; + + result.putIntoLine = function(ep) { + var thisCol = this; + + for (var i = 0; i < this.lines.length; i++) { + var line = this.lines[i]; + if (line.isFree(ep.part.top, ep.part.height)) { + line.push(ep); + return i; + } + } + + var line = []; + line.isFree = function(start, width) { + var end = start + width - 1; + var max = this.length; + + for (var i = 0; i < max; i++) { + var e = this[i]; + if (!(end < e.part.top || start > e.part.top + e.part.height - 1)) { + return false; + } + } + + return true; + }; + + line.push(ep); + + this.lines.push(line); + + return this.lines.length - 1; + }; + + return result; + + }; + + this._createDaysViewColumns = function() { + var columns = []; + + var start = this.startDate.getDatePart(); + + var days = this.days; + switch (this.viewType) { + case "Day": + days = 1; + break; + case "Week": + days = 7; + var weekStarts = resolved._weekStarts(); + start = start.firstDayOfWeek(weekStarts); + break; + case "WorkWeek": + days = 5; + start = start.firstDayOfWeek(1); // Monday + break; + } + + if (this.heightSpec === 'BusinessHoursNoScroll') { + start = start.addHours(this.businessBeginsHour); + } + + for (var i = 0; i < days; i++) { + + var format = calendar.headerDateFormat ? calendar.headerDateFormat : resolved.locale().datePattern; + + var column = {}; + column.start = start.addDays(i); + column.name = column.start.toString(format, resolved.locale()); + + columns.push(column); + } + + return columns; + }; + + this.visibleStart = function() { + if (calendar.viewType === "Resources") { + if (calendar._columns.length === 0) { + return DayPilot.Date.today(); + } + var dates = calendar._columns.map(function(column) { + return column.start.getTime(); + }); + var min = Math.min.apply(null, dates); + return new DayPilot.Date(min); + } + return this._columns[0].start; + }; + + this.visibleEnd = function() { + if (calendar.viewType === "Resources") { + if (calendar._columns.length === 0) { + return DayPilot.Date.today().addDays(1); + } + var dates = calendar._columns.map(function(column) { + return column.start.getTime(); + }); + var max = Math.max.apply(null, dates); + return new DayPilot.Date(max).addDays(1); + } + var max = this._columns.length - 1; + return this._columns[max].start.addDays(1); + }; + + + this._prefixCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + if (prefix) { + return prefix + part; + } + else { + return ""; + } + }; + + this._deleteEvents = function() { + + if (this.elements.events) { + + for (var i = 0; i < this.elements.events.length; i++) { + var div = this.elements.events[i]; + + var object = div.event; + if (object) { + object.calendar = null; + } + + div.onclick = null; + div.onclickSave = null; + div.onmouseover = null; + div.onmouseout = null; + div.onmousemove = null; + div.onmousedown = null; + + if (div.firstChild && div.firstChild.firstChild && div.firstChild.firstChild.tagName && div.firstChild.firstChild.tagName.toUpperCase() === 'IMG') { + var img = div.firstChild.firstChild; + img.onmousedown = null; + img.onmousemove = null; + img.onclick = null; + + } + + div.helper = null; + div.data = null; + div.event = null; + + DayPilot.de(div); + } + } + this.elements.events = []; + }; + + this._drawEvent = function(e) { + /* + + supported e.data properties: + * text + * html + * cssClass + * backColor + * barColor + * barBackColor + * toolTip + * barHidden + * borderColor + * fontColor + + */ + + + var data = e.cache || e.data; + + var main = this.nav.events; + + var rounded = true; + var radius = true; + var pixels = false; + + // var borderColor = this.eventBorderColor; + + var div = document.createElement("div"); + div.style.position = 'absolute'; + div.style.left = e.part.left + '%'; + div.style.top = (e.part.top) + 'px'; + div.style.width = e.part.width + '%'; + div.style.height = Math.max(e.part.height, 2) + 'px'; + div.style.overflow = 'hidden'; + + // TODO unify + div.data = e; + div.event = e; + + div.unselectable = 'on'; + div.style.MozUserSelect = 'none'; + div.style.KhtmlUserSelect = 'none'; + + div.className = this._prefixCssClass("_event"); + + if (data.cssClass) { + DayPilot.Util.addClass(div, data.cssClass); + } + + if (calendar.showToolTip && e.client.toolTip()) { + div.title = e.client.toolTip(); + } + + div.isFirst = e.part.start.getTime() === e.start().getTime(); + div.isLast = e.part.end.getTime() === e.end().getTime(); + + div.onclick = this._eventClickDispatch; + DayPilot.re(div, "contextmenu", this._eventRightClickDispatch); + + div.onmouseout = function(ev) { + if (div.deleteIcon) { + div.deleteIcon.style.display = "none"; + } + }; + + div.onmousemove = function (ev) { + // const + var resizeMargin = 5; + + if (typeof(DayPilotCalendar) === 'undefined') { + return; + } + + // position + var offset = DayPilot.mo3(div, ev); + if (!offset) { + return; + } + + if (DayPilotCalendar.resizing || DayPilotCalendar.moving) { + return; + } + + if (div.deleteIcon) { + div.deleteIcon.style.display = ""; + } + + var isLastPart = this.isLast; + + if (offset.y <= resizeMargin && e.client.resizeEnabled()) { + this.style.cursor = "n-resize"; + this.dpBorder = 'top'; + } + else if (this.offsetHeight - offset.y <= resizeMargin && e.client.resizeEnabled()) { + if (isLastPart) { + this.style.cursor = "s-resize"; + this.dpBorder = 'bottom'; + } + else { + this.style.cursor = 'not-allowed'; + } + } + else if (!DayPilotCalendar.resizing && !DayPilotCalendar.moving) { + if (calendar.eventClickHandling !== 'Disabled') { + this.style.cursor = 'pointer'; + } + else { + this.style.cursor = 'default'; + } + } + + }; + + div.onmousedown = function (ev) { + var button = ev.which || ev.button; + + if ((this.style.cursor === 'n-resize' || this.style.cursor === 's-resize') && button === 1) { + // set + DayPilotCalendar.resizing = this; + DayPilot.Global.resizing = this; + DayPilotCalendar.originalMouse = DayPilot.mc(ev); + DayPilotCalendar.originalHeight = this.offsetHeight; + DayPilotCalendar.originalTop = this.offsetTop; + + calendar.nav.top.style.cursor = this.style.cursor; + + } + else if (button === 1 && e.client.moveEnabled()) { + DayPilotCalendar.moving = this; + DayPilot.Global.moving = this; + DayPilotCalendar.moving.event = this.event; + var helper = DayPilotCalendar.moving.helper = {}; + helper.oldColumn = calendar._columns[this.data.part.dayIndex].id; + DayPilotCalendar.originalMouse = DayPilot.mc(ev); + DayPilotCalendar.originalTop = this.offsetTop; + + var offset = DayPilot.mo3(this, ev); + if (offset) { + DayPilotCalendar.moveOffsetY = offset.y; + } + else { + DayPilotCalendar.moveOffsetY = 0; + } + + // cursor + //document.body.style.cursor = 'move'; + calendar.nav.top.style.cursor = 'move'; + } + + return false; + }; + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = calendar._prefixCssClass("_event_inner"); + inner.innerHTML = e.client.html(); + + if (data.borderColor === "darker" && data.backColor) { + inner.style.borderColor = DayPilot.ColorUtil.darker(data.backColor, 2); + } + else { + inner.style.borderColor = data.borderColor; + } + + if (data.backColor) { + inner.style.background = data.backColor; + } + + if (data.fontColor) { + inner.style.color = data.fontColor; + } + + div.appendChild(inner); + + // TODO + if (e.client.barVisible()) { + var height = e.part.height - 2; + var barTop = 100 * e.part.barTop / height; // % + var barHeight = Math.ceil(100 * e.part.barHeight / height); // % + + var bar = document.createElement("div"); + bar.setAttribute("unselectable", "on"); + bar.className = this._prefixCssClass("_event_bar"); + bar.style.position = "absolute"; + + if (data.barBackColor) { + bar.style.backgroundColor = data.barBackColor; + } + + var barInner = document.createElement("div"); + barInner.setAttribute("unselectable", "on"); + barInner.className = this._prefixCssClass("_event_bar_inner"); + barInner.style.top = barTop + "%"; + if (0 < barHeight && barHeight <= 1) { + barInner.style.height = "1px"; + } + else { + barInner.style.height = barHeight + "%"; + } + + if (data.barColor) { + barInner.style.backgroundColor = data.barColor; + } + + bar.appendChild(barInner); + div.appendChild(bar); + } + + if (e.client.deleteEnabled()) { + var del = document.createElement("div"); + del.style.position = "absolute"; + del.style.right = "2px"; + del.style.top = "2px"; + del.style.width = "17px"; + del.style.height = "17px"; + del.className = calendar._prefixCssClass("_event_delete"); + del.onmousedown = function(ev) { + ev.stopPropagation(); + }; + del.onclick = function(ev) { + ev.stopPropagation(); + var e = this.parentNode.event; + if (e) { + calendar._eventDeleteDispatch(e); + } + }; + del.style.display = "none"; + div.deleteIcon = del; + div.appendChild(del); + } + + // areas + var areas = data.areas ? DayPilot.Areas.copy(data.areas) : []; + +/* var col = calendar._columnsBottom[e.part.dayIndex]; + + areas.forEach(function(area) { + if (area.start) { + area.top = calendar._getPixels(new DayPilot.Date(area.start), col.start).top - e.part.top - calendar._autoHiddenPixels(); + } + if (area.end) { + area.bottom = e.part.top + e.part.height - calendar._getPixels(new DayPilot.Date(area.end), col.start).top - calendar._autoHiddenPixels(); + } + }); + + if (e.client.deleteEnabled()) { + areas.push({"action":"JavaScript","v":"Hover","w":17,"h":17,"top":2,"right":2, "css": calendar._prefixCssClass("_event_delete"),"js":function(e) { calendar._eventDeleteDispatch(e); } }); + }*/ + + DayPilot.Areas.attach(div, e, {"areas": areas}); + + if (main.rows[0].cells[e.part.dayIndex]) { // temporary fix for multirow header, but won't hurt later + var wrapper = main.rows[0].cells[e.part.dayIndex].firstChild; + wrapper.appendChild(div); + + calendar._makeChildrenUnselectable(div); + + //var e = new DayPilotCalendar.Event(div, calendar); + } + + if (typeof calendar.onAfterEventRender === 'function') { + var args = {}; + args.e = div.event; + args.div = div; + + calendar.onAfterEventRender(args); + } + + calendar.elements.events.push(div); + }; + + this._makeChildrenUnselectable = function(el) { + var c = (el && el.childNodes) ? el.childNodes.length : 0; + for (var i = 0; i < c; i++) { + try { + var child = el.childNodes[i]; + if (child.nodeType === 1) { + child.unselectable = 'on'; + this._makeChildrenUnselectable(child); + } + } + catch (e) { + } + } + }; + + this._drawEvents = function() { + + //var start = new Date(); + + for (var i = 0; i < this._columns.length; i++) { + var col = this._columns[i]; + if (!col.blocks) { + continue; + } + + for (var m = 0; m < col.blocks.length; m++) { + var block = col.blocks[m]; + for (var j = 0; j < block.lines.length; j++) { + var line = block.lines[j]; + + for(var k = 0; k < line.length; k++) { + var e = line[k]; + + e.part.width = 100 / block.lines.length; + e.part.left = e.part.width * j; + + var isLastBlock = (j === block.lines.length - 1); + if (!isLastBlock) { + e.part.width = e.part.width * 1.5; + } + + this._drawEvent(e); + } + } + } + } + + //var end = new Date(); + //var diff = end.getTime() - start.getTime(); + }; + + this._drawTop = function() { + + //this.nav.top = document.getElementById(this.id); + this.nav.top.innerHTML = ''; + + DayPilot.Util.addClass(this.nav.top, this._prefixCssClass("_main")); + + this.nav.top.style.MozUserSelect = 'none'; + this.nav.top.style.KhtmlUserSelect = 'none'; + this.nav.top.style.position = 'relative'; + this.nav.top.style.width = this.width ? this.width : '100%'; + + if (this.hideUntilInit) { + this.nav.top.style.visibility = 'hidden'; + } + + if (!this.visible) { + this.nav.top.style.display = "none"; + } + + this.nav.scroll = document.createElement("div"); + this.nav.scroll.style.height = this._getScrollableHeight() + "px"; + + if (this.heightSpec === 'BusinessHours') { + this.nav.scroll.style.overflow = "auto"; + } + else + { + this.nav.scroll.style.overflow = "hidden"; + } + + this.nav.scroll.style.position = "relative"; + + var header = this._drawTopHeaderDiv(); + this.nav.top.appendChild(header); + + // fixing the column alignment bug + // solved thanks to http://stackoverflow.com/questions/139000/div-with-overflowauto-and-a-100-wide-table-problem + this.nav.scroll.style.zoom = 1; + + var wrap = this._drawScrollable(); + this.nav.scrollable = wrap.firstChild; + this.nav.scroll.appendChild(wrap); + this.nav.top.appendChild(this.nav.scroll); + + this.nav.scrollLayer = document.createElement("div"); + this.nav.scrollLayer.style.position = 'absolute'; + this.nav.scrollLayer.style.top = '0px'; + this.nav.scrollLayer.style.left = '0px'; + this.nav.top.appendChild(this.nav.scrollLayer); + + this.nav.loading = document.createElement("div"); + this.nav.loading.style.position = 'absolute'; + this.nav.loading.style.top = '0px'; + this.nav.loading.style.left = (this.hourWidth + 5) + "px"; + // this.nav.loading.style.backgroundColor = this.loadingLabelBackColor; + // this.nav.loading.style.fontSize = this.loadingLabelFontSize; + // this.nav.loading.style.fontFamily = this.loadingLabelFontFamily; + // this.nav.loading.style.color = this.loadingLabelFontColor; + // this.nav.loading.style.padding = '2px'; + this.nav.loading.innerHTML = calendar._xssTextHtml(calendar.loadingLabelText, calendar.loadingLabelHtml); + this.nav.loading.style.display = 'none'; + + this.nav.top.appendChild(this.nav.loading); + + }; + + // used during full update + this._drawHourTable = function() { + // clear old hour table + if (!this.fasterDispose) DayPilot.pu(this.nav.hourTable); + this.nav.scrollable.rows[0].cells[0].innerHTML = ''; + this.nav.hourTable = this._createHourTable(); + this.nav.scrollable.rows[0].cells[0].appendChild(this.nav.hourTable); + }; + + // used during initial load only + this._drawScrollable = function() { + var zoom = document.createElement("div"); + zoom.style.zoom = 1; + zoom.style.position = 'relative'; + // zoom.onmousemove = calendar._mousemove; + + var table = document.createElement("table"); + + table.cellSpacing = "0"; + table.cellPadding = "0"; + table.border = "0"; + table.style.border = "0px none"; + table.style.width = "100%"; + table.style.position = 'absolute'; + + var r = table.insertRow(-1); + + var c; + c = r.insertCell(-1); + c.valign = "top"; + c.style.padding = '0px'; + c.style.border = '0px none'; + + this.nav.hourTable = this._createHourTable(); + c.appendChild(this.nav.hourTable); + + c = r.insertCell(-1); + c.valign = "top"; + c.width = "100%"; + c.style.padding = '0px'; + c.style.border = '0px none'; + + var wrap = document.createElement("div"); + wrap.style.position = "relative"; + c.appendChild(wrap); + + wrap.appendChild(this._createEventsAndCells()); + wrap.appendChild(this._createEventsTable()); + + zoom.appendChild(table); + + this.nav.zoom = zoom; + + return zoom; + }; + + this._createEventsAndCells = function() { + var table = document.createElement("table"); + + table.cellPadding = "0"; + table.cellSpacing = "0"; + table.border = "0"; + table.style.width = "100%"; + table.style.border = "0px none"; + table.style.tableLayout = 'fixed'; + + this.nav.main = table; + this.nav.events = table; + + return table; + }; + + this._createEventsTable = function() { + var table = document.createElement("table"); + + //table.style.position = "absolute"; + table.style.top = "0px"; + table.cellPadding = "0"; + table.cellSpacing = "0"; + table.border = "0"; + table.style.position = "absolute"; + table.style.width = "100%"; + table.style.border = "0px none"; + table.style.tableLayout = 'fixed'; + //table.setAttribute("events", "true"); + + this.nav.events = table; + var create = true; + var columns = this._columns; + var cl = columns.length; + + var r = (create) ? table.insertRow(-1) : table.rows[0]; + + for (var j = 0; j < cl; j++) { + var c = (create) ? r.insertCell(-1) : r.cells[j]; + + if (create) { + + c.style.padding = '0px'; + c.style.border = '0px none'; + c.style.height = '0px'; + c.style.overflow = 'visible'; + if (!calendar.rtl) { + c.style.textAlign = 'left'; + } + + // withpct + //c.style.width = (100.0 / columns.length) + "%"; + + var div = document.createElement("div"); + div.style.marginRight = calendar.columnMarginRight + "px"; + div.style.position = 'relative'; + div.style.height = '1px'; + div.style.marginTop = '-1px'; + + var selection = document.createElement("div"); + c.selection = selection; + + c.appendChild(div); + c.appendChild(selection); + + } + } + + return table; + }; + + this._createHourTable = function() { + var table = document.createElement("table"); + table.cellSpacing = "0"; + table.cellPadding = "0"; + table.border = "0"; + table.style.border = '0px none'; + table.style.width = this.hourWidth + "px"; + table.oncontextmenu = function() { return false; }; + + var hours = calendar._durationHours(); + for (var i = 0; i < hours; i++) { + this._createHourRow(table, i); + } + + return table; + + }; + + this._createHourRow = function(table, i) { + var height = (this.cellHeight * 2); + + var r = table.insertRow(-1); + r.style.height = height + "px"; + + var c = r.insertCell(-1); + c.valign = "bottom"; + c.unselectable = "on"; + c.style.cursor = "default"; + c.style.padding = '0px'; + c.style.border = '0px none'; + + var frame = document.createElement("div"); + frame.style.position = "relative"; + frame.className = this._prefixCssClass("_rowheader"); + frame.style.width = this.hourWidth + "px"; + frame.style.height = (height) + "px"; + frame.style.overflow = 'hidden'; + frame.unselectable = 'on'; + + var block = document.createElement("div"); + block.className = this._prefixCssClass("_rowheader_inner"); + block.unselectable = "on"; + + var text = document.createElement("div"); + text.unselectable = "on"; + + var start = this.startDate.addHours(i).addHours(calendar._visibleStart()); + var hour = start.getHours(); + + var am = hour < 12; + var timeFormat = resolved.timeFormat(); + if (timeFormat === "Clock12Hours") { + hour = hour % 12; + if (hour === 0) { + hour = 12; + } + } + + text.innerHTML = hour; + + var span = document.createElement("span"); + span.unselectable = "on"; + span.className = this._prefixCssClass("_rowheader_minutes"); + + var sup; + if (timeFormat === "Clock12Hours") { + if (am) { + sup = "AM"; + } + else { + sup = "PM"; + } + } + else { + sup = "00"; + } + + span.innerHTML = sup; + + text.appendChild(span); + + block.appendChild(text); + + frame.appendChild(block); + + c.appendChild(frame); + }; + + this._getScrollableHeight = function() { + switch (this.heightSpec) { + case "Full": + return (24 * 2 * this.cellHeight); + case "BusinessHours": + var dHours = this._businessHoursSpan(); + return dHours * this.cellHeight * 2; + case "BusinessHoursNoScroll": + var dHours = this._businessHoursSpan(); + return dHours * this.cellHeight * 2; + default: + throw "DayPilot.Calendar: Unexpected 'heightSpec' value."; + + } + }; + + this._updateCorner = function() { + var parent = calendar.nav.corner ? calendar.nav.corner.parentNode : null; + if (!parent) { + return; + } + + parent.innerHTML = ''; + + var corner = this._drawCorner(); + parent.appendChild(corner); + calendar.nav.corner = corner; + + }; + + this._drawTopHeaderDiv = function() { + var header = document.createElement("div"); + header.style.overflow = "auto"; + + var table = document.createElement("table"); + table.cellPadding = "0"; + table.cellSpacing = "0"; + table.border = "0"; + table.style.width = "100%"; + table.style.borderCollapse = 'separate'; + table.style.border = "0px none"; + + var r = table.insertRow(-1); + + // corner + var c = r.insertCell(-1); + c.style.padding = '0px'; + c.style.border = '0px none'; + + var corner = this._drawCorner(); + c.appendChild(corner); + this.nav.corner = corner; + + // top header + c = r.insertCell(-1); + + c.style.width = "100%"; + c.valign = "top"; + c.style.position = 'relative'; // ref point + c.style.padding = '0px'; + c.style.border = '0px none'; + + this.nav.header = document.createElement("table"); + this.nav.header.cellPadding = "0"; + this.nav.header.cellSpacing = "0"; + this.nav.header.border = "0"; + this.nav.header.width = "100%"; + this.nav.header.style.tableLayout = "fixed"; + this.nav.header.oncontextmenu = function() { return false; }; + + var scrollbar = this.nav.scroll.style.overflow !== 'hidden'; + c.appendChild(this.nav.header); + + if (scrollbar) { + c = r.insertCell(-1); + c.unselectable = "on"; + + var inside = document.createElement("div"); + inside.unselectable = "on"; + inside.style.position = "relative"; + inside.style.width = "16px"; + inside.style.height = this.headerHeight + "px"; + inside.className = this._prefixCssClass("_cornerright"); + + var inner = document.createElement("div"); + inner.className = this._prefixCssClass('_cornerright_inner'); + inside.appendChild(inner); + + c.appendChild(inside); + + this.nav.cornerRight = inside; + } + + header.appendChild(table); + + return header; + + }; + + this._drawCorner = function() { + var wrap = document.createElement("div"); + wrap.style.position = 'relative'; + wrap.className = this._prefixCssClass("_corner"); + wrap.style.width = this.hourWidth + "px"; + wrap.style.height = this.headerHeight + "px"; + wrap.oncontextmenu = function() { return false; }; + + var corner = document.createElement("div"); + corner.unselectable = "on"; + corner.className = this._prefixCssClass("_corner_inner"); + + wrap.appendChild(corner); + + return wrap; + }; + + this._disposeMain = function() { + var table = this.nav.main; + table.root = null; + table.onmouseup = null; + + for (var y = 0; y < table.rows.length; y++) { + var r = table.rows[y]; + for (var x = 0; x < r.cells.length; x++) { + var c = r.cells[x]; + c.root = null; + + c.onmousedown = null; + c.onmousemove = null; + c.onmouseout = null; + c.onmouseup = null; + } + } + + if (!this.fasterDispose) DayPilot.pu(table); + }; + + // draw time cells + this._drawMain = function() { + + //DayPilotCalendar.selectedCells = []; + var cols = []; + var dates = []; + + var table = this.nav.main; + var step = 30 * 60 * 1000; + var rowCount = this._rowCount(); + + var columns = calendar._columns; + //var create = !this.tableCreated || columns.length !== table.rows[0].cells.length || rowCount !== table.rows.length; // redraw only if number of columns changes + var create = true; + + if (table) { + this._disposeMain(); + } + + while (table && table.rows && table.rows.length > 0 && create) { + if (!this.fasterDispose) { + DayPilot.pu(table.rows[0]); + } + table.deleteRow(0); + } + + this.tableCreated = true; + + var cl = columns.length; + + var events = this.nav.events; + while (events && events.rows && events.rows.length > 0 && create) { + if (!this.fasterDispose) { + DayPilot.pu(events.rows[0]); + } + events.deleteRow(0); + } + + var cl = columns.length; + + var r = (create) ? events.insertRow(-1) : events.rows[0]; + + for (var j = 0; j < cl; j++) { + var c = (create) ? r.insertCell(-1) : r.cells[j]; + + if (create) { + + c.style.padding = '0px'; + c.style.border = '0px none'; + c.style.height = '0px'; + c.style.overflow = 'visible'; + if (!calendar.rtl) { + c.style.textAlign = 'left'; + } + + // withpct + //c.style.width = (100.0 / columns.length) + "%"; + + var div = document.createElement("div"); + div.style.marginRight = calendar.columnMarginRight + "px"; + div.style.position = 'relative'; + div.style.height = '1px'; + div.style.marginTop = '-1px'; + + var selection = document.createElement("div"); + selection.style.position = "relative"; + c.selection = selection; + + c.appendChild(div); + c.appendChild(selection); + + } + } + + for (var i = 0; i < rowCount; i++) { + var r = (create) ? table.insertRow(-1) : table.rows[i]; + + if (create) { + r.style.MozUserSelect = 'none'; + r.style.KhtmlUserSelect = 'none'; + } + + for (var j = 0; j < cl; j++) { + var col = this._columns[j]; + + var c = (create) ? r.insertCell(-1) : r.cells[j]; + + // always update + c.start = col.start.addTime(i * step); + c.end = c.start.addTime(step); + c.resource = col.id; + + c.onmousedown = this._onCellMousedown; + // c.onmousemove = this._mousemove; + c.onmouseup = function() { + return false; + }; + + c.onclick = function() { + return false; + }; + + if (create) { + c.root = this; + + c.style.padding = '0px'; + c.style.border = '0px none'; + c.style.verticalAlign = 'top'; + c.style.height = calendar.cellHeight + 'px'; + c.style.overflow = 'hidden'; + c.unselectable = 'on'; + + var div = document.createElement("div"); + div.unselectable = 'on'; + div.style.height = calendar.cellHeight + "px"; + div.style.position = "relative"; + div.className = this._prefixCssClass("_cell"); + + var business = this._isBusinessCell(c.start, c.end); + + var properties = { + "business": business, + "text": null, + "html": null, + "cssClass": null, + "backColor": null, + "backImage": null, + "backRepeat": null, + }; + + (function() { + if (typeof calendar.onBeforeCellRender === 'function') { + var args = {}; + args.cell = { + "start": c.start, + "end": c.end, + "resource": c.resource, + "properties": properties + }; + calendar.onBeforeCellRender(args); + } + })(); + + + if (properties.business) { + DayPilot.Util.addClass(div, calendar._prefixCssClass("_cell_business")); + } + + if (properties.cssClass) { + DayPilot.Util.addClass(div, properties.cssClass); + } + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = this._prefixCssClass("_cell_inner"); + + var html = DayPilot.Util.escapeTextHtml(properties.text, properties.html); + if (html) { + inner.innerHTML = html; + } + + if (properties.backColor) { + inner.style.backgroundColor = properties.backColor; + } + + if (properties.backImage) { + inner.style.backgroundImage = "url(" + properties.backImage + ")"; + } + + if (properties.backRepeat) { + inner.style.backgroundRepeat = properties.backRepeat; + } + + div.appendChild(inner); + c.appendChild(div); + + c.appendChild(div); + + } + } + } + + table.root = this; + + calendar.nav.scrollable.onmousemove = function(ev) { + var ref = calendar.nav.scrollable; + calendar.coords = DayPilot.mo3(ref, ev); + + var mousePos = DayPilot.mc(ev); + + if (DayPilotCalendar.resizing) { + if (!DayPilotCalendar.resizingShadow) { + DayPilotCalendar.resizingShadow = calendar._createShadow(DayPilotCalendar.resizing, false, calendar.shadow); + } + + var _step = calendar.cellHeight; + var _startOffset = 1; + var delta = (mousePos.y - DayPilotCalendar.originalMouse.y); + + // TODO: clear + if (DayPilotCalendar.resizing.dpBorder === 'bottom') { + var newHeight = Math.floor(((DayPilotCalendar.originalHeight + DayPilotCalendar.originalTop + delta) + _step / 2) / _step) * _step - DayPilotCalendar.originalTop + _startOffset; + + if (newHeight < _step) + newHeight = _step; + + var max = calendar.nav.main.clientHeight; + if (DayPilotCalendar.originalTop + newHeight > max) + newHeight = max - DayPilotCalendar.originalTop; + + // DayPilotCalendar.resizingShadow.style.height = (newHeight - 4) + 'px'; + DayPilotCalendar.resizingShadow.style.height = (newHeight) + 'px'; + } + else if (DayPilotCalendar.resizing.dpBorder === 'top') { + var newTop = Math.floor(((DayPilotCalendar.originalTop + delta - _startOffset) + _step / 2) / _step) * _step + _startOffset; + + if (newTop < _startOffset) { + newTop = _startOffset; + } + + if (newTop > DayPilotCalendar.originalTop + DayPilotCalendar.originalHeight - _step) { + newTop = DayPilotCalendar.originalTop + DayPilotCalendar.originalHeight - _step; + } + + // var newHeight = DayPilotCalendar.originalHeight - (newTop - DayPilotCalendar.originalTop) - 4; + var newHeight = DayPilotCalendar.originalHeight - (newTop - DayPilotCalendar.originalTop); + + if (newHeight < _step) { + newHeight = _step; + } + else { + DayPilotCalendar.resizingShadow.style.top = newTop + 'px'; + } + + DayPilotCalendar.resizingShadow.style.height = (newHeight) + 'px'; + } + } + else if (DayPilotCalendar.moving) { + + if (!calendar.coords) { + return; + } + + if (!DayPilotCalendar.movingShadow) { + + var minDistance = 3; + var mousePos = DayPilot.mc(ev); + var distance = Math.abs(mousePos.x - DayPilotCalendar.originalMouse.x) + Math.abs(mousePos.y - DayPilotCalendar.originalMouse.y); + if (distance <= minDistance) { + return; + } + // fixes the ie8 bug (incorrect offsetX and offsetY causes flickering during move if there are inline elements in the event + DayPilotCalendar.movingShadow = calendar._createShadow(DayPilotCalendar.moving, true, calendar.shadow); + DayPilotCalendar.movingShadow.style.width = (DayPilotCalendar.movingShadow.parentNode.offsetWidth + 1) + 'px'; + } + + var _step = calendar.cellHeight; + var _startOffset = 1; + + var offset = DayPilotCalendar.moveOffsetY; + if (!offset) { + offset = _step / 2; // for external drag + } + + var newTop = Math.floor(((calendar.coords.y - offset - _startOffset) + _step / 2) / _step) * _step + _startOffset; + + if (newTop < _startOffset) { + newTop = _startOffset; + } + + var main = calendar.nav.events; + var max = calendar.nav.main.clientHeight + _startOffset; + + var height = parseInt(DayPilotCalendar.movingShadow.style.height); // DayPilotCalendar.moving.data.height + if (newTop + height > max) { + newTop = max - height; + } + + DayPilot.Util.addClass(DayPilotCalendar.moving, calendar._prefixCssClass("_event_moving_source")); + + DayPilotCalendar.movingShadow.parentNode.style.display = 'none'; + DayPilotCalendar.movingShadow.style.top = newTop + 'px'; + DayPilotCalendar.movingShadow.parentNode.style.display = ''; + + var colWidth = main.clientWidth / main.rows[0].cells.length; + var column = Math.floor((calendar.coords.x - 45) / colWidth); + + if (column < 0) { + column = 0; + } + + if (column < main.rows[0].cells.length && column >= 0 && DayPilotCalendar.movingShadow.column !== column) { + DayPilotCalendar.movingShadow.column = column; + DayPilotCalendar.moveShadow(main.rows[0].cells[column]); + } + } + else if (DayPilotCalendar.selecting) { + + var mousePos = DayPilot.mc(ev); + + var cellcoords = calendar._table.getCellCoords(); + var x = DayPilotCalendar.column; + var cell = calendar.nav.main.rows[cellcoords.y].cells[x]; + + + // clean + // calendar.clearSelection(); + + // new selected cells + if (mousePos.y < DayPilotCalendar.firstMousePos.y) { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsBelow(cell); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.selectedCells[0]; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.firstSelected; + } + else { + DayPilotCalendar.selectedCells = DayPilotCalendar.getCellsAbove(cell); + DayPilotCalendar.topSelectedCell = DayPilotCalendar.firstSelected; + DayPilotCalendar.bottomSelectedCell = DayPilotCalendar.selectedCells[0]; + } + + calendar._activateSelection(); + + } + }; + calendar.nav.scrollable.style.display = ''; + }; + + this._isBusinessCell = function(start, end) { + if (this.businessBeginsHour < this.businessEndsHour) + { + return !(start.getHours() < this.businessBeginsHour || start.getHours() >= this.businessEndsHour || start.getDayOfWeek() === 6 || start.getDayOfWeek() === 0); + } + + if (start.getHours() >= this.businessBeginsHour) + { + return true; + } + + if (start.getHours() < this.businessEndsHour) + { + return true; + } + + return false; + }; + + this._disposeHeader = function() { + var table = this.nav.header; + if (table && table.rows) { + for(var y = 0; y < table.rows.length; y++) { + var r = table.rows[y]; + for (var x = 0; x < r.cells.length; x++) { + var c = r.cells[x]; + c.onclick = null; + c.onmousemove = null; + c.onmouseout = null; + } + } + } + if (!this.fasterDispose) DayPilot.pu(table); + }; + + this._drawHeaderRow = function(create) { + + // column headers + var r = (create) ? this.nav.header.insertRow(-1) : this.nav.header.rows[0]; + + var columns = this._columns; + + var len = columns.length; + + function drawHeaderCell(i) { + var data = columns[i]; + + var cell = (create) ? r.insertCell(-1) : r.cells[i]; + cell.data = data; + + cell.style.overflow = 'hidden'; + cell.style.padding = '0px'; + cell.style.border = '0px none'; + cell.style.height = (calendar.headerHeight) + "px"; + + cell.onclick = calendar._headerClickDispatch; + + var div = (create) ? document.createElement("div") : cell.firstChild; + var inner; + + if (create) { + div.unselectable = 'on'; + div.style.MozUserSelect = 'none'; + div.style.cursor = 'default'; + div.style.position = 'relative'; + div.className = calendar._prefixCssClass('_colheader'); + div.style.height = calendar.headerHeight + "px"; + + if (!calendar.headerTextWrappingEnabled) { + div.style.whiteSpace = 'nowrap'; + } + + inner = document.createElement("div"); + inner.className = calendar._prefixCssClass('_colheader_inner'); + inner.unselectable = 'on'; + + div.appendChild(inner); + cell.appendChild(div); + } + else { + inner = div.firstChild; + } + + var args = {}; + args.header = {}; + args.header.cssClass = null; + args.header.verticalAlignment = "center"; + args.column = calendar._createColumn(data, calendar); + + if (typeof calendar.onBeforeHeaderRender === 'function') { + DayPilot.Util.copyProps(data, args.header, ['id', 'start', 'name', 'html', 'backColor', 'toolTip', 'areas']); + calendar.onBeforeHeaderRender(args); + DayPilot.Util.copyProps(args.header, data, ['html', 'backColor', 'toolTip', 'areas', 'cssClass', 'verticalAlignment']); + } + + if (data.toolTip) { + inner.title = data.toolTip; + } + + if (data.cssClass) { + DayPilot.Util.addClass(div, data.cssClass); + } + + if (data.backColor) { + inner.style.background = data.backColor; + } + + if (data.areas) { + DayPilot.Areas.attach(div, data); + } + + var va = data.verticalAlignment; + if (va) { + inner.style.display = "flex"; + switch (va) { + case "center": + inner.style.alignItems = "center"; + break; + case "top": + inner.style.alignItems = "flex-start"; + break; + case "bottom": + inner.style.alignItems = "flex-end"; + break; + } + } + + var text = div.firstChild; + text.innerHTML = calendar._xssTextHtml(data.name, data.html); + } + + for (var i = 0; i < len; i++) { + drawHeaderCell(i); + } + }; + + this._headerClickDispatch = function(ev) { + + var handling = calendar.headerClickHandling; + + if (handling === "Disabled") { + return; + } + + var data = this.data; + var c = calendar._createColumn(data); + + var args = {}; + args.header = {}; + args.header.id = data.id; + args.header.name = data.name; + args.header.start = data.start; + args.column = c; + args.originalEvent = ev; + args.shift = ev.shiftKey; + args.ctrl = ev.ctrlKey; + args.meta = ev.metaKey; + + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onHeaderClick === 'function') { + calendar.onHeaderClick(args); + if (args.preventDefault.value) { + return; + } + } + + if (typeof calendar.onHeaderClicked === 'function') { + calendar.onHeaderClicked(args); + } + + }; + + this._createColumn = function(data) { + return new DayPilot.CalendarColumn(data, calendar); + }; + + this._widthUnit = function() { + if (this.width && this.width.indexOf("px") !== -1) { + return "Pixel"; + } + return "Percentage"; + }; + + this._drawHeader = function() { + + var header = this.nav.header; + var create = true; + + var columns = this._columns; + var len = columns.length; + + while (this.headerCreated && header && header.rows && header.rows.length > 0 && create) { + if (!this.fasterDispose) DayPilot.pu(header.rows[0]); + header.deleteRow(0); + } + + this.headerCreated = true; + + if (!create) { + // corner + var corner = calendar.nav.corner; + if (!this.fasterDispose) DayPilot.pu(corner.firstChild); + } + + this._drawHeaderRow(create); + }; + + this.loadingStart = function() { + if (this.loadingLabelVisible) { + this.nav.loading.innerHTML = this.loadingLabelText; + this.nav.loading.style.top = (this.headerHeight + 5) + "px"; + this.nav.loading.style.display = ''; + } + }; + + this.commandCallBack = function(command, data) { + var params = {}; + params.command = command; + this._callBack2('Command', data, params); + }; + + this.loadingStop = function(msg) { + if (this.callbackTimeout) { + window.clearTimeout(this.callbackTimeout); + } + + this.nav.loading.style.display = 'none'; + }; + + this._enableScrolling = function() { + + var scrollDiv = this.nav.scroll; + + if (!scrollDiv.onscroll) { + scrollDiv.onscroll = function() { + calendar._saveScrollHour(); + }; + } + + var scrollpos = (typeof this._config.scrollpos !== 'undefined') ? this._config.scrollpos : this.initScrollPos; + + if (!scrollpos) { + return; + } + + + if (scrollpos === 'Auto') { + if (this.heightSpec === "BusinessHours") { + scrollpos = 2 * this.cellHeight * this.businessBeginsHour; + } + else { + scrollpos = 0; + } + } + + scrollDiv.root = this; + + // initial position + if (scrollDiv.scrollTop === 0) { + scrollDiv.scrollTop = scrollpos; + } + }; + + this.callbackError = function (result, context) { + alert("Error!\r\nResult: " + result + "\r\nContext:" + context); + }; + + this._fixScrollHeader = function() { + var w = DayPilot.sw(this.nav.scroll); + var d = this.nav.cornerRight; + if (d) { + d.style.width = w + 'px'; + } + }; + + this._registerGlobalHandlers = function() { + if (!DayPilotCalendar.globalHandlers) { + DayPilotCalendar.globalHandlers = true; + DayPilot.re(document, 'mouseup', DayPilotCalendar.gMouseUp); + DayPilot.re(window, 'unload', DayPilotCalendar.gUnload); + } + }; + + this.events = {}; + //this.events.list = []; + + this.events.add = function(e) { + + var data = null; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + data = e; + } + else { + throw "DayPilot.Calendar.events.add() expects an object or DayPilot.Event instance."; + } + + if (!calendar.events.list) { + calendar.events.list = []; + } + + calendar.events.list.push(data); + calendar._update({"eventsOnly": true}); + calendar._angular.notify(); + }; + + + this.events.find = function(id) { + if (!calendar.events.list) { + return null; + } + + if (typeof id === "function") { + var fn = id; + for (var i = 0; i < calendar.events.list.length; i++) { + var e = new DayPilot.Event(calendar.events.list[i], calendar); + if (fn(e)) { + return e; + } + } + return null; + } + + for (var i = 0; i < calendar.events.list.length; i++) { + var data = calendar.events.list[i]; + if (data.id === id) { + return new DayPilot.Event(data, calendar); + } + } + return null; + }; + + this.events.update = function(e) { + if (e instanceof DayPilot.Event) { + e.commit(); + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + var index = DayPilot.indexOf(calendar.events.list, target.data); + calendar.events.list.splice(index, 1, e); + } + } + + calendar._update({"eventsOnly": true}); + calendar._angular.notify(); + }; + + this.events.remove = function(e) { + var data; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + data = target.data; + } + } + else if (typeof e === "string" || typeof e === "number") { + var target = calendar.events.find(e); + if (target) { + data = target.data; + } + } + + var index = DayPilot.indexOf(calendar.events.list, data); + calendar.events.list.splice(index, 1); + calendar._update({"eventsOnly": true}); + calendar._angular.notify(); + }; + + this.events.load = function(url, success, error) { + var onError = function(args) { + var largs = {}; + largs.exception = args.exception; + largs.request = args.request; + + if (typeof error === 'function') { + error(largs); + } + }; + + var onSuccess = function(args) { + var r = args.request; + var data; + + // it's supposed to be JSON + try { + data = JSON.parse(r.responseText); + } + catch (e) { + var fargs = {}; + fargs.exception = e; + onError(fargs); + return; + } + + if (DayPilot.isArray(data)) { + var sargs = {}; + sargs.preventDefault = function() { + this.preventDefault.value = true; + }; + sargs.data = data; + if (typeof success === "function") { + success(sargs); + } + + if (sargs.preventDefault.value) { + return; + } + + calendar.events.list = data; + if (calendar._initialized) { + calendar._update({"eventsOnly": true}); + } + } + }; + + var usePost = calendar.eventsLoadMethod && calendar.eventsLoadMethod.toUpperCase() === "POST"; + + if (usePost) { + DayPilot.Http.ajax({ + "method": "POST", + "data": { "start": calendar.visibleStart().toString(), "end": calendar.visibleEnd().toString()}, + "url": url, + "success": onSuccess, + "error": onError + }); + } + else { + var fullUrl = url; + var queryString = "start=" + calendar.visibleStart().toString() + "&end=" + calendar.visibleEnd().toString(); + if (fullUrl.indexOf("?") > -1) { + fullUrl += "&" + queryString; + } + else { + fullUrl += "?" + queryString; + } + + DayPilot.Http.ajax({ + "method": "GET", + "url": fullUrl, + "success": onSuccess, + "error": onError + }); + } + + }; + + this._updateTheme = function() { + // manually update theme for elements that are not redrawn during update + //return; + + var needsUpdate = calendar.nav.top.className !== calendar._prefixCssClass("_main"); + + if (!needsUpdate) { + return; + } + + calendar.nav.top.className = calendar._prefixCssClass("_main"); + var corner = calendar.nav.corner; + corner.className = calendar._prefixCssClass("_corner"); + corner.firstChild.className = calendar._prefixCssClass("_corner_inner"); + + var cr = calendar.nav.cornerRight; + if (cr) { + cr.className = calendar._prefixCssClass("_cornerright"); + cr.firstChild.className = calendar._prefixCssClass("_cornerright_inner"); + } + }; + + this.update = function(options) { + + if (calendar._disposed) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Calendar instance that has been disposed."); + } + + calendar._loadOptions(options); + calendar._update(); + }; + + this._update = function(args) { + + if (!this._initialized) { + return; + } + + var args = args || {}; + var full = !args.eventsOnly; + + calendar._prepareVariables(); + calendar._deleteEvents(); + + // reset after drag and drop/deleting + calendar.nav.top.style.cursor = "auto"; + + // calendar._show(); + + if (full) { + calendar._prepareColumns(); + calendar._drawHeader(); + calendar._drawMain(); + calendar._drawHourTable(); + calendar._updateHeight(); + calendar._updateCorner(); + calendar._fixScrollHeader(); + calendar._updateTheme(); + + calendar._restoreScrollHour(); + } + + calendar._loadEvents(); + calendar._updateHeaderHeight(); + + calendar._drawEvents(); + calendar.clearSelection(); + + if (this.visible) { + this.show(); + } + else { + this.hide(); + } + }; + + + this._specialHandling = null; + this._loadOptions = function(options) { + if (!options) { + return; + } + var specialHandling = { + "events": { + "preInit": function() { + var events = this.data || []; + if (DayPilot.isArray(events.list)) { + calendar.events.list = events.list; + } + else { + calendar.events.list = events; + } + } + }, + "columns": { + "preInit": function() { + calendar.columns.list = this.data; + } + } + }; + this._specialHandling = specialHandling; + + for (var name in options) { + if (specialHandling[name]) { + var item = specialHandling[name]; + item.data = options[name]; + if (item.preInit) { + item.preInit(); + } + } + else { + calendar[name] = options[name]; + } + } + + }; + + this._postInit = function() { + var specialHandling = this._specialHandling; + for (var name in specialHandling) { + var item = specialHandling[name]; + if (item.postInit) { + item.postInit(); + } + } + }; + + this._loadTop = function() { + if (this.id && this.id.tagName) { + this.nav.top = this.id; + } + else if (typeof this.id === "string") { + this.nav.top = document.getElementById(this.id); + if (!this.nav.top) { + throw "DayPilot.Calendar: The placeholder element not found: '" + id + "'."; + } + } + else { + throw "DayPilot.Calendar() constructor requires the target element or its ID as a parameter"; + } + }; + + this._cache = {}; + this._cache.events = []; + + this._doBeforeEventRender = function(i) { + var cache = this._cache.events; + var data = this.events.list[i]; + var evc = {}; + + // make a copy + for (var name in data) { + evc[name] = data[name]; + } + + if (typeof this.onBeforeEventRender === 'function') { + var args = {}; + args.control = calendar; + args.data = evc; + this.onBeforeEventRender(args); + } + + cache[i] = evc; + + }; + + this._loadEvents = function() { + + var events = this.events.list; + + calendar._cache.events = []; + + if (!events) { + return; + } + + if (!DayPilot.isArray(events)) { + throw new DayPilot.Exception("DayPilot.Calendar.events.list expects an array object. You supplied: " + (typeof events)); + } + + var length = events.length; + var duration = 24 * 60 * 60 * 1000; + + this.cache.pixels = {}; + + var loadCache = []; + + this.scrollLabels = []; + + this.minStart = 10000; + this.maxEnd = 0; + + for (var i = 0; i < length; i++) { + var e = events[i]; + var edata = e; + + if (typeof edata !== "object") { + throw new DayPilot.Exception("Event data item must be an object"); + } + if (!edata.start) { + throw new DayPilot.Exception("Event data item must specify 'start' property"); + } + if (!edata.end) { + throw new DayPilot.Exception("Event data item must specify 'end' property"); + } + + if (edata instanceof DayPilot.Event) { + throw new DayPilot.Exception("DayPilot.Calendar: DayPilot.Event object detected in events.list array. Use raw event data instead."); + } + + e.start = new DayPilot.Date(e.start); + e.end = new DayPilot.Date(e.end); + } + + if (typeof this.onBeforeEventRender === 'function') { + for (var i = 0; i < length; i++) { + this._doBeforeEventRender(i); + } + } + + for(var i = 0; i < this._columns.length; i++) { + + var scroll = {}; + scroll.minEnd = 1000000; + scroll.maxStart = -1; + this.scrollLabels.push(scroll); + + var col = this._columns[i]; + col.events = []; + col.lines = []; + col.blocks = []; + + var colStart = new DayPilot.Date(col.start); + var colStartTicks = colStart.getTime(); + var colEnd = colStart.addTime(duration); + var colEndTicks = colEnd.getTime(); + + for (var j = 0; j < length; j++) { + if (loadCache[j]) { + continue; + } + + var e = events[j]; + + var start = e.start; + var end = e.end; + + var startTicks = start.getTime(); + var endTicks = end.getTime(); + + if (endTicks < startTicks) { // skip invalid events + continue; + } + + // belongs here + var belongsHere = !(endTicks <= colStartTicks || startTicks >= colEndTicks); + if (calendar.viewType === "Resources") { + belongsHere = belongsHere && col.id === e.resource; + } + + if (belongsHere) { + var ep = new DayPilot.Event(e, calendar); // event part + ep.part.dayIndex = i; + ep.part.start = colStartTicks < startTicks ? e.start : colStart; + ep.part.end = colEndTicks > endTicks ? e.end : colEnd; + + var partStartPixels = this.getPixels(ep.part.start, col.start); + var partEndPixels = this.getPixels(ep.part.end, col.start); + + var top = partStartPixels.top; + var bottom = partEndPixels.top; + + // events in the hidden areas + if (top === bottom && (partStartPixels.cut || partEndPixels.cut)) { + continue; + } + + var boxBottom = partEndPixels.boxBottom; + + ep.part.top = Math.floor(top / this.cellHeight) * this.cellHeight + 1; + ep.part.height = Math.max(Math.ceil(boxBottom / this.cellHeight) * this.cellHeight - ep.part.top, this.cellHeight - 1) + 1; + ep.part.barTop = Math.max(top - ep.part.top - 1, 0); // minimum 0 + ep.part.barHeight = Math.max(bottom - top - 2, 1); // minimum 1 + + var start = ep.part.top; + var end = ep.part.top + ep.part.height; + + if (start > scroll.maxStart) { + scroll.maxStart = start; + } + if (end < scroll.minEnd) { + scroll.minEnd = end; + } + + if (start < this.minStart) { + this.minStart = start; + } + if (end > this.maxEnd) { + this.maxEnd = end; + } + col.events.push(ep); + + if (typeof this.onBeforeEventRender === 'function') { + ep.cache = this._cache.events[j]; + } + + if (ep.part.start.getTime() === startTicks && ep.part.end.getTime() === endTicks) { + loadCache[j] = true; + } + } + } + + } + + + // sort events inside rows + for (var i = 0; i < this._columns.length; i++) { + var col = this._columns[i]; + col.events.sort(this._eventComparer); + + // put into lines + for (var j = 0; j < col.events.length; j++) { + var e = col.events[j]; + col.putIntoBlock(e); + } + + for (var j = 0; j < col.blocks.length; j++) { + var block = col.blocks[j]; + block.events.sort(this._eventComparer); + for (var k = 0; k < block.events.length; k++ ) { + var e = block.events[k]; + block.putIntoLine(e); + } + } + } + }; + + this._eventComparer = function(a, b) { + if (!a || !b || !a.start || !b.start) { + return 0; // no sorting, invalid arguments + } + + var byStart = a.start().getTime() - b.start().getTime(); + if (byStart !== 0) { + return byStart; + } + + var byEnd = b.end().getTime() - a.end().getTime(); // desc + return byEnd; + }; + + this.debug = function(msg, append) { + if (!this.debuggingEnabled) { + return; + } + + if (!calendar.debugMessages) { + calendar.debugMessages = []; + } + calendar.debugMessages.push(msg); + + if (typeof console !== 'undefined') { + console.log(msg); + } + }; + + this.getPixels = function(date, start) { + if (!start) start = this.startDate; + + var startTicks = start.getTime(); + var ticks = date.getTime(); + + var cache = this.cache.pixels[ticks + "_" + startTicks]; + if (cache) { + return cache; + } + + startTicks = start.getTime(); + + var boxTicks = 30 * 60 * 1000; + var topTicks = ticks - startTicks; + var boxOffsetTicks = topTicks % boxTicks; + + var boxStartTicks = topTicks - boxOffsetTicks; + var boxEndTicks = boxStartTicks + boxTicks; + if (boxOffsetTicks === 0) { + boxEndTicks = boxStartTicks; + } + + // it's linear scale so far + var result = {}; + result.cut = false; + result.top = this._ticksToPixels(topTicks); + result.boxTop = this._ticksToPixels(boxStartTicks); + result.boxBottom = this._ticksToPixels(boxEndTicks); + + this.cache.pixels[ticks + "_" + startTicks] = result; + + return result; + }; + + this._ticksToPixels = function(ticks) { + return Math.floor( (this.cellHeight * ticks) / (1000 * 60 * 30) ); + }; + + this._prepareVariables = function() { + this.startDate = new DayPilot.Date(this.startDate).getDatePart(); + }; + + this._updateHeaderHeight = function() { + if (this.nav.corner) { + this.nav.corner.style.height = this.headerHeight + "px"; + } + }; + + this._updateHeight = function() { + var sh = this._getScrollableHeight(); + if (this.nav.scroll && sh > 0) { + this.nav.scroll.style.height = sh + "px"; + } + }; + + this._angular = {}; + this._angular.scope = null; + this._angular.notify = function() { + if (calendar._angular.scope) { + calendar._angular.scope["$apply"](); + } + }; + this._angular.apply = function(f) { + // autoapply has been disabled + f(); + + /* + if (calendar.angularAutoApply && calendar._angular.scope) { + calendar._angular.scope["$apply"](f); + } + else { + f(); + } + */ + }; + + this._saveScrollHour = function() { + if (!calendar.nav.scroll) { + return; + } + var top = calendar.nav.scroll.scrollTop; + var pos = top / (2*calendar.cellHeight); + calendar._config.scrollHour = pos; + }; + + this._restoreScrollHour = function() { + var scrollpos = 0; + if (typeof calendar._config.scrollHour === "number") { + scrollpos = 2 * calendar.cellHeight * calendar._config.scrollHour; + //calendar._config.scrollHour = null; + } + else { + if (calendar.initScrollPos === 'Auto') { + if (this.heightSpec === "BusinessHours") { + scrollpos = 2 * this.cellHeight * this.businessBeginsHour; + } + else { + scrollpos = 0; + } + } + } + + calendar.nav.scroll.scrollTop = scrollpos; + }; + + this._loadFromServer = function() { + // make sure it has a place to ask + if (this.backendUrl || typeof WebForm_DoCallback === 'function') { + return (typeof calendar.events.list === 'undefined') || (!calendar.events.list); + } + else { + return false; + } + }; + + this._show = function() { + if (this.nav.top.style.visibility === 'hidden') { + this.nav.top.style.visibility = 'visible'; + } + }; + + this.show = function() { + calendar.visible = true; + calendar.nav.top.style.display = ''; + this._fixScrollHeader(); + }; + + this.hide = function() { + calendar.visible = false; + calendar.nav.top.style.display = 'none'; + }; + this._initShort = function() { + this._prepareVariables(); + this._prepareColumns(); + this._drawTop(); + this._drawHeader(); + this._drawMain(); + this._fixScrollHeader(); + this._enableScrolling(); + this._registerGlobalHandlers(); + DayPilotCalendar.register(this); + + this._waitForVisibility(); + this._callBack2('Init'); + }; + + this._config = {}; + + this._saveConfig = function() { + this._config.themes = []; + this._config.themes.push(this.theme || this.cssClassPrefix); + }; + + this._clearThemes = function() { + var themes = this._config.themes; + for (var i = 0; i < themes.length; i++) { + var theme = themes[i]; + DayPilot.Util.removeClass(this.nav.top, theme + "_main"); + } + this._config.themes = []; + }; + + this._doAfterRender = function() { + this.afterRender(null, false); + if (typeof this.onAfterRender === "function") { + var args = {}; + args.isCallBack = false; + this.onAfterRender(args); + } + }; + + this._doInit = function() { + if (typeof this.onInit === "function" && !this._onInitCalled) { + this._onInitCalled = true; + var args = {}; + this.onInit(args); + } + }; + + this._visible = function() { + var el = calendar.nav.top; + if (!el) { + return false; + } + return el.offsetWidth > 0 && el.offsetHeight > 0; + }; + + this._waitForVisibility = function() { + var visible = calendar._visible; + + if (!visible()) { + calendar._visibilityInterval = setInterval(function() { + if (visible()) { + calendar._enableScrolling(); + calendar._fixScrollHeader(); + clearInterval(calendar._visibilityInterval); + } + }, 100); + } + }; + + this._xssTextHtml = function(text, html) { + + if (calendar._resolved._xssProtectionEnabled()) { + return DayPilot.Util.escapeTextHtml(text, html); + } + + if (!DayPilot.Util.isNullOrUndefined(html)) { + return html; + } + if (DayPilot.Util.isNullOrUndefined(text)) { + return ""; + } + return text; + }; + + + this.internal = {}; + this.internal.loadOptions = calendar._loadOptions; + this.internal.xssTextHtml = calendar._xssTextHtml; + + this.init = function() { + this._loadTop(); + + var loadFromServer = this._loadFromServer(); + + this._saveConfig(); + + if (loadFromServer) { + this._initShort(); + return; + } + + this._prepareVariables(); + this._prepareColumns(); + + this._loadEvents(); + + this._drawTop(); + this._drawHeader(); + this._drawMain(); + + this._show(); + + this._fixScrollHeader(); + this._enableScrolling(); + this._registerGlobalHandlers(); + DayPilotCalendar.register(this); + + if (this.events) { // are events available? + this._updateHeaderHeight(); + this._drawEvents(); + } + + this._doAfterRender(); + this._doInit(); + this._waitForVisibility(); + this._initialized = true; + + return this; + }; + + this.Init = this.init; + + this._loadOptions(options); + }; + + DayPilot.CalendarColumn = function(col, calendar) { + var column = this; + + column.id = col.id; + column.name = col.name; + column.data = col.data; + column.start = new DayPilot.Date(col.start); + column.calendar = calendar; + + column.toJSON = function() { + var json = {}; + json.id = this.id; + if (this.start) { + json.start = this.start.toString(); + } + json.name = this.name; + return json; + }; + }; + + + // publish the API + DayPilot.Calendar = DayPilotCalendar.Calendar; + + // jQuery plugin + if (typeof jQuery !== 'undefined') { + (function( $ ){ + $.fn.daypilotCalendar = function(options) { + var first = null; + var j = this.each(function() { + if (this.daypilot) { // already initialized + return; + }; + + var daypilot = new DayPilot.Calendar(this.id); + this.daypilot = daypilot; + for (name in options) { + daypilot[name] = options[name]; + } + daypilot.init(); + if (!first) { + first = daypilot; + } + }); + if (this.length === 1) { + return first; + } + else { + return j; + } + }; + })( jQuery ); + } + + (function registerAngularModule() { + + var app = DayPilot.am(); + + if (!app) { + return; + } + + app.directive("daypilotCalendar", ['$parse', function($parse) { +// app.directive("daypilotCalendar", function() { + return { + "restrict": "E", + "template": "
", + "replace": true, + "link": function (scope, element, attrs) { + + var calendar = new DayPilot.Calendar(element[0]); + calendar._angular.scope = scope; + calendar.init(); + + var oattr = attrs["id"]; + if (oattr) { + scope[oattr] = calendar; + } + + // save DayPilot.Calendar object in the specified variable + var pas = attrs["publishAs"]; + if (pas) { + var getter = $parse(pas); + var setter = getter.assign; + setter(scope, calendar); + } + + // bind event handlers from attributes starting with "on" + for (var name in attrs) { + if (name.indexOf("on") === 0) { // event handler + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + scope["$apply"](function() { + f(scope, {"args": args}); + }); + }; + })(name); + } + } + + var watch = scope["$watch"]; + var config = attrs["config"] || attrs["daypilotConfig"]; + var events = attrs["events"] || attrs["daypilotEvents"]; + + watch.call(scope, config, function (value) { + //var bbOld = calendar.businessBeginsHour; + + for (var name in value) { + calendar[name] = value[name]; + } + calendar.update(); + calendar._doInit(); + }, true); + + watch.call(scope, events, function(value) { + //var calendar = element.data("calendar"); + calendar.events.list = value; + calendar.update(); + }, true); + + } + }; + }]); + })(); + +})(); diff --git a/static/src/js/src/daypilot-common.src.js b/static/src/js/src/daypilot-common.src.js new file mode 100644 index 0000000..2fee00a --- /dev/null +++ b/static/src/js/src/daypilot-common.src.js @@ -0,0 +1,3986 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +(function() { + + if (typeof DayPilot.$ !== 'undefined') { + return; + } + + if (typeof DayPilot.Global === "undefined") { + DayPilot.Global = {}; + } + + DayPilot.$ = function(id) { + return document.getElementById(id); + }; + + Object.defineProperty(DayPilot, 'isKhtml', { + get: function() { return typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.indexOf("KHTML") !== -1; } + }); + + DayPilot.mo2 = function (target, ev){ + ev = ev || window.event; + + // IE + if (typeof(ev.offsetX) !== 'undefined') { + + var coords = {x: ev.offsetX + 1, y:ev.offsetY + 1}; + //document.title = "ie/doc:" + document.documentElement.scrollTop; + + if (!target) { + return coords; + } + + var current = ev.srcElement; + while (current && current !== target) { + if (current.tagName !== 'SPAN') { // hack for DayPilotMonth/IE, hour info on the right side of an event + coords.x += current.offsetLeft; + if (current.offsetTop > 0) { // hack for http://forums.daypilot.org/Topic.aspx/879/move_event_bug + coords.y += current.offsetTop - current.scrollTop; + } + } + + current = current.offsetParent; + } + + if (current) { + return coords; + } + return null; + } + + // FF + if (typeof(ev.layerX) !== 'undefined') { + + var coords = {x:ev.layerX, y:ev.layerY, src: ev.target}; + + if (!target) { + return coords; + } + var current = ev.target; + + // find the positioned offsetParent, the layerX reference + while (current && current.style.position !== 'absolute' && current.style.position !== 'relative') { + current = current.parentNode; + if (DayPilot.isKhtml) { // hack for KHTML (Safari and Google Chrome), used in DPC/event moving + coords.y += current.scrollTop; + } + } + + while (current && current !== target) { + coords.x += current.offsetLeft; + coords.y += current.offsetTop - current.scrollTop; + current = current.offsetParent; + } + if (current) { + return coords; + } + + return null; + } + + return null; + }; + + // mouse offset relative to the specified target + DayPilot.mo3 = function(target, ev) { + var coords; + var page = DayPilot.page(ev); + if (page) { + if (target) { + var abs = DayPilot.abs(target); + if (!abs) { + throw new Error("no abs"); + return null; + } + coords = {x: page.x - abs.x, y: page.y - abs.y}; + } + else { + coords = {x: page.x, y: page.y}; + } + } + else { + coords = DayPilot.mo2(target, ev); + if (!coords) { + // throw new Error("no coords"); + return null; + } + } + + coords.shift = ev.shiftKey; + coords.meta = ev.metaKey; + coords.ctrl = ev.ctrlKey; + coords.alt = ev.altKey; + + return coords; + }; + + DayPilot.browser = {}; + + Object.defineProperty(DayPilot.browser, 'hover', { + get: function() { return !window.matchMedia("(any-hover: none)").matches; } + }); + + DayPilot.touch = {}; + + // returns pageX, pageY (calculated from clientX if pageX is not available) + DayPilot.page = function(ev) { + // required for chrome/android + var target = ev.changedTouches && ev.changedTouches[0] ? ev.changedTouches[0] : ev; + + if (typeof target.pageX !== 'undefined') { + return {x: target.pageX, y: target.pageY}; + } + if (typeof ev.clientX !== 'undefined' && document.body && document.documentElement) { + return { + x: ev.clientX + document.body.scrollLeft + document.documentElement.scrollLeft, + y: ev.clientY + document.body.scrollTop + document.documentElement.scrollTop + }; + } + // shouldn't happen + return null; + }; + + // absolute element position on page + DayPilot.abs = function(element, visible) { + if (!element) { + return null; + } + + if (element.getBoundingClientRect) { + var r = DayPilot.absBoundingClientBased(element); + + if (visible) { + // use diff, absOffsetBased is not as accurate + var full = DayPilot.absOffsetBased(element, false); + var visible = DayPilot.absOffsetBased(element, true); + + r.x += visible.x - full.x; + r.y += visible.y - full.y; + r.w = visible.w; + r.h = visible.h; + } + + return r; + } + else { + return DayPilot.absOffsetBased(element, visible); + } + + }; + + DayPilot.absBoundingClientBased = function(element) { + var elemRect = element.getBoundingClientRect(); + + return { + // x: elemRect.left + window.scrollX, // IE11 doesn't support this + x: elemRect.left + window.pageXOffset, + // y: elemRect.top + window.scrollY, // IE11 doesn't support this + y: elemRect.top + window.pageYOffset, + w: element.clientWidth, + h: element.clientHeight, + toString: function() { + return "x:" + this.x + " y:" + this.y + " w:" + this.w + " h:" + this.h; + } + }; + }; + + + // old implementation of absolute position + // problems with adjacent float and margin-left in IE7 + // still the best way to calculate the visible part of the element + DayPilot.absOffsetBased = function(element, visible) { + var r = { + x: element.offsetLeft, + y: element.offsetTop, + w: element.clientWidth, + h: element.clientHeight, + toString: function() { + return "x:" + this.x + " y:" + this.y + " w:" + this.w + " h:" + this.h; + } + }; + + while (element.offsetParent) { + element = element.offsetParent; + + r.x -= element.scrollLeft; + r.y -= element.scrollTop; + + if (visible) { // calculates the visible part + if (r.x < 0) { + r.w += r.x; // decrease width + r.x = 0; + } + + if (r.y < 0) { + r.h += r.y; // decrease height + r.y = 0; + } + + if (element.scrollLeft > 0 && r.x + r.w > element.clientWidth) { + r.w -= r.x + r.w - element.clientWidth; + } + + if (element.scrollTop && r.y + r.h > element.clientHeight) { + r.h -= r.y + r.h - element.clientHeight; + } + } + + r.x += element.offsetLeft; + r.y += element.offsetTop; + + } + + var pageOffset = DayPilot.pageOffset(); + r.x += pageOffset.x; + r.y += pageOffset.y; + + return r; + }; + + DayPilot.isArray = function(o) { + return Object.prototype.toString.call(o) === '[object Array]'; + }; + + // distance of two points, works with x and y + DayPilot.distance = function(point1, point2) { + return Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2)); + }; + + DayPilot.sheet = function() { + + if (typeof window === "undefined") { + // next.js server-side rendering + var sheet = {}; + sheet.add = function() {}; + sheet.commit = function() {}; + return sheet; + } + + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + if (!style.styleSheet) { // ie + style.appendChild(document.createTextNode("")); + } + + var h = document.head || document.getElementsByTagName('head')[0]; + h.appendChild(style); + + var oldStyle = !! style.styleSheet; // old ie + + var sheet = {}; + sheet.rules = []; + sheet.commit = function() { + if (oldStyle) { + style.styleSheet.cssText = this.rules.join("\n"); + } + }; + + sheet.add = function(selector, rules, index) { + if (oldStyle) { + this.rules.push(selector + "{" + rules + "\u007d"); + return; + } + if(style.sheet.insertRule) { + if (typeof index === "undefined") { + index = style.sheet.cssRules.length; + } + style.sheet.insertRule(selector + "{" + rules + "\u007d", index); + } + else if (style.sheet.addRule) { + style.sheet.addRule(selector, rules, index); + } + }; + return sheet; + }; + + DayPilot.gs = function(el, styleProp) { + return window.getComputedStyle(el, null).getPropertyValue(styleProp) || ""; + }; + + DayPilot.StyleReader = function(element) { + + this.get = function(property) { + if (!element) { + return null; + } + return DayPilot.gs(element, property); + }; + + this.getPx = function(property) { + var val = this.get(property); + if (val.indexOf("px") === -1) { + return undefined; + } + else { + return parseInt(val, 10); + } + }; + + }; + + // register the default themes + (function() { + if (DayPilot.Global.defaultCss) { + return; + } + + var sheet = DayPilot.sheet(); + + sheet.add(".calendar_default_main", "border: 1px solid #c0c0c0; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;"); + sheet.add(".calendar_default_main *, .calendar_default_main *:before, .calendar_default_main *:after", "box-sizing: content-box;"); // bootstrap + sheet.add(".calendar_default_rowheader_inner,.calendar_default_cornerright_inner,.calendar_default_corner_inner,.calendar_default_colheader_inner,.calendar_default_alldayheader_inner", "color: #333;background: #f3f3f3;"); + sheet.add(".calendar_default_cornerright_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px; border-bottom: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_direction_rtl .calendar_default_cornerright_inner", "border-right: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_rowheader_inner", "font-size: 16pt;text-align: right; position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0; padding: 3px;"); + sheet.add(".calendar_default_direction_rtl .calendar_default_rowheader_inner", "border-right: none;"); + sheet.add(".calendar_default_corner_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_direction_rtl .calendar_default_corner_inner", "border-right: none;"); + sheet.add(".calendar_default_rowheader_minutes", "font-size:10px;vertical-align: super;padding-left: 2px;padding-right: 2px;"); + sheet.add(".calendar_default_colheader_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0; display: flex; align-items: center; justify-content: center; font-size: 13px;"); + sheet.add(".calendar_default_cell_inner", "position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #ddd;border-bottom: 1px solid #ddd; background: #f9f9f9;"); + sheet.add(".calendar_default_cell_business .calendar_default_cell_inner", "background: #fff"); + sheet.add(".calendar_default_alldayheader_inner", "text-align: center;position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"); + sheet.add(".calendar_default_message", "opacity: 0.9; padding: 10px; color: #ffffff;background: #ffa216;"); + sheet.add(".calendar_default_alldayevent_inner,.calendar_default_event_inner", 'color: #333; border: 1px solid #999;'); // border-top: 4px solid #1066a8; + sheet.add(".calendar_default_event_bar", "top: 0px;bottom: 0px;left: 0px;width: 6px;background-color: #9dc8e8;"); + sheet.add(".calendar_default_event_bar_inner", "position: absolute;width: 6px;background-color: #1066a8;"); + sheet.add(".calendar_default_alldayevent_inner,.calendar_default_event_inner", 'background: #fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".calendar_default_selected .calendar_default_event_inner", "background: #ddd;"); + sheet.add(".calendar_default_alldayevent_inner", "position: absolute;top: 2px;bottom: 2px;left: 2px;right: 2px;overflow:hidden;padding: 2px;margin-right: 1px; font-size: 13px;"); + sheet.add(".calendar_default_event_withheader .calendar_default_event_inner", "padding-top: 15px;"); + sheet.add(".calendar_default_event", "cursor: default;"); + sheet.add(".calendar_default_event_inner", "position: absolute;overflow: hidden;top: 0px;bottom: 0px;left: 0px;right: 0px;padding: 2px 2px 2px 8px; font-size: 13px;"); + sheet.add(".calendar_default_event_delete", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat; opacity: 0.6; cursor: pointer;"); + sheet.add(".calendar_default_event_delete:hover", "opacity: 1;-ms-filter: none;"); + sheet.add(".calendar_default_scroll_up", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAB3RJTUUH2wESDiYcrhwCiQAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAARnQU1BAACxjwv8YQUAAACcSURBVHjaY2AgF9wWsTW6yGMlhi7OhC7AyMDQzMnBXIpFHAFuCtuaMTP+P8nA8P/b1x//FfW/HHuF1UQmxv+NUP1c3OxMVVhNvCVi683E8H8LXOY/w9+fTH81tF8fv4NiIpBRj+YoZtZ/LDUoJmKYhsVUpv0MDiyMDP96sIYV0FS2/8z9ICaLlOhvS4b/jC//MzC8xBG0vJeF7GQBlK0xdiUzCtsAAAAASUVORK5CYII=);"); + sheet.add(".calendar_default_scroll_down", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAALiMAAC4jAXilP3YAAACqSURBVChTY7wpam3L9J+xmQEP+PGPKZZxP4MDi4zI78uMDIwa2NT+Z2DYovrmiC+TI8OBP/8ZmEqwGvif4e8vxr+FIDkmEKH25vBWBgbG0+iK/zEwLtF+ffwOXCGI8Y+BoRFFIdC030x/WmBiYBNhpgLdswNJ8RSYaSgmgk39z1gPUfj/29ef/9rwhQTDHRHbrbdEbLvRFcGthkkAra/9/uMvhkK8piNLAgCRpTnNn4AEmAAAAABJRU5ErkJggg==);"); + sheet.add(".calendar_default_now", "background-color: red;"); + sheet.add(".calendar_default_now:before", "content: ''; top: -5px; border-width: 5px; border-color: transparent transparent transparent red; border-style: solid; width: 0px; height:0px; position: absolute; -moz-transform: scale(.9999);"); + sheet.add(".calendar_default_shadow_top", 'box-sizing: border-box; padding:2px;border:1px solid #ccc;background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".calendar_default_shadow_bottom", 'box-sizing: border-box; padding:2px;border:1px solid #ccc;background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".calendar_default_crosshair_vertical, .calendar_default_crosshair_horizontal, .calendar_default_crosshair_left, .calendar_default_crosshair_top", "background-color: gray; opacity: 0.2;"); + sheet.add(".calendar_default_loading", "background-color: orange; color: white; padding: 2px;"); + sheet.add(".calendar_default_scroll", "background-color: #f3f3f3;"); + sheet.add(".calendar_default_event_moving_source", "opacity: 0.5;"); + sheet.add(".calendar_default_shadow_inner", "box-sizing: border-box; background-color: #bbbbbb;border: 1px solid #888888;opacity: 0.5;height: 100%;"); + sheet.add(".calendar_default_shadow", "box-shadow: 0 2px 5px rgba(0,0,0,.2);"); + + + // menu + sheet.add(".menu_default_main", "user-select:none; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;font-size: 13px;border: 1px solid #dddddd;background-color: white;padding: 0px;cursor: default;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAABCAIAAABG0om7AAAAKXRFWHRDcmVhdGlvbiBUaW1lAHBvIDEwIDUgMjAxMCAyMjozMzo1OSArMDEwMGzy7+IAAAAHdElNRQfaBQoUJAesj4VUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAABGdBTUEAALGPC/xhBQAAABVJREFUeNpj/P//PwO1weMnT2RlZAAYuwX/4oA3BgAAAABJRU5ErkJggg==);background-repeat: repeat-y;xborder-radius: 5px;-moz-box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);-webkit-box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);box-shadow:0px 2px 3px rgba(000,000,000,0.3),inset 0px 0px 2px rgba(255,255,255,0.8);"); + sheet.add(".menu_default_main, .menu_default_main *, .menu_default_main *:before, .menu_default_main *:after", "box-sizing: content-box;"); + sheet.add(".menu_default_title", "background-color: #f2f2f2;border-bottom: 1px solid gray;padding: 4px 4px 4px 37px;"); + sheet.add(".menu_default_main a", "padding: 2px 2px 2px 35px;color: black;text-decoration: none;cursor: default;"); + sheet.add(".menu_default_main.menu_default_withchildren a", "padding: 2px 35px 2px 35px;"); + sheet.add(".menu_default_main a img", "margin-left: 6px;margin-top: 2px;"); + sheet.add(".menu_default_item_text", "display: block;height: 20px;line-height: 20px; overflow:hidden;padding-left: 2px;padding-right: 20px; white-space: nowrap;"); + sheet.add(".menu_default_main a:hover", "background-color: #f3f3f3;"); + sheet.add(".menu_default_main div div", "border-top: 1px solid #dddddd;margin-top: 2px;margin-bottom: 2px;margin-left: 28px;"); + sheet.add(".menu_default_main a.menu_default_item_disabled", "color: #ccc"); + sheet.add(".menu_default_item_haschildren.menu_default_item_haschildren_active", 'background-color: #f3f3f3;'); + sheet.add(".menu_default_item_haschildren a:before", "content: ''; border-width: 5px; border-color: transparent transparent transparent #666; border-style: solid; width: 0px; height:0px; position: absolute; right: 5px; margin-top: 5px;"); + sheet.add(".menu_default_item_icon", "position: absolute; top:0px; left: 0px; padding: 2px 2px 2px 8px;"); + sheet.add(".menu_default_item a i", "height: 20px;line-height: 20px;"); + sheet.add(".menu_default_item .menu_default_item_symbol", "width: 18px; height: 18px; color: #999; margin-left: 6px;margin-top: 2px;"); + + + // menubar + sheet.add(".menubar_default_main", "border-bottom: 1px solid #ccc; font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px; user-select:none;"); + sheet.add(".menubar_default_item", "display: inline-block; padding: 6px 10px; cursor: default;"); + sheet.add(".menubar_default_item:hover", "background-color: #f2f2f2;"); + sheet.add(".menubar_default_item_active", "background-color: #f2f2f2;"); + + + sheet.add(".scheduler_default_selected .scheduler_default_event_inner", "background: #ddd;"); + sheet.add(".scheduler_default_main", "border: 1px solid #c0c0c0;font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;"); + sheet.add(".scheduler_default_timeheader", "cursor: default;color: #333;"); + sheet.add(".scheduler_default_message", "opacity: 0.9;filter: alpha(opacity=90);padding: 10px; color: #ffffff;background: #ffa216;"); + sheet.add(".scheduler_default_timeheadergroup,.scheduler_default_timeheadercol", "color: #333;background: #f3f3f3;"); + sheet.add(".scheduler_default_rowheader,.scheduler_default_corner", "color: #333;background: #f3f3f3;"); + sheet.add(".scheduler_default_rowheader_inner", "position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #eee;padding: 2px;"); + sheet.add(".scheduler_default_timeheadergroup, .scheduler_default_timeheadercol", "text-align: center;"); + sheet.add(".scheduler_default_timeheadergroup_inner", "position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;"); + sheet.add(".scheduler_default_timeheadercol_inner", "position: absolute;left: 0px;right: 0px;top: 0px;bottom: 0px;border-right: 1px solid #c0c0c0;"); + sheet.add(".scheduler_default_divider", "background-color: #c0c0c0;"); + sheet.add(".scheduler_default_divider_horizontal", "background-color: #c0c0c0;"); + sheet.add(".scheduler_default_matrix_vertical_line", "background-color: #eee;"); + sheet.add(".scheduler_default_matrix_vertical_break", "background-color: #000;"); + sheet.add(".scheduler_default_matrix_horizontal_line", "background-color: #eee;"); + sheet.add(".scheduler_default_resourcedivider", "background-color: #c0c0c0;"); + sheet.add(".scheduler_default_shadow_inner", "background-color: #666666;opacity: 0.5;filter: alpha(opacity=50);height: 100%;xborder-radius: 5px;"); + sheet.add(".scheduler_default_event", "color:#333; font-size: 13px;"); + sheet.add(".scheduler_default_event_inner", "position:absolute;top:0px;left:0px;right:0px;bottom:0px;padding:5px 2px 2px 2px;overflow:hidden;border:1px solid #ccc;"); + sheet.add(".scheduler_default_event_bar", "top:0px;left:0px;right:0px;height:4px;background-color:#9dc8e8;"); + sheet.add(".scheduler_default_event_bar_inner", "position:absolute;height:4px;background-color:#1066a8;"); + sheet.add(".scheduler_default_event_inner", 'background:#fff;background: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#eeeeee));background: -webkit-linear-gradient(top, #ffffff 0%, #eeeeee);background: -moz-linear-gradient(top, #ffffff 0%, #eeeeee);background: -ms-linear-gradient(top, #ffffff 0%, #eeeeee);background: -o-linear-gradient(top, #ffffff 0%, #eeeeee);background: linear-gradient(top, #ffffff 0%, #eeeeee);filter: progid:DXImageTransform.Microsoft.Gradient(startColorStr="#ffffff", endColorStr="#eeeeee");'); + sheet.add(".scheduler_default_event_float_inner", "padding:6px 2px 2px 8px;"); // space for arrow + sheet.add(".scheduler_default_event_float_inner:after", 'content:"";border-color: transparent #666 transparent transparent;border-style:solid;border-width:5px;width:0;height:0;position:absolute;top:8px;left:-4px;'); + sheet.add(".scheduler_default_columnheader_inner", "font-weight: bold;"); + sheet.add(".scheduler_default_columnheader_splitter", "background-color: #666;opacity: 0.5;filter: alpha(opacity=50);"); + sheet.add(".scheduler_default_columnheader_cell_inner", "padding: 2px;"); + sheet.add(".scheduler_default_cell", "background-color: #f9f9f9;"); + sheet.add(".scheduler_default_cell.scheduler_default_cell_business", "background-color: #fff;"); + + sheet.add(".navigator_default_main", "border-left: 1px solid #c0c0c0;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;background-color: white;color: #000000; box-sizing: content-box;"); + sheet.add(".navigator_default_main *, .navigator_default_main *:before, .navigator_default_main *:after", "box-sizing: content-box;"); + sheet.add(".navigator_default_month", "font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 12px;"); + sheet.add(".navigator_default_day", "color: black;"); + sheet.add(".navigator_default_weekend", "background-color: #f0f0f0;"); + sheet.add(".navigator_default_dayheader", "color: black;"); + sheet.add(".navigator_default_line", "border-bottom: 1px solid #c0c0c0;"); + sheet.add(".navigator_default_dayother", "color: gray;"); + sheet.add(".navigator_default_todaybox", "border: 1px solid red;"); + sheet.add(".navigator_default_title, .navigator_default_titleleft, .navigator_default_titleright", "border-top: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;color: #333;background: #f3f3f3;"); + sheet.add(".navigator_default_busy", "font-weight: bold;"); + sheet.add(".navigator_default_cell", "text-align: center;"); + sheet.add(".navigator_default_select .navigator_default_cell_box", "background-color: #FFE794; opacity: 0.5;"); + sheet.add(".navigator_default_title", "text-align: center;"); + sheet.add(".navigator_default_titleleft, .navigator_default_titleright", "text-align: center;"); + sheet.add(".navigator_default_dayheader", "text-align: center;"); + sheet.add(".navigator_default_weeknumber", "text-align: center; color: #999;"); + sheet.add(".navigator_default_cell_text", "cursor: pointer;"); + + sheet.add(".month_default_main", "border: 1px solid #c0c0c0;font-family: -apple-system,system-ui,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; font-size: 13px;color: #333;"); + sheet.add(".month_default_main *, .month_default_main *:before, .month_default_main *:after", "box-sizing: content-box;"); + sheet.add(".month_default_cell_inner", "border-right: 1px solid #ddd;border-bottom: 1px solid #ddd;position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;background-color: #f9f9f9;"); + sheet.add(".month_default_cell_business .month_default_cell_inner", "background-color: #fff;"); + sheet.add(".month_default_cell_header", "text-align: right; padding: 4px; box-sizing: border-box;"); + sheet.add(".month_default_header_inner", 'position: absolute;top: 0px;left: 0px;bottom: 0px;right: 0px;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;cursor: default;color: #333;background: #f3f3f3; overflow:hidden; display: flex; align-items: center; justify-content: center;'); + sheet.add(".month_default_message", 'padding: 10px;opacity: 0.9; color: #ffffff;background: #ffa216;'); + sheet.add(".month_default_event_inner", 'position: absolute;top: 0px;bottom: 0px;left: 1px;right: 1px;overflow:hidden;padding: 2px;padding-left: 10px;color: #333;background: #fff;background: linear-gradient(to bottom, #ffffff 0%, #eeeeee);border: 1px solid #999;border-radius: 0px;display: flex; align-items: center; font-size: 13px;'); + sheet.add(".month_default_event_continueright .month_default_event_inner", "border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-right-style: dotted;"); + sheet.add(".month_default_event_continueleft .month_default_event_inner", "border-top-left-radius: 0px;border-bottom-left-radius: 0px;border-left-style: dotted;"); + + sheet.add(".month_default_event_bar", "top: 0px;bottom: 0px;left: 0px;width: 6px;"); + sheet.add(".month_default_event_bar_inner", "position: absolute;width: 6px;background-color: #1066a8;"); + sheet.add(".month_default_event_continueleft .month_default_event_bar", "display: none;"); + + sheet.add(".month_default_selected .month_default_event_inner", "background: #ddd;"); + // sheet.add(".month_default_shadow_inner", "background-color: #666666;opacity: 0.5;height: 100%;"); + sheet.add(".month_default_event_delete", "background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NCNwAAAI5JREFUKFNtkLERgCAMRbmzdK8s4gAUlhYOYEHJEJYOYOEwDmGBPxC4kOPfvePy84MGR0RJ2N1A8H3N6DATwSQ57m2ql8NBG+AEM7D+UW+wjdfUPgerYNgB5gOLRHqhcasg84C2QxPMtrUhSqQIhg7ypy9VM2EUZPI/4rQ7rGxqo9sadTegw+UdjeDLAKUfhbaQUVPIfJYAAAAASUVORK5CYII=) center center no-repeat; opacity: 0.6; cursor: pointer;"); + sheet.add(".month_default_event_delete:hover", "opacity: 1;-ms-filter: none;"); + sheet.add(".month_default_event_timeleft", "color: #ccc; font-size: 8pt"); + sheet.add(".month_default_event_timeright", "color: #ccc; font-size: 8pt; text-align: right;"); + sheet.add(".month_default_loading", "background-color: orange; color: white; padding: 2px;"); + sheet.add(".month_default_shadow_inner", "box-sizing: border-box; background-color: #bbbbbb;border: 1px solid #888888;opacity: 0.5;height: 100%;"); + sheet.add(".month_default_shadow", "box-shadow: 0 2px 5px rgba(0,0,0,.2);"); + + sheet.commit(); + + DayPilot.Global.defaultCss = true; + })(); + + // document element + DayPilot.doc = function() { + var de = document.documentElement; + return (de && de.clientHeight) ? de : document.body; + }; + + DayPilot.guid = function() { + var S4 = function() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + }; + return ("" + S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); + }; + + DayPilot.pageOffset = function() { + if (typeof pageXOffset !== 'undefined') { + return { x: pageXOffset, y: pageYOffset }; + } + var d = DayPilot.doc(); + return { x: d.scrollLeft, y: d.scrollTop }; + }; + + DayPilot.indexOf = function(array, object) { + if (!array || !array.length) { + return -1; + } + for (var i = 0; i < array.length; i++) { + if (array[i] === object) { + return i; + } + } + return -1; + }; + + // all children + DayPilot.ac = function(e, children) { + if (!children) { + var children = []; + } + for (var i = 0; e.children && i < e.children.length; i++) { + children.push(e.children[i]); + DayPilot.ac(e.children[i], children); + } + + return children; + }; + + // remove from array + DayPilot.rfa = function(array, object) { + var i = DayPilot.indexOf(array, object); + if (i === -1) { + return; + } + array.splice(i, 1); + }; + + // mouse coords + DayPilot.mc = function(ev){ + if(ev.pageX || ev.pageY){ + return {x:ev.pageX, y:ev.pageY}; + } + return { + x:ev.clientX + document.documentElement.scrollLeft, + y:ev.clientY + document.documentElement.scrollTop + }; + }; + + DayPilot.Stats = {}; + DayPilot.Stats.eventObjects = 0; + DayPilot.Stats.dateObjects = 0; + DayPilot.Stats.cacheHitsCtor = 0; + DayPilot.Stats.cacheHitsParsing = 0; + DayPilot.Stats.cacheHitsTicks = 0; + + DayPilot.re = function(el, ev, func) { + if (!func) { + return; + } + if (!ev) { + return; + } + if (!el) { + return; + } + el.addEventListener(ev, func, false); + }; + + DayPilot.rePassive = function(el, ev, func) { + if (!func) { + return; + } + if (!ev) { + return; + } + if (!el) { + return; + } + el.addEventListener(ev, func, {"passive": true}); + }; + + DayPilot.reNonPassive = function(el, ev, func) { + if (!func) { + return; + } + if (!ev) { + return; + } + if (!el) { + return; + } + el.addEventListener(ev, func, {"passive": false}); + }; + + // purge + // thanks to http://javascript.crockford.com/memory/leak.html + DayPilot.pu = function(d) { + //var removed = []; + //var start = new Date(); + var a = d.attributes, i, l, n; + if (a) { + l = a.length; + for (i = 0; i < l; i += 1) { + if (!a[i]) { + continue; + } + n = a[i].name; + if (typeof d[n] === 'function') { + d[n] = null; + } + } + } + a = d.childNodes; + if (a) { + l = a.length; + for (i = 0; i < l; i += 1) { + var children = DayPilot.pu(d.childNodes[i]); + } + } + }; + + // delete element + DayPilot.de = function(e) { + if (!e) { + return; + } + if (DayPilot.isArray(e)) { + for (var i = 0; i < e.length; i++) { + DayPilot.de(e[i]); + } + return; + } + e.parentNode && e.parentNode.removeChild(e); + }; + + // vertical scrollbar width + DayPilot.sw = function(element) { + if (!element) { + return 0; + } + return element.offsetWidth - element.clientWidth; + }; + + // angular module + DayPilot.am = function() { + if (typeof angular === "undefined") { + return null; + } + if (!DayPilot.am.cached) { + DayPilot.am.cached = angular.module("daypilot", []); + } + return DayPilot.am.cached; + }; + + DayPilot.Selection = function (start, end, resource, root) { + this.type = 'selection'; + this.start = start.isDayPilotDate ? start : new DayPilot.Date(start); + this.end = end.isDayPilotDate ? end : new DayPilot.Date(end); + this.resource = resource; + this.root = root; + + this.toJSON = function(key) { + var json = {}; + json.start = this.start; + json.end = this.end; + json.resource = this.resource; + + return json; + }; + }; + + /* XMLHttpRequest */ + + DayPilot.request = function(url, callback, postData, errorCallback) { + var req = DayPilot.createXmlHttp(); + if (!req) { + return; + } + + req.open("POST", url, true); + req.setRequestHeader('Content-type', 'text/plain'); + req.onreadystatechange = function() { + if (req.readyState !== 4) + return; + if (req.status !== 200 && req.status !== 304) { + if (errorCallback) { + errorCallback(req); + } + else { + if (window.console) { console.log('HTTP error ' + req.status); } + } + return; + } + callback(req); + }; + if (req.readyState === 4) { + return; + } + if (typeof postData === 'object') { + postData = JSON.stringify(postData); + } + req.send(postData); + }; + + DayPilot.ajax = function(params) { + if (!params) { + throw new DayPilot.Exception("Parameter object required."); + } + + if (typeof params.url !== "string") { + throw new DayPilot.Exception("The parameter object must have 'url' property.") + } + + var req = DayPilot.createXmlHttp(); + if (!req) { + throw new DayPilot.Exception("Unable to create XMLHttpRequest object"); + } + + var dataIsObject = typeof params.data === "object"; + + var data = params.data; + var method = params.method || (params.data ? "POST" : "GET"); + var success = params.success || function() {}; + var error = params.error || function() {}; + var url = params.url; + var contentType = params.contentType || (dataIsObject ? "application/json" : "text/plain"); + var headers = params.headers || {}; + + req.open(method, url, true); + req.setRequestHeader('Content-type', contentType); + + // overriding the content-type is allowed + DayPilot.Util.ownPropsAsArray(headers).forEach(function(item) { + req.setRequestHeader(item.key, item.val); + }); + + req.onreadystatechange = function() { + if (req.readyState !== 4) { + return; + } + if (req.status !== 200 && req.status !== 201 && req.status !== 204 && req.status !== 304) { + if (error) { + var args = {}; + args.request = req; + error(args); + } + else { + if (window.console) { console.log('HTTP error ' + req.status); } + } + return; + } + var args = {}; + args.request = req; + if (req.responseText) { + args.data = JSON.parse(req.responseText); + } + success(args); + }; + if (req.readyState === 4) { + return; + } + if (dataIsObject) { + data = JSON.stringify(data); + } + req.send(data); + }; + + DayPilot.createXmlHttp = function() { + return new XMLHttpRequest(); + }; + + DayPilot.Http = {}; + + DayPilot.Http.ajax = function(params) { + DayPilot.ajax(params); + }; + + /* +allowed params: +- headers +- contentType + */ + DayPilot.Http.get = function(url, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "GET"; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Http.post = function(url, data, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "POST"; + aparams.data = data; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Http.put = function(url, data, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "PUT"; + aparams.data = data; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Http.delete = function(url, params) { + params = params || {}; + return new Promise(function(resolve, reject) { + var aparams = {}; + aparams.url = url; + aparams.method = "DELETE"; + aparams.success = function(args) { + resolve(args); + }; + aparams.error = function(args) { + reject(args); + }; + aparams.contentType = params.contentType; + aparams.headers = params.headers; + + DayPilot.ajax(aparams); + }); + }; + + DayPilot.Util = {}; + DayPilot.Util.addClass = function(object, name) { + if (!object) { + return; + } + if (!object.className) { + object.className = name; + return; + } + var already = new RegExp("(^|\\s)" + name + "($|\\s)"); + if (!already.test(object.className)) { + object.className = object.className + ' ' + name; + } + }; + + DayPilot.Util.removeClass = function(object, name) { + if (!object) { + return; + } + var already = new RegExp("(^|\\s)" + name + "($|\\s)"); + object.className = object.className.replace(already, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); // trim spaces + }; + + DayPilot.Util.copyProps = function(source, target, props) { + if (!target) { + target = {}; + } + if (!source) { + return target; + } + if (typeof props === 'undefined') { + for (var name in source) { + if (source.hasOwnProperty(name) && typeof source[name] !== 'undefined') { + target[name] = source[name]; + } + } + } + else { + for (var i = 0; i < props.length; i++) { + var name = props[i]; + if (typeof source[name] !== 'undefined') { + target[name] = source[name]; + } + } + } + return target; + }; + + DayPilot.Util.ownPropsAsArray = function(object) { + var result = []; + + if (!object) { + return result; + } + + for (var name in object) { + if (object.hasOwnProperty(name)) { + var item = {}; + item.key = name; + item.val = object[name]; + result.push(item); + } + } + + return result; + }; + + DayPilot.Util.replaceCharAt = function(str, index, character) { + return str.substr(0, index) + character + str.substr(index + character.length); + }; + + DayPilot.Util.isNullOrUndefined = function(val) { + return val === null || typeof val === "undefined"; + }; + + DayPilot.Util.escapeHtml = function(html) { + var div = document.createElement("div"); + div.innerText = html; + return div.innerHTML; + }; + + DayPilot.Util.escapeTextHtml = function(text, html) { + if (!DayPilot.Util.isNullOrUndefined(html)) { + return html; + } + if (DayPilot.Util.isNullOrUndefined(text)) { + return ""; + } + return DayPilot.Util.escapeHtml(text); + }; + + /* areas */ + + DayPilot.Areas = {}; + + /** + * Attach active areas to a target div. + * Works with "Visible", "TouchVisible" and "Hover" visibility + */ + DayPilot.Areas.attach = function (div, e, options) { + var options = options || {}; + var areas = options.areas; + var allowed = options.allowed || function() { return true; }; + var offsetX = options.offsetX || 0; + + // permanently visible active areas + areas = areasExtract(e, areas); + + if (!areas) { + return; + } + + if (!DayPilot.isArray(areas)) { + return; + } + + if (areas.length === 0) { + return; + } + + DayPilot.re(div, "mousemove", function(ev) { + if (!div.active && !div.areasDisabled && allowed()) { + DayPilot.Areas.showAreas(div, e, ev, areas, { "offsetX": offsetX, "eventDiv": options.eventDiv}); + } + }); + DayPilot.re(div, "mouseleave", function(ev) { + DayPilot.Areas.hideAreas(div, ev); + }); + + areas.forEach(function(area) { + if (!DayPilot.Areas.isVisible(area)) { + return; + } + var a = DayPilot.Areas.createArea(div, e, area, { "offsetX": offsetX, "eventDiv": options.eventDiv}); + div.appendChild(a); + }); + }; + + DayPilot.Areas.disable = function(div) { + div.areasDisabled = true; + Array.from(div.childNodes).filter(function(item) { return item.isActiveArea && !item.area.start; }).forEach(function(item) { + item._originalDisplay = item.style.display; + item.style.display = "none"; + }); + }; + + DayPilot.Areas.enable = function(div) { + div.areasDisabled = false; + Array.from(div.childNodes).filter(function(item) { return item.isActiveArea && !item.area.start; }).forEach(function(item) { + if (item._originalDisplay) { + item.style.display = item._originalDisplay; + } + else { + item.style.display = ""; + } + }); + }; + + DayPilot.Areas.remove = function(div) { + var divs = Array.from(div.childNodes).filter(function(item) { return item.isActiveArea; }); + + DayPilot.de(divs); + }; + + DayPilot.Areas.isVisible = function(area) { + var v = area.visibility || area.v || "Visible"; + if (v === "Visible") { + return true; + } + if (v === "TouchVisible") { + if (!DayPilot.browser.hover) { + return true; + } + } + return false; + }; + + DayPilot.Areas.copy = function(areas) { + if (!DayPilot.isArray(areas)) { + return []; + } + + return areas.map(function(area) { + return DayPilot.Util.copyProps(area, {}); + }); + }; + + /** + * Extracts areas array from the source object, giving priority to a standalone areas object. + * @param e + * @param areas + */ + var areasExtract = function(e, areas) { + if (!DayPilot.isArray(areas)) { + areas = e.areas; + if (!areas) { + if (e.cache) { + areas = e.cache.areas; + } + else if (e.data) { + areas = e.data.areas; + } + } + } + return areas; + }; + + + DayPilot.Areas.showAreas = function(div, e, ev, areas, options) { + if (DayPilot.Global.resizing) { + return; + } + + if (DayPilot.Global.moving) { + return; + } + + if (DayPilot.Global.selecting) { + return; + } + + if (div.active) { + return; + } + + if (!DayPilot.browser.hover) { + return; + } + + if (DayPilot.Areas.all && DayPilot.Areas.all.length > 0) { + for (var i = 0; i < DayPilot.Areas.all.length; i++) { + var d = DayPilot.Areas.all[i]; + if (d !== div) { + DayPilot.Areas.hideAreas(d, ev); + } + } + } + + div.active = {}; + + //var areas; + if (!DayPilot.isArray(areas)) { + areas = e.areas; + if (!areas) { + if (e.cache) { + areas = e.cache.areas; + } + else if (e.data) { + areas = e.data.areas; + } + } + } + + if (!areas || areas.length === 0) { + return; + } + + if (div.areas && div.areas.length > 0) { + return; + } + div.areas = []; + + for (var i = 0; i < areas.length; i++) { + var area = areas[i]; + + if (DayPilot.Areas.isVisible(area)) { + continue; + } + + var a = DayPilot.Areas.createArea(div, e, area, options); + + div.areas.push(a); + div.appendChild(a); + + DayPilot.Areas.all.push(div); + } + div.active.children = DayPilot.ac(div); + }; + + /** + * + * @param div Target div element + * @param e Source data object + * @param area Area definition + * @returns {Element} + */ + DayPilot.Areas.createArea = function(div, e, area, options) { + + /* + actions: + - Default (equals not specified) + - None (cancels bubbling to parent element) + - ContextMenu + - HoverMenu + - ResizeStart + - ResizeEnd + - Move + - excluded: JavaScript, Bubble + */ + + var options = options || {}; + var offsetX = options.offsetX || 0; + var ediv = options.eventDiv || div; + + var a = document.createElement("div"); + a.isActiveArea = true; + a.area = area; + a.setAttribute("unselectable", "on"); + var w = area.w || area.width; + var h = area.h || area.height; + var css = area.cssClass || area.css || area.className; + if (typeof area.style !== "undefined") { + a.setAttribute("style", area.style); + } + a.style.position = "absolute"; + + a.style.width = resolvePosVal(w); + a.style.height = resolvePosVal(h); + a.style.right = resolvePosVal(area.right); + a.style.top = resolvePosVal(area.top); + a.style.left = resolvePosVal(area.left); + a.style.bottom = resolvePosVal(area.bottom); + + if (typeof area.html !== 'undefined' || typeof area.text !== "undefined") { + // a.innerHTML = area.html || area.text; + a.innerHTML = DayPilot.Util.escapeTextHtml(area.text, area.html); + } + else if (area.icon) { + var iel = document.createElement("i"); + iel.className = area.icon; + a.appendChild(iel); + } + else if (area.image) { + var img = document.createElement("img"); + img.src = area.image; + a.appendChild(img); + } + else if (area.symbol) { + var ns = "http://www.w3.org/2000/svg"; + var svg = document.createElementNS(ns,"svg"); + svg.setAttribute("width", "100%"); + svg.setAttribute("height", "100%"); + var use = document.createElementNS(ns,"use"); + use.setAttribute("href", area.symbol); + svg.appendChild(use); + a.appendChild(svg); + } + + if (css) { + a.className = css; + } + if (area.toolTip) { + a.setAttribute("title", area.toolTip); + } + if (area.backColor) { + a.style.background = area.backColor; + } + if (area.background) { // alias + a.style.background = area.background; + } + if (area.fontColor) { + a.style.color = area.fontColor; + } + if (area.padding) { + a.style.padding = area.padding + "px"; + a.style.boxSizing = "border-box"; + } + if (area.verticalAlignment) { + a.style.display = "flex"; + switch (area.verticalAlignment) { + case "center": + a.style.alignItems = "center"; + break; + case "top": + a.style.alignItems = "flex-start"; + break; + case "bottom": + a.style.alignItems = "flex-end"; + break; + } + } + if (area.horizontalAlignment) { + a.style.display = "flex"; + switch (area.horizontalAlignment) { + case "right": + a.style.justifyContent = "flex-end"; + break; + case "left": + a.style.justifyContent = "flex-start"; + break; + case "center": + a.style.justifyContent = "center"; + break; + } + } + + if (area.action === "ResizeEnd" || area.action === "ResizeStart" || area.action === "Move") { + if (e.calendar.isCalendar) { + switch (area.action) { + case "ResizeEnd": + area.cursor = "s-resize"; + area.dpBorder = "bottom"; + break; + case "ResizeStart": + area.cursor = "n-resize"; + area.dpBorder = "top"; + break; + case "Move": + area.cursor = "move"; + break; + } + } + if (e.calendar.isScheduler || e.calendar.isMonth) { + switch (area.action) { + case "ResizeEnd": + area.cursor = "e-resize"; + area.dpBorder = "right"; + break; + case "ResizeStart": + area.cursor = "w-resize"; + area.dpBorder = "left"; + break; + case "Move": + area.cursor = "move"; + break; + } + } + a.onmousemove = (function(div, e, area) { + return function(ev) { + + if (e.calendar.internal && e.calendar.internal.dragInProgress && e.calendar.internal.dragInProgress()) { // resizing in progress + return; + } + ev.cancelBubble = true; + + div.style.cursor = area.cursor; + if (area.dpBorder) { + div.dpBorder = area.dpBorder; + } + }; + })(ediv, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + div.style.cursor = ''; + }; + })(ediv, e, area); + } + if ((area.action === "ResizeEnd" || area.action === "ResizeStart") && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + var touch = e.calendar.internal.touch; + var t = ev.touches ? ev.touches[0] : ev; + var coords = {x: t.pageX, y: t.pageY }; + // immediately + e.calendar.coords = touch.relativeCoords(ev); + touch.preventEventTap = true; + if (e.calendar.isScheduler) { + touch.startResizing(div, area.action === "ResizeEnd" ? "right" : "left"); + } + else if (e.calendar.isCalendar) { + touch.startResizing(div, area.action === "ResizeEnd" ? "bottom" : "top", coords); + } + + }; + })(ediv, e, area); + DayPilot.rePassive(a, DayPilot.touch.start, touchstart); + // a.addEventListener(DayPilot.touch.start, touchstart, {"passive": true}); + } + } + if (area.action === "ContextMenu" && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + + showContextMenu(div, e, area, ev); + var touch = e.calendar.internal.touch; + touch.preventEventTap = true; + }; + })(ediv, e, area); + var touchend = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + }; + })(ediv, e, area); + DayPilot.reNonPassive(a, DayPilot.touch.start, touchstart); + DayPilot.reNonPassive(a, DayPilot.touch.end, touchend); + } + } + if (area.action === "Bubble" && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + + var args = doOnClick(area, e, ev); + if (args.preventDefault.value) { + return; + } + showBubble(e, area, ev); + var touch = e.calendar.internal.touch; + touch.preventEventTap = true; + + if (typeof area.onClicked === "function") { + area.onClicked(args); + } + }; + })(ediv, e, area); + var touchend = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + ev.preventDefault(); + }; + })(ediv, e, area); + DayPilot.reNonPassive(a, DayPilot.touch.start, touchstart); + DayPilot.reNonPassive(a, DayPilot.touch.end, touchend); + } + } + if (area.action === "Move" && e.isEvent) { + if (e.calendar.internal.touch) { + var touchstart = (function(div, e, area) { + return function(ev) { + ev.cancelBubble = true; + var touch = e.calendar.internal.touch; + var t = ev.touches ? ev.touches[0] : ev; + var coords = {x: t.pageX, y: t.pageY }; + // immediately + e.calendar.coords = touch.relativeCoords(ev); + + // DayPilot.Global.movingAreaData = area.data; + if (DayPilot.Global && DayPilot.Global.touch) { + DayPilot.Global.touch.active = true; + } + + touch.preventEventTap = true; + touch.startMoving(div, coords); + }; + })(ediv, e, area); + DayPilot.rePassive(a, DayPilot.touch.start, touchstart); + // a.addEventListener(DayPilot.touch.start, touchstart, {"passive": true}); + } + } + if (area.action === "Bubble" && e.isEvent) { + a.onmousemove = (function(div, e, area) { + return function(ev) { + if (area.bubble) { + area.bubble.showEvent(e, true); + } + else if (e.calendar.bubble) { + e.calendar.bubble.showEvent(e, true); + } + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + if (typeof DayPilot.Bubble !== "undefined") { + //DayPilot.Bubble.hideActive(); + if (area.bubble) { + area.bubble.hideOnMouseOut(); + } + else if (e.calendar.bubble) { + e.calendar.bubble.hideOnMouseOut(); + } + } + + }; + })(div, e, area); + } + else if (area.action === "Bubble" && e.isRow) { + a.onmousemove = (function(div, e, area) { + return function(ev) { + if (area.bubble) { + area.bubble.showResource(e, true); + } + else if (e.calendar.resourceBubble) { + e.calendar.resourceBubble.showResource(e, true); + } + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + if (typeof DayPilot.Bubble !== "undefined") { + //DayPilot.Bubble.hideActive(); + if (area.bubble) { + area.bubble.hideOnMouseOut(); + } + else if (e.calendar.resourceBubble) { + e.calendar.resourceBubble.hideOnMouseOut(); + } + } + + }; + })(div, e, area); + } + else if (area.action === "Bubble" && typeof DayPilot.Bubble !== "undefined" && area.bubble instanceof DayPilot.Bubble) { + a.onmousemove = (function(div, e, area) { + return function(ev) { + area.bubble.showHtml(null, null); + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + if (typeof DayPilot.Bubble !== "undefined") { + if (area.bubble) { + area.bubble.hideOnMouseOut(); + } + } + + }; + })(div, e, area); + } + if (area.action === "HoverMenu") { + a.onmousemove = (function(div, e, area) { + return function(ev) { + var m = area.menu; + if (m && m.show) { + if (!m.visible) { + m.show(e); + } + else if (m.source && typeof m.source.id !== 'undefined' && m.source.id !== e.id) { + m.show(e); + } + m.cancelHideTimeout(); + } + }; + })(div, e, area); + a.onmouseout = (function(div, e, area) { + return function(ev) { + var m = area.menu; + if (!m) { + return; + } + if (m.hideOnMouseOver) { + m.delayedHide(); + } + }; + })(div, e, area); + } + if (area.action === "None") { + var touchstart = (function(div, e, area) { + return function(ev) { + var args = doOnClick(area, e, ev); + + if (typeof area.onClicked === "function") { + area.onClicked(args); + } + + ev.preventDefault(); + ev.stopPropagation(); + }; + })(ediv, e, area); + DayPilot.reNonPassive(a, DayPilot.touch.start, touchstart); + } + + // prevent event moving + a.onmousedown = (function(div, e, area) { + return function(ev) { + if (typeof area.onmousedown === 'function') { // obsolete, remove + area.onmousedown(ev); + } + + if (typeof area.mousedown === 'function') { // internal + var args = {}; + args.area = area; + args.div = div; + args.originalEvent = ev; + args.source = e; + area.mousedown(args); + } + + if (area.action === "Move" && e.isRow) { + var row = e.$.row; + var startMoving = e.calendar.internal.rowStartMoving; + + startMoving(row); + } + + // cancel any bubble + if (typeof DayPilot.Bubble !== "undefined") { + DayPilot.Bubble.hideActive(); + } + + if (area.action === "Move") { + DayPilot.Global.movingAreaData = area.data; + } + + if (area.action === "Move" && e.isEvent) { + if (e.calendar.internal && e.calendar.internal.startMoving) { + e.calendar.internal.startMoving(div, ev); + } + } + + var cancel = true; + + if (cancel) { + if (area.action === "Move" || area.action === "ResizeEnd" || area.action === "ResizeStart" || !area.action || area.action === "Default") { + return; + } + ev.preventDefault(); // prevents text selection on dragging + ev.cancelBubble = true; + } + }; + })(div, e, area); + a.onclick = (function(div, e, area) { + return function(ev) { + var args = doOnClick(area, e, ev); + + if (args.preventDefault.value) { + return; + } + + switch (area.action) { + case "ContextMenu": + showContextMenu(div, e, area, ev); + ev.cancelBubble = true; + break; + case "None": + ev.cancelBubble = true; + break; + } + + if (typeof area.onClicked === "function") { + area.onClicked(args); + } + }; + })(div, e, area); + + if (typeof area.onMouseEnter === "function") { + a.addEventListener("mouseenter", (function(div, e, area) { + return function(ev) { + var args = {}; + args.area = area; + args.source = e; + args.originalEvent = ev; + area.onMouseEnter(args); + }; + })(div, e, area)); + } + if (typeof area.onMouseLeave === "function") { + a.addEventListener("mouseleave", (function(div, e, area) { + return function(ev) { + var args = {}; + args.area = area; + args.source = e; + args.originalEvent = ev; + area.onMouseLeave(args); + }; + })(div, e, area)); + } + + function doOnClick(area, source, originalEvent) { + var args = {}; + args.area = area; + args.source = source; + args.originalEvent = originalEvent; + args.preventDefault = function() { + args.preventDefault.value = true; + }; + + if (typeof area.onClick === "function") { + area.onClick(args); + } + return args; + } + + function showBubble(e, area, ev) { + if (DayPilot.Bubble) { + DayPilot.Bubble.touchPosition(ev); + } + + if (e.calendar.bubble) { + e.calendar.bubble.showEvent(e, true); + } + } + + function showContextMenu(div, e, area, ev) { + if (DayPilot.Menu) { + DayPilot.Menu.touchPosition(ev); + } + + var m = area.contextMenu || area.menu; + if (!(m instanceof DayPilot.Menu)) { + if (e.isEvent && e.client.contextMenu()) { + m = e.client.contextMenu(); + } + else if (e.isEvent && e.calendar.contextMenu) { + m = e.calendar.contextMenu; + } + } + if (m && m.show) { + var initiator = { "type": "area", "div": div, "e": e, "area": area, "a": a}; + m.show(e, { "initiator": initiator}); + } + } + + function resolvePosVal(val) { + if (typeof val === "string" && isNaN(val)) { + return val; + } + else if (typeof val !== "undefined") { + return val + "px"; + } + return undefined; + } + + return a; + }; + + DayPilot.Areas.all = []; + + DayPilot.Areas.hideAreas = function(div, ev) { + if (!div) { + return; + } + + if (!div || !div.active) { + return; + } + + var active = div.active; + var areas = div.areas; + + if (active && active.children) { + if (ev) { + var target = ev.toElement || ev.relatedTarget; + if (~DayPilot.indexOf(active.children, target)) { + return; + } + } + } + + if (!areas || areas.length === 0) { + div.active = null; + return; + } + + DayPilot.de(areas); + + div.active = null; + div.areas = []; + + DayPilot.rfa(DayPilot.Areas.all, div); + + active.children = null; + }; + + DayPilot.Areas.hideAll = function(ev) { + if (!DayPilot.Areas.all || DayPilot.Areas.all.length === 0) { + return; + } + for (var i = 0; i < DayPilot.Areas.all.length; i++) { + DayPilot.Areas.hideAreas(DayPilot.Areas.all[i], ev); + } + + }; + + /* end of areas */ + + DayPilot.Exception = function(msg) { + return new Error(msg); + }; + + DayPilot.Locale = function(id, config) { + this.id = id; + this.dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; + this.dayNamesShort = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; + this.monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; + this.datePattern = "M/d/yyyy"; + this.timePattern = "H:mm"; + this.dateTimePattern = "M/d/yyyy H:mm"; + this.timeFormat = "Clock12Hours"; + this.weekStarts = 0; + + if (config) { + for (var name in config) { + this[name] = config[name]; + } + } + }; + + DayPilot.Locale.all = {}; + + DayPilot.Locale.find = function(id) { + if (!id) { + return null; + } + var normalized = id.toLowerCase(); + if (normalized.length > 2) { + normalized = DayPilot.Util.replaceCharAt(normalized, 2, '-'); + } + return DayPilot.Locale.all[normalized]; + }; + + DayPilot.Locale.register = function(locale) { + DayPilot.Locale.all[locale.id] = locale; + }; + + DayPilot.Locale.register(new DayPilot.Locale('ca-es', {'dayNames':['diumenge','dilluns','dimarts','dimecres','dijous','divendres','dissabte'],'dayNamesShort':['dg','dl','dt','dc','dj','dv','ds'],'monthNames':['gener','febrer','març','abril','maig','juny','juliol','agost','setembre','octubre','novembre','desembre',''],'monthNamesShort':['gen.','febr.','març','abr.','maig','juny','jul.','ag.','set.','oct.','nov.','des.',''],'timePattern':'H:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('cs-cz', {'dayNames':['neděle','pondělí','úterý','středa','čtvrtek','pátek','sobota'],'dayNamesShort':['ne','po','út','st','čt','pá','so'],'monthNames':['leden','únor','březen','duben','květen','červen','červenec','srpen','září','říjen','listopad','prosinec',''],'monthNamesShort':['I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII',''],'timePattern':'H:mm','datePattern':'d. M. yyyy','dateTimePattern':'d. M. yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('da-dk', {'dayNames':['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],'dayNamesShort':['sø','ma','ti','on','to','fr','lø'],'monthNames':['januar','februar','marts','april','maj','juni','juli','august','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'HH:mm','datePattern':'dd-MM-yyyy','dateTimePattern':'dd-MM-yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-at', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Jänner','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jän','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-ch', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-de', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('de-lu', {'dayNames':['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],'dayNamesShort':['So','Mo','Di','Mi','Do','Fr','Sa'],'monthNames':['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember',''],'monthNamesShort':['Jan','Feb','Mrz','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('en-au', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'h:mm tt','datePattern':'d/MM/yyyy','dateTimePattern':'d/MM/yyyy h:mm tt','timeFormat':'Clock12Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('en-ca', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'h:mm tt','datePattern':'yyyy-MM-dd','dateTimePattern':'yyyy-MM-dd h:mm tt','timeFormat':'Clock12Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('en-gb', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('en-us', {'dayNames':['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],'dayNamesShort':['Su','Mo','Tu','We','Th','Fr','Sa'],'monthNames':['January','February','March','April','May','June','July','August','September','October','November','December',''],'monthNamesShort':['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',''],'timePattern':'h:mm tt','datePattern':'M/d/yyyy','dateTimePattern':'M/d/yyyy h:mm tt','timeFormat':'Clock12Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('es-es', {'dayNames':['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],'dayNamesShort':['D','L','M','X','J','V','S'],'monthNames':['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre',''],'monthNamesShort':['ene.','feb.','mar.','abr.','may.','jun.','jul.','ago.','sep.','oct.','nov.','dic.',''],'timePattern':'H:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('es-mx', {'dayNames':['domingo','lunes','martes','miércoles','jueves','viernes','sábado'],'dayNamesShort':['do.','lu.','ma.','mi.','ju.','vi.','sá.'],'monthNames':['enero','febrero','marzo','abril','mayo','junio','julio','agosto','septiembre','octubre','noviembre','diciembre',''],'monthNamesShort':['ene.','feb.','mar.','abr.','may.','jun.','jul.','ago.','sep.','oct.','nov.','dic.',''],'timePattern':'hh:mm tt','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy hh:mm tt','timeFormat':'Clock12Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('eu-es', {'dayNames':['igandea','astelehena','asteartea','asteazkena','osteguna','ostirala','larunbata'],'dayNamesShort':['ig','al','as','az','og','or','lr'],'monthNames':['urtarrila','otsaila','martxoa','apirila','maiatza','ekaina','uztaila','abuztua','iraila','urria','azaroa','abendua',''],'monthNamesShort':['urt.','ots.','mar.','api.','mai.','eka.','uzt.','abu.','ira.','urr.','aza.','abe.',''],'timePattern':'H:mm','datePattern':'yyyy/MM/dd','dateTimePattern':'yyyy/MM/dd H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fi-fi', {'dayNames':['sunnuntai','maanantai','tiistai','keskiviikko','torstai','perjantai','lauantai'],'dayNamesShort':['su','ma','ti','ke','to','pe','la'],'monthNames':['tammikuu','helmikuu','maaliskuu','huhtikuu','toukokuu','kesäkuu','heinäkuu','elokuu','syyskuu','lokakuu','marraskuu','joulukuu',''],'monthNamesShort':['tammi','helmi','maalis','huhti','touko','kesä','heinä','elo','syys','loka','marras','joulu',''],'timePattern':'H:mm','datePattern':'d.M.yyyy','dateTimePattern':'d.M.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-be', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd-MM-yy','dateTimePattern':'dd-MM-yy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-ch', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-fr', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('fr-lu', {'dayNames':['dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi'],'dayNamesShort':['di','lu','ma','me','je','ve','sa'],'monthNames':['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre',''],'monthNamesShort':['janv.','févr.','mars','avr.','mai','juin','juil.','août','sept.','oct.','nov.','déc.',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('gl-es', {'dayNames':['domingo','luns','martes','mércores','xoves','venres','sábado'],'dayNamesShort':['do','lu','ma','mé','xo','ve','sá'],'monthNames':['xaneiro','febreiro','marzo','abril','maio','xuño','xullo','agosto','setembro','outubro','novembro','decembro',''],'monthNamesShort':['xan','feb','mar','abr','maio','xuño','xul','ago','set','out','nov','dec',''],'timePattern':'H:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('it-it', {'dayNames':['domenica','lunedì','martedì','mercoledì','giovedì','venerdì','sabato'],'dayNamesShort':['do','lu','ma','me','gi','ve','sa'],'monthNames':['gennaio','febbraio','marzo','aprile','maggio','giugno','luglio','agosto','settembre','ottobre','novembre','dicembre',''],'monthNamesShort':['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('it-ch', {'dayNames':['domenica','lunedì','martedì','mercoledì','giovedì','venerdì','sabato'],'dayNamesShort':['do','lu','ma','me','gi','ve','sa'],'monthNames':['gennaio','febbraio','marzo','aprile','maggio','giugno','luglio','agosto','settembre','ottobre','novembre','dicembre',''],'monthNamesShort':['gen','feb','mar','apr','mag','giu','lug','ago','set','ott','nov','dic',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('ja-jp', {'dayNames':['日曜日','月曜日','火曜日','水曜日','木曜日','金曜日','土曜日'],'dayNamesShort':['日','月','火','水','木','金','土'],'monthNames':['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月',''],'monthNamesShort':['1','2','3','4','5','6','7','8','9','10','11','12',''],'timePattern':'H:mm','datePattern':'yyyy/MM/dd','dateTimePattern':'yyyy/MM/dd H:mm','timeFormat':'Clock24Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('nb-no', {'dayNames':['søndag','mandag','tirsdag','onsdag','torsdag','fredag','lørdag'],'dayNamesShort':['sø','ma','ti','on','to','fr','lø'],'monthNames':['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember',''],'monthNamesShort':['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('nl-nl', {'dayNames':['zondag','maandag','dinsdag','woensdag','donderdag','vrijdag','zaterdag'],'dayNamesShort':['zo','ma','di','wo','do','vr','za'],'monthNames':['januari','februari','maart','april','mei','juni','juli','augustus','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'HH:mm','datePattern':'d-M-yyyy','dateTimePattern':'d-M-yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('nl-be', {'dayNames':['zondag','maandag','dinsdag','woensdag','donderdag','vrijdag','zaterdag'],'dayNamesShort':['zo','ma','di','wo','do','vr','za'],'monthNames':['januari','februari','maart','april','mei','juni','juli','augustus','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'H:mm','datePattern':'d/MM/yyyy','dateTimePattern':'d/MM/yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('nn-no', {'dayNames':['søndag','måndag','tysdag','onsdag','torsdag','fredag','laurdag'],'dayNamesShort':['sø','må','ty','on','to','fr','la'],'monthNames':['januar','februar','mars','april','mai','juni','juli','august','september','oktober','november','desember',''],'monthNamesShort':['jan','feb','mar','apr','mai','jun','jul','aug','sep','okt','nov','des',''],'timePattern':'HH:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('pt-br', {'dayNames':['domingo','segunda-feira','terça-feira','quarta-feira','quinta-feira','sexta-feira','sábado'],'dayNamesShort':['D','S','T','Q','Q','S','S'],'monthNames':['janeiro','fevereiro','março','abril','maio','junho','julho','agosto','setembro','outubro','novembro','dezembro',''],'monthNamesShort':['jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('pl-pl', {'dayNames':['niedziela','poniedziałek','wtorek','środa','czwartek','piątek','sobota'],'dayNamesShort':['N','Pn','Wt','Śr','Cz','Pt','So'],'monthNames':['styczeń','luty','marzec','kwiecień','maj','czerwiec','lipiec','sierpień','wrzesień','październik','listopad','grudzień',''],'monthNamesShort':['sty','lut','mar','kwi','maj','cze','lip','sie','wrz','paź','lis','gru',''],'timePattern':'HH:mm','datePattern':'yyyy-MM-dd','dateTimePattern':'yyyy-MM-dd HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('pt-pt', {'dayNames':['domingo','segunda-feira','terça-feira','quarta-feira','quinta-feira','sexta-feira','sábado'],'dayNamesShort':['D','S','T','Q','Q','S','S'],'monthNames':['janeiro','fevereiro','março','abril','maio','junho','julho','agosto','setembro','outubro','novembro','dezembro',''],'monthNamesShort':['jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez',''],'timePattern':'HH:mm','datePattern':'dd/MM/yyyy','dateTimePattern':'dd/MM/yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':0})); + DayPilot.Locale.register(new DayPilot.Locale('ro-ro', {'dayNames':['duminică','luni','marți','miercuri','joi','vineri','sâmbătă'],'dayNamesShort':['D','L','Ma','Mi','J','V','S'],'monthNames':['ianuarie','februarie','martie','aprilie','mai','iunie','iulie','august','septembrie','octombrie','noiembrie','decembrie',''],'monthNamesShort':['ian.','feb.','mar.','apr.','mai.','iun.','iul.','aug.','sep.','oct.','nov.','dec.',''],'timePattern':'H:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('ru-ru', {'dayNames':['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],'dayNamesShort':['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],'monthNames':['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь',''],'monthNamesShort':['янв','фев','мар','апр','май','июн','июл','авг','сен','окт','ноя','дек',''],'timePattern':'H:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('sk-sk', {'dayNames':['nedeľa','pondelok','utorok','streda','štvrtok','piatok','sobota'],'dayNamesShort':['ne','po','ut','st','št','pi','so'],'monthNames':['január','február','marec','apríl','máj','jún','júl','august','september','október','november','december',''],'monthNamesShort':['1','2','3','4','5','6','7','8','9','10','11','12',''],'timePattern':'H:mm','datePattern':'d.M.yyyy','dateTimePattern':'d.M.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('sv-se', {'dayNames':['söndag','måndag','tisdag','onsdag','torsdag','fredag','lördag'],'dayNamesShort':['sö','må','ti','on','to','fr','lö'],'monthNames':['januari','februari','mars','april','maj','juni','juli','augusti','september','oktober','november','december',''],'monthNamesShort':['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec',''],'timePattern':'HH:mm','datePattern':'yyyy-MM-dd','dateTimePattern':'yyyy-MM-dd HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('tr-tr', {'dayNames':['Pazar','Pazartesi','Salı','Çarşamba','Perşembe','Cuma','Cumartesi'],'dayNamesShort':['Pz','Pt','Sa','Ça','Pe','Cu','Ct'],'monthNames':['Ocak','Şubat','Mart','Nisan','Mayıs','Haziran','Temmuz','Ağustos','Eylül','Ekim','Kasım','Aralık',''],'monthNamesShort':['Oca','Şub','Mar','Nis','May','Haz','Tem','Ağu','Eyl','Eki','Kas','Ara',''],'timePattern':'HH:mm','datePattern':'d.M.yyyy','dateTimePattern':'d.M.yyyy HH:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('uk-ua', {'dayNames':['неділя','понеділок','вівторок','середа','четвер',"п'ятниця",'субота'],'dayNamesShort':['Нд','Пн','Вт','Ср','Чт','Пт','Сб'],'monthNames':['січень','лютий','березень','квітень','травень','червень','липень','серпень','вересень','жовтень','листопад','грудень',''],'monthNamesShort':['Січ','Лют','Бер','Кві','Тра','Чер','Лип','Сер','Вер','Жов','Лис','Гру',''],'timePattern':'H:mm','datePattern':'dd.MM.yyyy','dateTimePattern':'dd.MM.yyyy H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('zh-cn', {'dayNames':['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],'dayNamesShort':['日','一','二','三','四','五','六'],'monthNames':['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月',''],'monthNamesShort':['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月',''],'timePattern':'H:mm','datePattern':'yyyy/M/d','dateTimePattern':'yyyy/M/d H:mm','timeFormat':'Clock24Hours','weekStarts':1})); + DayPilot.Locale.register(new DayPilot.Locale('zh-tw', {'dayNames':['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],'dayNamesShort':['日','一','二','三','四','五','六'],'monthNames':['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月',''],'monthNamesShort':['一月','二月','三月','四月','五月','六月','七月','八月','九月','十月','十一月','十二月',''],'timePattern':'tt hh:mm','datePattern':'yyyy/M/d','dateTimePattern':'yyyy/M/d tt hh:mm','timeFormat':'Clock12Hours','weekStarts':0})); + + DayPilot.Locale.US = DayPilot.Locale.find("en-us"); + + /** + * Created on 2023-04-04. + */ + + DayPilot.Switcher = function(options) { + + var This = this; + + this._views = []; + this._triggers = []; + this._navigator = {}; + + this.selectedClass = null; + + this._active = null; + + this._day = DayPilot.Date.today(); + + this.onChange = null; + this.onChanged = null; + this.onSelect = null; + + this._navigator.updateMode = function (mode) { + var control = This._navigator.control; + if (!control) { + return; + } + control.selectMode = mode; + control.select(This._day); + }; + + this.addView = function (spec, options) { + var element; + if (typeof spec === 'string') { + element = document.getElementById(spec); + if (!element) { + throw "Element not found: " + spec; + } + } + else { // DayPilot object, DOM element + element = spec; + } + + var control = element; + + var view = {}; + view._isView = true; + view._id = control.id; + view.control = control; + view._options = options || {}; + view._hide = function () { + if (control.hide) { + control.hide(); + } + else if (control.nav && control.nav.top) { + control.nav.top.style.display = 'none'; + } + else { + control.style.display = 'none'; + } + }; + view._sendNavigate = function(date) { + var serverBased = (function() { + if (control.backendUrl) { // ASP.NET MVC, Java + return true; + } + if (typeof WebForm_DoCallback === 'function' && control.uniqueID) { // ASP.NET WebForms + return true; + } + return false; + })(); + if (serverBased) { + if (control.commandCallBack) { + control.commandCallBack("navigate", { "day": date }); + } + } + else { + control.startDate = date; + control.update(); + } + }; + view._show = function () { + This._hideViews(); + if (control.show) { + control.show(); + } + else if (control.nav && control.nav.top) { + control.nav.top.style.display = ''; + } + else { + control.style.display = ''; + } + }; + view._selectMode = function () { // for navigator + if (view._options.navigatorSelectMode) { + return view._options.navigatorSelectMode; + } + + if (control.isCalendar) { + switch (control.viewType) { + case "Day": + return "day"; + case "Week": + return "week"; + case "WorkWeek": + return "week"; + default: + return "day"; + } + } + else if (control.isMonth) { + switch (control.viewType) { + case "Month": + return "month"; + case "Weeks": + return "week"; + default: + return "day"; + } + } + return "day"; + }; + + this._views.push(view); + + return view; + }; + + this.addTrigger = function (id, control) { + var element; + if (typeof id === 'string') { + element = document.getElementById(id); + if (!element) { + throw "Element not found: " + id; + } + } + else { + element = id; + } + + var view = this._findViewByControl(control); + if (!view) { + view = this.addView(control); + } + + var trigger = {}; + trigger._isTrigger = true; + trigger._element = element; + trigger._id = element.id; + trigger._view = view; + trigger._onClick = function (ev) { + + This.show(trigger); + This._select(trigger); + + if (ev) { + ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; + } + + }; + + DayPilot.re(element, 'click', trigger._onClick); + + this._triggers.push(trigger); + + return trigger; + }; + + // backwards compatibility + this.addButton = this.addTrigger; + + this.select = function(id) { + var trigger = this._findTriggerById(id); + if (trigger) { + trigger._onClick(); + } + else if (this._triggers.length > 0) { + this._triggers[0]._onClick(); + } + }; + + this._findTriggerById = function(id) { + for (var i = 0; i < this._triggers.length; i++) { + var trigger = this._triggers[i]; + if (trigger._id === id) { + return trigger; + } + } + return null; + }; + + this._select = function(trigger) { + if (!this.selectedClass) { + return; + } + + for (var i = 0; i < this._triggers.length; i++) { + var s = this._triggers[i]; + DayPilot.Util.removeClass(s._element, this.selectedClass); + } + DayPilot.Util.addClass(trigger._element, this.selectedClass); + }; + + this.addNavigator = function (control) { + //this.navigator = {}; + This._navigator.control = control; + + control.timeRangeSelectedHandling = "JavaScript"; + control.onTimeRangeSelected = function() { + var start, end, day; + if (control.api === 1) { + start = arguments[0]; + end = arguments[1]; + day = arguments[2]; + } + else { + var args = arguments[0]; + start = args.start; + end = args.end; + day = args.day; + } + This._day = day; + + navigate(start, end, day); + + }; + }; + + this.show = function (el) { + var view, trigger; + if (el._isTrigger) { + trigger = el; + view = trigger._view; + } + else { + view = el._isView ? el : this._findViewByControl(el); + if (this._active === view) { + return; + } + } + + if (This.onSelect) { + var args = {}; + args.source = trigger ? trigger._element : null; + args.target = view.control; + + This.onSelect(args); + // TODO add preventDefault + } + + this._active = view; + view._show(); + + var mode = view._selectMode(); + This._navigator.updateMode(mode); + + //This.navigator.select(This.day); + + //This.active.sendNavigate(this.day); + + // this ensures first onChange call if single day = today is displayed + var start = This._navigator.control.selectionStart; + var end = This._navigator.control.selectionEnd.addDays(1); + var day = This._navigator.control.selectionDay; + navigate(start, end, day); + }; + + this._findViewByControl = function (control) { + for (var i = 0; i < this._views.length; i++) { + if (this._views[i].control === control) { + return this._views[i]; + } + } + return null; + }; + + this._hideViews = function () { + //var controls = [dp_day, dp_week, dp_month]; + for (var i = 0; i < this._views.length; i++) { + this._views[i]._hide(); + } + }; + + Object.defineProperty(this, "active", { + get: function() { + return This._active; + } + }); + + this.events = {}; + + this.events.load = function(url, success, error) { + if (This._active && This._active.control) { + This._active.control.events.load(url, success, error); + } + else { + throw "DayPilot.Switcher.events.load(): Active view not found"; + } + }; + + this._previousArgs = null; + + this._init = function() { + if (!options) { + return; + } + + for (var name in options) { + if (name === "triggers") { + var triggers = options.triggers || []; + triggers.forEach(function(item) { + This.addTrigger(item.id, item.view); + }); + } + else if (name === "navigator") { + This.addNavigator(options.navigator); + } + else { + This[name] = options[name]; + } + } + + }; + + this._init(); + + function navigate(start, end, day) { + var args = {}; + args.start = start; + args.end = end; + args.day = day; + args.target = This._active.control; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + var previous = This._previousArgs; + if (previous) { + if (previous.start === args.start && previous.end === args.end && previous.day === args.day && previous.target === args.target) { + return; // duplicate, no change + } + } + + This._previousArgs = args; + + if (typeof This.onChange === "function") { + This.onChange(args); + if (args.preventDefault.value) { + return; + } + } + + // backwards compatibility + if (typeof This.onTimeRangeSelect === "function") { + This.onTimeRangeSelect(args); + if (args.preventDefault.value) { + return; + } + } + + This._active._sendNavigate(This._day); + + if (typeof This.onChanged === "function") { + This.onChanged(args); + } + + if (typeof This.onTimeRangeSelected === "function") { + This.onTimeRangeSelected(args); + } + + } + + }; + + // DayPilot.Date START + + DayPilot.Duration = function(ticks) { + var d = this; + + var day = 1000*60*60*24.0; + var hour = 1000*60*60.0; + var minute = 1000*60.0; + var second = 1000.0; + + if (arguments.length === 2) { + var start = arguments[0]; + var end = arguments[1]; + + if (!(start instanceof DayPilot.Date) && (typeof start !== "string")) { + throw "DayPilot.Duration(): Invalid start argument, DayPilot.Date expected"; + } + if (!(end instanceof DayPilot.Date) && (typeof end !== "string")) { + throw "DayPilot.Duration(): Invalid end argument, DayPilot.Date expected"; + } + if (typeof start === "string") { + start = new DayPilot.Date(start); + } + if (typeof end === "string") { + end = new DayPilot.Date(end); + } + ticks = end.getTime() - start.getTime(); + } + + this.ticks = ticks; + + // caching, allows direct comparison + if (DayPilot.Date.Cache.DurationCtor["" + ticks]) { + return DayPilot.Date.Cache.DurationCtor["" + ticks]; + } + DayPilot.Date.Cache.DurationCtor["" + ticks] = this; + + this.toString = function(pattern) { + if (!pattern) { + return d.days() + "." + d.hours() + ":" + d.minutes() + ":" + d.seconds() + "." + d.milliseconds(); + } + + var minutes = d.minutes(); + minutes = (minutes < 10 ? "0" : "") + minutes; + + // dumb replacement + var result = pattern; + result = result.replace("mm", minutes); + result = result.replace("m", d.minutes()); + result = result.replace("H", d.hours()); + result = result.replace("h", d.hours()); + result = result.replace("d", d.days()); + result = result.replace("s", d.seconds()); + return result; + }; + + this.totalHours = function() { + return d.ticks / hour; + }; + + this.totalDays = function() { + return d.ticks / day; + }; + + this.totalMinutes = function() { + return d.ticks / minute; + }; + + this.totalSeconds = function() { + return d.ticks / second; + }; + + this.days = function() { + return Math.floor(d.totalDays()); + }; + + this.hours = function() { + var hourPartTicks = d.ticks - d.days()*day; + return Math.floor(hourPartTicks/hour); + }; + + this.minutes = function() { + var minutePartTicks = d.ticks - Math.floor(d.totalHours()) * hour; + return Math.floor(minutePartTicks/minute); + }; + + this.seconds = function() { + var secondPartTicks = d.ticks - Math.floor(d.totalMinutes()) * minute; + return Math.floor(secondPartTicks/second); + }; + + this.milliseconds = function() { + return d.ticks % second; + }; + + }; + + DayPilot.Duration.weeks = function(i) { + return new DayPilot.Duration(i * 1000*60*60*24*7); + }; + + DayPilot.Duration.days = function(i) { + return new DayPilot.Duration(i * 1000*60*60*24); + }; + + DayPilot.Duration.hours = function(i) { + return new DayPilot.Duration(i * 1000*60*60); + }; + + DayPilot.Duration.minutes = function(i) { + return new DayPilot.Duration(i * 1000*60); + }; + + DayPilot.Duration.seconds = function(i) { + return new DayPilot.Duration(i * 1000); + }; + + // alias to DayPilot.Duration + // disabled, doesn't work with caching + DayPilot.TimeSpan = function() { + + throw "Please use DayPilot.Duration class instead of DayPilot.TimeSpan."; + // DayPilot.Duration.apply(this, arguments); + }; + try { + DayPilot.TimeSpan.prototype = Object.create(DayPilot.Duration.prototype); // make instanceof work + } + catch (e) {} // doesn't work in IE8 + + // DayPilot.TimeSpan.prototype.constructor = DayPilot.TimeSpan; // not necessary, it's an alias, not an inherited class + + /* Date utils */ + + // DayPilot.Date class + /* Constructor signatures: + + -- new DayPilot.Date(date, isLocal) + date - JavaScript Date object + isLocal - true if the local time should be taken from date, otherwise GMT base is used + + -- new DayPilot.Date() - returns now, using local date + + -- new DayPilot.Date(string) + string - date in ISO 8601 format, e.g. 2009-01-01T00:00:00 + + */ + DayPilot.Date = function(date, readLocal) { + + if (date instanceof DayPilot.Date) { // it's already a DayPilot.Date object, return it (no copy) + return date; + } + + var ticks; + + if (DayPilot.Util.isNullOrUndefined(date)) { // date not set, use NOW + ticks = DayPilot.DateUtil.fromLocal().getTime(); + date = ticks; + } + + var cache = DayPilot.Date.Cache.Ctor; + if (cache[date]) { + DayPilot.Stats.cacheHitsCtor += 1; + return cache[date]; + } + + var isString = false; + + if (typeof date === "string") { + ticks = DayPilot.DateUtil.fromStringSortable(date, readLocal).getTime(); + isString = true; + } + else if (typeof date === "number") { + if (isNaN(date)) { + throw "Cannot create DayPilot.Date from NaN"; + } + ticks = date; + } + else if (date instanceof Date) { + if (readLocal) { + ticks = DayPilot.DateUtil.fromLocal(date).getTime(); + } + else { + ticks = date.getTime(); + } + } + else { + throw "Unrecognized parameter: use Date, number or string in ISO 8601 format"; + } + + var value = ticksToSortable(ticks); // normalized value + + if (cache[value]) { + return cache[value]; + } + + cache[value] = this; + cache[ticks] = this; + if (isString && value !== date && DayPilot.DateUtil.hasTzSpec(date)) { // don't cache strings with TZ spec + cache[date] = this; + } + + if (Object.defineProperty) { + Object.defineProperty(this, "ticks", { + get: function() { return ticks; } + }); + Object.defineProperty(this, "value", { + "value": value, + "writable": false, + "enumerable": true + }); + } + else { + this.ticks = ticks; + this.value = value; + } + + if (DayPilot.Date.Config.legacyShowD) { + this.d = new Date(ticks); + } + + DayPilot.Stats.dateObjects += 1; + }; + + DayPilot.Date.Config = {}; + DayPilot.Date.Config.legacyShowD = false; + + DayPilot.Date.Cache = {}; + DayPilot.Date.Cache.Parsing = {}; + DayPilot.Date.Cache.Ctor = {}; + DayPilot.Date.Cache.Ticks = {}; + DayPilot.Date.Cache.DurationCtor = {}; + + DayPilot.Date.Cache.clear = function() { + DayPilot.Date.Cache.Parsing = {}; + DayPilot.Date.Cache.Ctor = {}; + DayPilot.Date.Cache.Ticks = {}; + DayPilot.Date.Cache.DurationCtor = {}; + }; + + + DayPilot.Date.prototype.addDays = function(days) { + if (!days) { + return this; + } + return new DayPilot.Date(this.ticks + days * 24 * 60 * 60 * 1000); + }; + + DayPilot.Date.prototype.addHours = function(hours) { + if (!hours) { + return this; + } + return this.addTime(hours * 60 * 60 * 1000); + }; + + DayPilot.Date.prototype.addMilliseconds = function(millis) { + if (!millis) { + return this; + } + return this.addTime(millis); + }; + + DayPilot.Date.prototype.addMinutes = function(minutes) { + if (!minutes) { + return this; + } + return this.addTime(minutes * 60 * 1000); + }; + + DayPilot.Date.prototype.addMonths = function(months) { + if (!months) { + return this; + } + + var date = new Date(this.ticks); + + var y = date.getUTCFullYear(); + var m = date.getUTCMonth() + 1; + + if (months > 0) { + while (months >= 12) { + months -= 12; + y++; + } + if (months > 12 - m) { + y++; + m = months - (12 - m); + } + else { + m += months; + } + } + else { + while (months <= -12) { + months += 12; + y--; + } + if (m + months <= 0) { // + y--; + m = 12 + m + months; + } + else { + m = m + months; + } + } + + var d = new Date(date.getTime()); + d.setUTCDate(1); + d.setUTCFullYear(y); + d.setUTCMonth(m - 1); + + //var max = DayPilot.Date.daysInMonth(y, m); + var max = new DayPilot.Date(d).daysInMonth(); + d.setUTCDate(Math.min(max, date.getUTCDate())); + + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.addSeconds = function(seconds) { + if (!seconds) { + return this; + } + return this.addTime(seconds * 1000); + }; + + DayPilot.Date.prototype.addTime = function(ticks) { + if (!ticks) { + return this; + } + if (ticks instanceof DayPilot.Duration) { + ticks = ticks.ticks; + } + return new DayPilot.Date(this.ticks + ticks); + }; + + DayPilot.Date.prototype.addYears = function(years) { + var original = new Date(this.ticks); + var d = new Date(this.ticks); + var y = this.getYear() + years; + var m = this.getMonth(); + + d.setUTCDate(1); + d.setUTCFullYear(y); + d.setUTCMonth(m); + + //var max = DayPilot.Date.daysInMonth(y, m + 1); + var max = new DayPilot.Date(d).daysInMonth(); + d.setUTCDate(Math.min(max, original.getUTCDate())); + + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.dayOfWeek = function() { + return new Date(this.ticks).getUTCDay(); + }; + + DayPilot.Date.prototype.getDayOfWeek = function() { + return new Date(this.ticks).getUTCDay(); + }; + + DayPilot.Date.prototype.getDayOfYear = function() { + var first = this.firstDayOfYear(); + return DayPilot.DateUtil.daysDiff(first, this) + 1; + }; + + DayPilot.Date.prototype.daysInMonth = function() { + var date = new Date(this.ticks); + var month = date.getUTCMonth() + 1; + var year = date.getUTCFullYear(); + + + var m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + if (month !== 2) + return m[month - 1]; + if (year % 4 !== 0) + return m[1]; + if (year % 100 === 0 && year % 400 !== 0) + return m[1]; + return m[1] + 1; + + }; + + DayPilot.Date.prototype.daysInYear = function() { + var year = this.getYear(); + if (year % 4 !== 0) { + return 365; + } + if (year % 100 === 0 && year % 400 !== 0) { + return 365; + } + return 366; + }; + + DayPilot.Date.prototype.dayOfYear = function() { + return Math.ceil((this.getDatePart().getTime() - this.firstDayOfYear().getTime()) / 86400000) + 1; + }; + + // not required, direct comparison can be used + DayPilot.Date.prototype.equals = function(another) { + if (another === null) { + return false; + } + if (another instanceof DayPilot.Date) { + return this === another; + } + else { + throw "The parameter must be a DayPilot.Date object (DayPilot.Date.equals())"; + } + }; + + DayPilot.Date.prototype.firstDayOfMonth = function() { + //var utc = DayPilot.Date.firstDayOfMonth(this.getYear(), this.getMonth() + 1); + //return new DayPilot.Date(utc); + + var d = new Date(); + d.setUTCFullYear(this.getYear(), this.getMonth(), 1); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return new DayPilot.Date(d); + + }; + + DayPilot.Date.prototype.firstDayOfYear = function() { + var year = this.getYear(); + var d = new Date(); + d.setUTCFullYear(year, 0, 1); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.firstDayOfWeek = function(weekStarts) { + var d = this; + if (weekStarts instanceof DayPilot.Locale) { + weekStarts = weekStarts.weekStarts; + } + else if (typeof weekStarts === "string" && DayPilot.Locale.find(weekStarts)) { + var locale = DayPilot.Locale.find(weekStarts); + weekStarts = locale.weekStarts; + } + else { + weekStarts = weekStarts || 0; + } + + var day = d.dayOfWeek(); + while (day !== weekStarts) { + d = d.addDays(-1); + day = d.dayOfWeek(); + } + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.getDay = function() { + return new Date(this.ticks).getUTCDate(); + }; + + DayPilot.Date.prototype.getDatePart = function() { + var d = new Date(this.ticks); + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.getYear = function() { + return new Date(this.ticks).getUTCFullYear(); + }; + + DayPilot.Date.prototype.getHours = function() { + return new Date(this.ticks).getUTCHours(); + }; + + DayPilot.Date.prototype.getMilliseconds = function() { + return new Date(this.ticks).getUTCMilliseconds(); + }; + + DayPilot.Date.prototype.getMinutes = function() { + return new Date(this.ticks).getUTCMinutes(); + }; + + DayPilot.Date.prototype.getMonth = function() { + return new Date(this.ticks).getUTCMonth(); + }; + + DayPilot.Date.prototype.getSeconds = function() { + return new Date(this.ticks).getUTCSeconds(); + }; + + DayPilot.Date.prototype.getTotalTicks = function() { + return this.getTime(); + }; + + // undocumented + DayPilot.Date.prototype.getTime = function() { + return this.ticks; + }; + + DayPilot.Date.prototype.getTimePart = function() { + var datePart = this.getDatePart(); + return DayPilot.DateUtil.diff(this, datePart); + }; + + DayPilot.Date.prototype.lastDayOfMonth = function() { + //var utc = DayPilot.Date.lastDayOfMonth(this.getYear(), this.getMonth() + 1); + //return new DayPilot.Date(utc); + var d = new Date(this.firstDayOfMonth().getTime()); + var length = this.daysInMonth(); + d.setUTCDate(length); + return new DayPilot.Date(d); + }; + + DayPilot.Date.prototype.weekNumber = function() { + var first = this.firstDayOfYear(); + var days = (this.getTime() - first.getTime()) / 86400000; + return Math.ceil((days + first.dayOfWeek() + 1) / 7); + }; + + // ISO 8601 + DayPilot.Date.prototype.weekNumberISO = function() { + var thursdayFlag = false; + var dayOfYear = this.dayOfYear(); + + var startWeekDayOfYear = this.firstDayOfYear().dayOfWeek(); + var endWeekDayOfYear = this.firstDayOfYear().addYears(1).addDays(-1).dayOfWeek(); + //int startWeekDayOfYear = new DateTime(date.getYear(), 1, 1).getDayOfWeekOrdinal(); + //int endWeekDayOfYear = new DateTime(date.getYear(), 12, 31).getDayOfWeekOrdinal(); + + if (startWeekDayOfYear === 0) { + startWeekDayOfYear = 7; + } + if (endWeekDayOfYear === 0) { + endWeekDayOfYear = 7; + } + + var daysInFirstWeek = 8 - (startWeekDayOfYear); + + if (startWeekDayOfYear === 4 || endWeekDayOfYear === 4) { + thursdayFlag = true; + } + + var fullWeeks = Math.ceil((dayOfYear - (daysInFirstWeek)) / 7.0); + + var weekNumber = fullWeeks; + + if (daysInFirstWeek >= 4) { + weekNumber = weekNumber + 1; + } + + if (weekNumber > 52 && !thursdayFlag) { + weekNumber = 1; + } + + if (weekNumber === 0) { + weekNumber = this.firstDayOfYear().addDays(-1).weekNumberISO(); //weekNrISO8601(new DateTime(date.getYear() - 1, 12, 31)); + } + + return weekNumber; + + }; + + DayPilot.Date.prototype.toDateLocal = function() { + var date = new Date(this.ticks); + + var d = new Date(); + d.setFullYear(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); + d.setHours(date.getUTCHours()); + d.setMinutes(date.getUTCMinutes()); + d.setSeconds(date.getUTCSeconds()); + d.setMilliseconds(date.getUTCMilliseconds()); + return d; + + }; + + DayPilot.Date.prototype.toDate = function() { + return new Date(this.ticks); + }; + + DayPilot.Date.prototype.toJSON = function() { + return this.value; + }; + + // formatting and languages needed here + DayPilot.Date.prototype.toString = function(pattern, locale) { + if (!pattern) { + return this.toStringSortable(); + } + return new Pattern(pattern, locale).print(this); + }; + + DayPilot.Date.prototype.toStringSortable = function() { + return ticksToSortable(this.ticks); + }; + + function ticksToSortable(ticks) { + + var cache = DayPilot.Date.Cache.Ticks; + if (cache[ticks]) { + DayPilot.Stats.cacheHitsTicks += 1; + return cache[ticks]; + } + + var d = new Date(ticks); + + var millisecond; + var ms = d.getUTCMilliseconds(); + + if (ms === 0) { + millisecond = ""; + } + else if (ms < 10) { + millisecond = ".00" + ms; + } + else if (ms < 100) { + millisecond = ".0" + ms; + } + else { + millisecond = "." + ms + } + + var second = d.getUTCSeconds(); + if (second < 10) + second = "0" + second; + var minute = d.getUTCMinutes(); + if (minute < 10) + minute = "0" + minute; + var hour = d.getUTCHours(); + if (hour < 10) + hour = "0" + hour; + var day = d.getUTCDate(); + if (day < 10) + day = "0" + day; + var month = d.getUTCMonth() + 1; + if (month < 10) + month = "0" + month; + var year = d.getUTCFullYear(); + + if (year <= 0) { + throw "The minimum year supported is 1."; + } + if (year < 10) { + year = "000" + year; + } + else if (year < 100) { + year = "00" + year; + } + else if (year < 1000) { + year = "0" + year; + } + + var result = year + "-" + month + "-" + day + 'T' + hour + ":" + minute + ":" + second + millisecond; + cache[ticks] = result; + return result; + } + + /* static functions, return DayPilot.Date object */ + + // returns null if parsing was not successful + DayPilot.Date.parse = function(str, pattern, locale) { + var p = new Pattern(pattern, locale); + return p.parse(str); + }; + + var todayCount = 0; + + DayPilot.Date.today = function() { + //return new DayPilot.Date().getDatePart(); + return new DayPilot.Date(DayPilot.DateUtil.localToday(), true); + }; + + DayPilot.Date.now = function() { + return new DayPilot.Date(); + }; + + DayPilot.Date.fromYearMonthDay = function(year, month, day) { + month = month || 1; + day = day || 1; + + var d = new Date(0); + d.setUTCFullYear(year); + d.setUTCMonth(month - 1); + d.setUTCDate(day); + return new DayPilot.Date(d); + }; + + DayPilot.DateUtil = {}; + + /* internal functions, all operate with GMT base of the date object + (except of DayPilot.DateUtil.fromLocal()) */ + + DayPilot.DateUtil.fromStringSortable = function(string, readLocal) { + /* + Supported formats: + 2015-01-01 + 2015-01-01T00:00:00 + 2015-01-01T00:00:00.000 + 2015-01-01T00:00:00Z + 2015-01-01T00:00:00.000Z + 2015-01-01T00:00:00+01:00 + 2015-01-01T00:00:00.000+01:00 + + */ + + if (!string) { + throw "Can't create DayPilot.Date from an empty string"; + } + + var len = string.length; + var date = len === 10; + var datetime = len === 19; + var long = len > 19; + + if (!date && !datetime && !long) { + throw "Invalid string format (use '2010-01-01' or '2010-01-01T00:00:00'): " + string; + } + + if (DayPilot.Date.Cache.Parsing[string] && !readLocal) { + DayPilot.Stats.cacheHitsParsing += 1; + return DayPilot.Date.Cache.Parsing[string]; + } + + var year = string.substring(0, 4); + var month = string.substring(5, 7); + var day = string.substring(8, 10); + + var d = new Date(0); + d.setUTCFullYear(year, month - 1, day); + + if (date) { + /* + d.setUTCHours(0); + d.setUTCMinutes(0); + d.setUTCSeconds(0); + d.setUTCMilliseconds(0); + */ + //result = d; + DayPilot.Date.Cache.Parsing[string] = d; + return d; + } + + var hours = string.substring(11, 13); + var minutes = string.substring(14, 16); + var seconds = string.substring(17, 19); + + d.setUTCHours(hours); + d.setUTCMinutes(minutes); + d.setUTCSeconds(seconds); + //d.setUTCMilliseconds(0); + //result = d; + + if (datetime) { + DayPilot.Date.Cache.Parsing[string] = d; + return d; + } + + var tzdir = string[19]; + + var tzoffset = 0; + + if (tzdir === ".") { + var ms = parseInt(string.substring(20, 23)); /// .000 + d.setUTCMilliseconds(ms); + tzoffset = DayPilot.DateUtil.getTzOffsetMinutes(string.substring(23)); + } + else { + tzoffset = DayPilot.DateUtil.getTzOffsetMinutes(string.substring(19)); + } + + var dd = new DayPilot.Date(d); + if (!readLocal) { + dd = dd.addMinutes(-tzoffset); + } + + d = dd.toDate(); // get UTC base + + DayPilot.Date.Cache.Parsing[string] = d; + return d; + }; + + DayPilot.DateUtil.getTzOffsetMinutes = function(string) { + if (DayPilot.Util.isNullOrUndefined(string) || string === "") { + return 0; + } + if (string === "Z") { + return 0; + } + + var tzdir = string[0]; + + var tzhours = parseInt(string.substring(1, 3)); + var tzminutes = parseInt(string.substring(4)); + var tzoffset = tzhours * 60 + tzminutes; + + if (tzdir === "-") { + return -tzoffset; + } + else if (tzdir === "+") { + return tzoffset; + } + else { + throw "Invalid timezone spec: " + string; + } + }; + + DayPilot.DateUtil.hasTzSpec = function(string) { + if (string.indexOf("+")) { + return true; + } + if (string.indexOf("-")) { + return true; + } + return false; + }; + + + // rename candidate: diffDays + DayPilot.DateUtil.daysDiff = function(first, second) { + (first && second) || (function() { throw "two parameters required"; })(); + + first = new DayPilot.Date(first); + second = new DayPilot.Date(second); + + if (first.getTime() > second.getTime()) { + return null; + } + + var i = 0; + var fDay = first.getDatePart(); + var sDay = second.getDatePart(); + + while (fDay < sDay) { + fDay = fDay.addDays(1); + i++; + } + + return i; + }; + + DayPilot.DateUtil.daysSpan = function(first, second) { + (first && second) || (function() { throw "two parameters required"; })(); + + first = new DayPilot.Date(first); + second = new DayPilot.Date(second); + + if (first.getTime() === second.getTime()) { + return 0; + } + + var diff = DayPilot.DateUtil.daysDiff(first, second); + + if (second.getTime() == second.getDatePart().getTime()) { + diff--; + } + + return diff; + }; + + DayPilot.DateUtil.diff = function(first, second) { // = first - second + if (!(first && second && first.getTime && second.getTime)) { + throw "Both compared objects must be Date objects (DayPilot.Date.diff)."; + } + + return first.getTime() - second.getTime(); + }; + + // returns Date object + DayPilot.DateUtil.fromLocal = function(localDate) { + if (!localDate) { + localDate = new Date(); + } + + var d = new Date(); + d.setUTCFullYear(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()); + d.setUTCHours(localDate.getHours()); + d.setUTCMinutes(localDate.getMinutes()); + d.setUTCSeconds(localDate.getSeconds()); + d.setUTCMilliseconds(localDate.getMilliseconds()); + return d; + }; + + DayPilot.DateUtil.localToday = function() { + var d = new Date(); + d.setHours(0); + d.setMinutes(0); + d.setSeconds(0); + d.setMilliseconds(0); + return d; + }; + + // rename candidate: toHourString + DayPilot.DateUtil.hours = function(date, use12) { + + var minute = date.getUTCMinutes(); + if (minute < 10) + minute = "0" + minute; + + + var hour = date.getUTCHours(); + //if (hour < 10) hour = "0" + hour; + + if (use12) { + var am = hour < 12; + var hour = hour % 12; + if (hour === 0) { + hour = 12; + } + var suffix = am ? "AM" : "PM"; + return hour + ':' + minute + ' ' + suffix; + } + else { + return hour + ':' + minute; + } + }; + + DayPilot.DateUtil.max = function(first, second) { + if (first.getTime() > second.getTime()) { + return first; + } + else { + return second; + } + }; + + DayPilot.DateUtil.min = function(first, second) { + if (first.getTime() < second.getTime()) { + return first; + } + else { + return second; + } + }; + + var Pattern = function(pattern, locale) { + if (typeof locale === "string") { + locale = DayPilot.Locale.find(locale); + } + var locale = locale || DayPilot.Locale.US; + var all = [ + {"seq": "yyyy", "expr": "[0-9]{4,4\u007d", "str": function(d) { + return d.getYear(); + }}, + {"seq": "yy", "expr": "[0-9]{2,2\u007d", "str": function(d) { + return d.getYear() % 100; + }}, + {"seq": "mm", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getMinutes(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "m", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getMinutes(); + return r; + }}, + {"seq": "HH", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getHours(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "H", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getHours(); + return r; + }}, + {"seq": "hh", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var hour = d.getHours(); + var hour = hour % 12; + if (hour === 0) { + hour = 12; + } + var r = hour; + return r < 10 ? "0" + r : r; + }}, + {"seq": "h", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var hour = d.getHours(); + var hour = hour % 12; + if (hour === 0) { + hour = 12; + } + return hour; + }}, + {"seq": "ss", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getSeconds(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "s", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getSeconds(); + return r; + }}, + {"seq": "MMMM", "expr": "[^\\s0-9]*", "str": function(d) { + var r = locale.monthNames[d.getMonth()]; + return r; + }, "transform" : function(input) { + var index = DayPilot.indexOf(locale.monthNames, input, equalsIgnoreCase); + if (index < 0) { + return null; + } + return index + 1; + }}, + {"seq": "MMM", "expr": "[^\\s0-9]*", "str": function(d) { // \u0073 = 's' + var r = locale.monthNamesShort[d.getMonth()]; + return r; + }, "transform" : function(input) { + var index = DayPilot.indexOf(locale.monthNamesShort, input, equalsIgnoreCase); + if (index < 0) { + return null; + } + return index + 1; + }}, + {"seq": "MM", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getMonth() + 1; + return r < 10 ? "0" + r : r; + }}, + {"seq": "M", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getMonth() + 1; + return r; + }}, + {"seq": "dddd", "expr": "[^\\s0-9]*", "str": function(d) { + var r = locale.dayNames[d.getDayOfWeek()]; + return r; + }}, + {"seq": "ddd", "expr": "[^\\s0-9]*", "str": function(d) { + var r = locale.dayNamesShort[d.getDayOfWeek()]; + return r; + }}, + {"seq": "dd", "expr": "[0-9]{2,2\u007d", "str": function(d) { + var r = d.getDay(); + return r < 10 ? "0" + r : r; + }}, + {"seq": "%d", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getDay(); + return r; + }}, + {"seq": "d", "expr": "[0-9]{1,2\u007d", "str": function(d) { + var r = d.getDay(); + return r; + }}, + {"seq": "tt", "expr": "(AM|PM|am|pm)", "str": function(d) { + var hour = d.getHours(); + var am = hour < 12; + return am ? "AM" : "PM"; + }, "transform" : function(input) { + return input.toUpperCase(); + }}, + ]; + + var escapeRegex = function(text) { + return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + }; + + this.init = function() { + this.year = this.findSequence("yyyy"); + this.month = this.findSequence("MMMM") || this.findSequence("MMM") || this.findSequence("MM") || this.findSequence("M"); + this.day = this.findSequence("dd") || this.findSequence("d"); + + this.hours = this.findSequence("HH") || this.findSequence("H"); + this.minutes = this.findSequence("mm") || this.findSequence("m"); + this.seconds = this.findSequence("ss") || this.findSequence("s"); + + this.ampm = this.findSequence("tt"); + this.hours12 = this.findSequence("hh") || this.findSequence("h"); + + /*if (this.hours && this.ampm) { + throw new DayPilot.Exception("'HH' and 'H' specifiers cannot be used in combination with 'tt'. Use 12-hour clock specifiers: 'hh' or 'h'."); + }*/ + }; + + this.findSequence = function(seq) { + + function defaultTransform(value) { + return parseInt(value); + } + + var index = pattern.indexOf(seq); + if (index === -1) { + return null; + } + return { + "findValue": function(input) { + var prepared = escapeRegex(pattern); + var transform = null; + for (var i = 0; i < all.length; i++) { + var len = all[i].length; + var pick = (seq === all[i].seq); + //var expr = ""; + var expr = all[i].expr; + if (pick) { + expr = "(" + expr + ")"; + transform = all[i].transform; + } + prepared = prepared.replace(all[i].seq, expr); + } + + prepared = "^" + prepared + "$"; + + try { + var r = new RegExp(prepared); + var array = r.exec(input); + if (!array) { + return null; + } + transform = transform || defaultTransform; // parseInt is the default transform/parse function + return transform(array[1]); + } + catch (e) { + throw "unable to create regex from: " + prepared; + } + } + }; + }; + + this.print = function(date) { + // always recompiles the pattern + + var find = function(t) { + for (var i = 0; i < all.length; i++) { + if (all[i] && all[i].seq === t) { + return all[i]; + } + } + return null; + }; + + var eos = pattern.length <= 0; + var pos = 0; + var components = []; + + while (!eos) { + var rem = pattern.substring(pos); + var matches = /%?(.)\1*/.exec(rem); // matches a sequence of identical characters, with an optional '%' preceding char + if (matches && matches.length > 0) { + var match = matches[0]; + var q = find(match); + if (q) { + components.push(q); + } + else { + components.push(match); + } + pos += match.length; + eos = pattern.length <= pos; + } + else { + eos = true; + } + } + + // resolve placeholders + for (var i = 0; i < components.length; i++) { + var c = components[i]; + if (typeof c !== 'string') { + components[i] = c.str(date); + } + } + + return components.join(""); + }; + + + + this.parse = function(input) { + + var year = this.year.findValue(input); + if (!year) { + return null; // unparseable + } + + var month = this.month.findValue(input); + if (DayPilot.Util.isNullOrUndefined(month)) { + return null; + } + if (month > 12 || month < 1) { + return null; + } + var day = this.day.findValue(input); + + var daysInMonth = DayPilot.Date.fromYearMonthDay(year, month).daysInMonth(); + if (day < 1 || day > daysInMonth) { + return null; + } + + var hours = this.hours ? this.hours.findValue(input) : 0; + var minutes = this.minutes ? this.minutes.findValue(input) : 0; + var seconds = this.seconds ? this.seconds.findValue(input) : 0; + + var ampm = this.ampm ? this.ampm.findValue(input): null; + + if (this.ampm && this.hours12) { + + var hours12 = this.hours12.findValue(input); + + if (hours12 < 1 || hours12 > 12) { + return null; + } + + if (ampm === "PM") { + if (hours12 === 12) { + hours = 12; + } + else { + hours = hours12 + 12; + } + } + else { + if (hours12 === 12) { + hours = 0; + } + else { + hours = hours12; + } + } + + } + + if (hours < 0 || hours > 23) { + return null; + } + + if (minutes < 0 || minutes > 59) { + return null; + } + + if (seconds < 0 || seconds > 59) { + return null; + } + + var d = new Date(); + d.setUTCFullYear(year, month - 1, day); + d.setUTCHours(hours); + d.setUTCMinutes(minutes); + d.setUTCSeconds(seconds); + d.setUTCMilliseconds(0); + + return new DayPilot.Date(d); + }; + + this.init(); + + }; + + function equalsIgnoreCase(str1, str2) { + if (DayPilot.Util.isNullOrUndefined(str1)) { + return false; + } + if (DayPilot.Util.isNullOrUndefined(str2)) { + return false; + } + return str1.toLocaleLowerCase() === str2.toLocaleLowerCase(); + } + + // DayPilot.Date END + + + DayPilot.ColorUtil = {}; + + function toHex(dec) { + dec = Math.min(dec, 255); + dec = Math.max(dec, 0); + var str = dec.toString(16); + return (dec < 16) ? "0" + str : str; + } + + DayPilot.ColorUtil.hexToRgb = function(hex) { + if (!/^#[0-9a-f]{6}$/i.test(hex)) { + throw new DayPilot.Exception("Invalid color, only full hex color string accepted, eg. '#ffaaff'."); + } + hex = hex.replace("#", ""); + return { + r: parseInt(hex.substring(0, 2), 16), + g: parseInt(hex.substring(2, 4), 16), + b: parseInt(hex.substring(4, 6), 16), + }; + }; + + DayPilot.ColorUtil.rgbToHex = function(rgb) { + return "#" + toHex(rgb.r) + toHex(rgb.g) + toHex(rgb.b); + }; + + // pt in 255 base + DayPilot.ColorUtil.adjustLuminance = function(rgb, pt) { + return { + r: rgb.r + pt, + g: rgb.g + pt, + b: rgb.b + pt + }; + }; + + DayPilot.ColorUtil.darker = function(hexColor, steps) { + var src = DayPilot.ColorUtil.hexToRgb(hexColor); + steps = steps || 1; + var step = 17; // (0xbb - 0xaa = 17) + var pt = steps * step; + var target = DayPilot.ColorUtil.adjustLuminance(src, -pt); + return DayPilot.ColorUtil.rgbToHex(target); + }; + + DayPilot.ColorUtil.lighter = function(hexColor, steps) { + if (typeof steps !== "number") { + steps = 1; + } + return DayPilot.ColorUtil.darker(hexColor, -steps); + }; + + + DayPilot.ColorUtil.pl = function(hexColor) { + var rgb = DayPilot.ColorUtil.hexToRgb(hexColor); + var r = rgb.r / 255; + var g = rgb.g / 255; + var b = rgb.b / 255; + var pl = Math.sqrt(0.299*r*r + 0.587*g*g + 0.114*b*b); + return pl; + }; + + DayPilot.ColorUtil.contrasting = function(hexColor, light, dark) { + var pl = DayPilot.ColorUtil.pl(hexColor); + light = light || "#ffffff"; + dark = dark || "#000000"; + return pl > 0.5 ? dark : light; + }; + + + DayPilot.Event = function(data, calendar, part) { + var e = this; + this.calendar = calendar; + this.data = data ? data : {}; + this.part = part ? part : {}; + + // backwards compatibility, still accepts id in "value" + if (typeof this.data.id === 'undefined') { + this.data.id = this.data.value; + } + + var copy = {}; + var synced = ["id", "text", "start", "end", "resource"]; + + this.isEvent = true; + + // internal + this.temp = function() { + if (copy.dirty) { + return copy; + } + for (var i = 0; i < synced.length; i++) { + copy[synced[i]] = e.data[synced[i]]; + } + copy.dirty = true; + return copy; + + }; + + // internal + this.copy = function() { + var result = {}; + for (var i = 0; i < synced.length; i++) { + result[synced[i]] = e.data[synced[i]]; + } + return result; + }; + + this.commit = function() { + if (!copy.dirty) { + return; + } + + for (var i = 0; i < synced.length; i++) { + e.data[synced[i]] = copy[synced[i]]; + } + + copy.dirty = false; + }; + + this.dirty = function() { + return copy.dirty; + }; + + this.id = function(val) { + if (typeof val === 'undefined') { + return e.data.id; + } + else { + this.temp().id = val; + } + }; + // obsolete, use id() instead + this.value = function(val) { + if (typeof val === 'undefined') { + return e.id(); + } + else { + e.id(val); + } + }; + this.text = function(val) { + if (typeof val === 'undefined') { + return e.data.text; + } + else { + this.temp().text = val; + this.client.innerHTML(val); // update the HTML automatically + } + }; + this.start = function(val) { + if (typeof val === 'undefined') { + return new DayPilot.Date(e.data.start); + } + else { + this.temp().start = new DayPilot.Date(val); + } + }; + this.end = function(val) { + if (typeof val === 'undefined') { + return new DayPilot.Date(e.data.end); + } + else { + this.temp().end = new DayPilot.Date(val); + } + }; + this.resource = function(val) { + if (typeof val === 'undefined') { + return e.data.resource; + } + else { + this.temp().resource = val; + } + }; + this.partStart = function() { + return new DayPilot.Date(this.part.start); + }; + this.partEnd = function() { + return new DayPilot.Date(this.part.end); + }; + + this.tag = function(field) { + var values = e.data.tag; + if (!values) { + return null; + } + if (typeof field === 'undefined') { + return e.data.tag; + } + var fields = e.calendar.tagFields; + var index = -1; + for (var i = 0; i < fields.length; i++) { + if (field === fields[i]) + index = i; + } + if (index === -1) { + throw "Field name not found."; + } + //var tags = t.split('&'); + return values[index]; + }; + + this.client = {}; + this.client.innerHTML = function(val) { + if (typeof val === 'undefined') { + var data = e.cache || e.data; + var xssTextHtml = e.calendar && e.calendar.internal && e.calendar.internal.xssTextHtml; + if (xssTextHtml) { + return xssTextHtml(data.text, data.html); + } + return DayPilot.Util.escapeTextHtml(data.text, data.html); + + /* + if (e.cache && typeof e.cache.html !== "undefined") { + return e.cache.html; + } + if (typeof e.data.html !== "undefined") { + return e.data.html; + } + return e.data.text; + */ + } + else { + e.data.html = val; + } + }; + + this.client.html = this.client.innerHTML; + + this.client.header = function(val) { + if (typeof val === 'undefined') { + return e.data.header; + } + else { + e.data.header = val; + } + }; + + this.client.cssClass = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.cssClass !== "undefined") { + return e.cache.cssClass; + } + return e.data.cssClass; + } + else { + e.data.cssClass = val; + } + }; + this.client.toolTip = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.toolTip !== "undefined") { + return e.cache.toolTip; + } + return typeof e.data.toolTip !== 'undefined' ? e.data.toolTip : e.data.text; + } + else { + e.data.toolTip = val; + } + }; + + this.client.barVisible = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.barHidden !== "undefined") { + return !e.cache.barHidden; + } + return e.calendar.durationBarVisible && !e.data.barHidden; + } + else { + e.data.barHidden = !val; + } + }; + + this.client.backColor = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.backColor !== "undefined") { + return e.cache.backColor; + } + return typeof e.data.backColor !== "undefined" ? e.data.backColor : e.calendar.eventBackColor; + } + else { + e.data.backColor = val; + } + }; + + this.client.borderColor = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.borderColor !== "undefined") { + return e.cache.borderColor; + } + return typeof e.data.borderColor !== "undefined" ? e.data.borderColor : e.calendar.eventBorderColor; + } + else { + e.data.borderColor = val; + } + }; + + this.client.contextMenu = function(val) { + if (typeof val === 'undefined') { + if (e.oContextMenu) { + return e.oContextMenu; + } + var cm = e.cache ? e.cache.contextMenu : e.data.contextMenu; + } + else { + e.oContextMenu = val; + } + }; + + this.client.moveEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.moveDisabled !== "undefined") { + return !e.cache.moveDisabled; + } + + return e.calendar.eventMoveHandling !== 'Disabled' && !e.data.moveDisabled; + } + else { + e.data.moveDisabled = !val; + } + }; + + this.client.resizeEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.resizeDisabled !== "undefined") { + return !e.cache.resizeDisabled; + } + return e.calendar.eventResizeHandling !== 'Disabled' && !e.data.resizeDisabled; + } + else { + e.data.resizeDisabled = !val; + } + }; + + this.client.clickEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.clickDisabled !== "undefined") { + return !e.cache.clickDisabled; + } + return e.calendar.eventClickHandling !== 'Disabled' && !e.data.clickDisabled; + } + else { + e.data.clickDisabled = !val; + } + }; + + this.client.rightClickEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.rightClickDisabled !== "undefined") { + return !e.cache.rightClickDisabled; + } + return e.calendar.eventRightClickHandling !== 'Disabled' && !e.data.rightClickDisabled; + } + else { + e.data.rightClickDisabled = !val; + } + }; + + this.client.deleteEnabled = function(val) { + if (typeof val === 'undefined') { + if (e.cache && typeof e.cache.deleteDisabled !== "undefined") { + return !e.cache.deleteDisabled; + } + return e.calendar.eventDeleteHandling !== 'Disabled' && !e.data.deleteDisabled; + } + else { + e.data.deleteDisabled = !val; + } + }; + + this.toJSON = function(key) { + var json = {}; + json.value = this.id(); // still sending it with the old name + json.id = this.id(); + json.text = this.text(); + json.start = this.start(); + json.end = this.end(); + json.tag = {}; + + if (e.calendar && e.calendar.tagFields) { + var fields = e.calendar.tagFields; + for (var i = 0; i < fields.length; i++) { + json.tag[fields[i]] = this.tag(fields[i]); + } + } + + return json; + }; + }; + +})(); + +/* JSON */ +// thanks to http://www.json.org/js.html + + +// declares DayPilot.JSON.stringify() +DayPilot.JSON = {}; + +(function () { + function f(n) { + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON2 !== 'function') { + + Date.prototype.toJSON2 = function (key) { + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + ''; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + function quote(string) { + escapeable.lastIndex = 0; + return escapeable.test(string) ? + '"' + string.replace(escapeable, function (a) { + var c = meta[a]; + if (typeof c === 'string') { + return c; + } + return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + function str(key, holder) { + var i, + k, + v, + length, + mind = gap, + partial, + value = holder[key]; + if (value && typeof value === 'object' && typeof value.toJSON2 === 'function') { + value = value.toJSON2(key); + } + else if (value && typeof value === 'object' && typeof value.toJSON === 'function' && !value.ignoreToJSON) { + value = value.toJSON(key); + } + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + switch (typeof value) { + case 'string': + return quote(value); + case 'number': + return isFinite(value) ? String(value) : 'null'; + case 'boolean': + case 'null': + return String(value); + case 'object': + if (!value) { + return 'null'; + } + gap += indent; + partial = []; + if (typeof value.length === 'number' && + !value.propertyIsEnumerable('length')) { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + v = (partial.length === 0) ? '{\u007D' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '\u007D' : '{' + partial.join(',') + '\u007D'; + gap = mind; + return v; + } + } + + if (typeof DayPilot.JSON.stringify !== 'function') { + DayPilot.JSON.stringify = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } else if (typeof space === 'string') { + indent = space; + } + rep = replacer; + if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + return str('', {'': value}); + }; + } + +})(); diff --git a/static/src/js/src/daypilot-datepicker.src.js b/static/src/js/src/daypilot-datepicker.src.js new file mode 100644 index 0000000..941009a --- /dev/null +++ b/static/src/js/src/daypilot-datepicker.src.js @@ -0,0 +1,284 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +(function() { + + if (typeof DayPilot.DatePicker !== 'undefined' && DayPilot.DatePicker.close) { + return; + } + + DayPilot.DatePicker = function(properties) { + this.v = '2024.3.539-lite'; + var navigatorId = "navigator_" + new Date().getTime(); + var This = this; + + this.onShow = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + // this.dateFormat = null; + + this.prepare = function() { + this.locale = "en-us"; + this.target = null; + this.targetAlignment = "left"; + this.resetTarget = true; + this.pattern = this._resolved.locale().datePattern; // "M/d/yyyy" + this.theme = "navigator_default"; + this.patterns = []; + this.zIndex = null; + + // load settings + if (properties) { + for (var name in properties) { + this[name] = properties[name]; + } + } + + }; + + this.init = function() { + + this.date = new DayPilot.Date(this.date); + + var value = this._readFromTarget(); + + if (this.resetTarget && !value) { + this._writeToTarget(this.date); + } + else if (!this.resetTarget) { + This.date = value; + } + + var target = this._element(); + if (target) { + target.addEventListener("input", function() { + This.date = This._readFromTarget(); + if (This.date) { + This.navigator.select(This.date, {dontNotify: true}); + } + }); + } + + document.addEventListener("mousedown", function() { + This.close(); + }); + + return this; + + }; + + this.close = function() { + if (!this._visible) { + return; + } + + this._visible = false; + + if (this.navigator) { + this.navigator.dispose(); + } + this.div.innerHTML = ''; + if (this.div && this.div.parentNode === document.body) { + document.body.removeChild(this.div); + } + }; + + this.setDate = function(date) { + this.date = new DayPilot.Date(date); + this._writeToTarget(this.date); + }; + + this._readFromTarget = function() { + // recognized targets: input (value), other DOM elements (innerHTML) + var element = this._element(); + + if (!element) { + return this.date; + } + + var value = null; + if (element.tagName === "INPUT") { + value = element.value; + } + else { + value = element.innerText; + } + + if (!value) { + return null; + } + + var date = DayPilot.Date.parse(value, This.pattern); + for (var i = 0; i < This.patterns.length; i++) { + if (date) { + return date; + } + date = DayPilot.Date.parse(value, This.patterns[i]); + } + + return date; + }; + + this._writeToTarget = function(date) { + var element = this._element(); + + if (!element) { + return; + } + + var value = date.toString(This.pattern, This.locale); + if (element.tagName === "INPUT") { + element.value = value; + } + else { + element.innerHTML = value; + } + + }; + + this._resolved = {}; + this._resolved.locale = function() { + return DayPilot.Locale.find(This.locale); + }; + + /* this._resolved.dateFormat = function() { + if (typeof This.dateFormat === "string") { + return This.dateFormat; + } + return This._resolved.locale().datePattern; + }*/ + + this._element = function() { + var id = this.target; + // accept DOM element or id (string) + var element = (id && id.nodeType && id.nodeType === 1 ) ? id : document.getElementById(id); + return element; + }; + + Object.defineProperty(this, "visible", { + get: function() { return This._visible; } + }); + + this.show = function() { + + if (this._visible) { + return; + } + + var element = this._element(); + var navigator = this.navigator; + + var navigator = new DayPilot.Navigator(navigatorId); + navigator.api = 2; + navigator.cssOnly = true; + navigator.theme = This.theme; + navigator.weekStarts = "Auto"; + navigator.locale = This.locale; + navigator.onTimeRangeSelected = function(args) { + This.date = args.start; + + var start = args.start.addTime(navigator._pickerTimePart); + var value = start.toString(This.pattern, This.locale); + + var args = {}; + args.start = start; + args.date = start; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof This.onTimeRangeSelect === 'function') { + This.onTimeRangeSelect(args); + if (args.preventDefault.value) { + return; + } + } + + This._writeToTarget(value); + This.close(); + + if (typeof This.onTimeRangeSelected === 'function') { + This.onTimeRangeSelected(args); + } + }; + + this.navigator = navigator; + + var position = DayPilot.abs(element); + var height = element.offsetHeight; + + var align = This.targetAlignment; + + var div = document.createElement("div"); + div.style.position = "absolute"; + + if (align === "left") { + div.style.left = position.x + "px"; + } + + + div.style.top = (position.y + height) + "px"; + if (This.zIndex) { + div.style.zIndex = This.zIndex; + } + + var nav = document.createElement("div"); + nav.id = navigatorId; + div.appendChild(nav); + + div.addEventListener("mousedown", function(ev) { + var ev = ev || window.event; + ev.cancelBubble = true; + ev.stopPropagation && ev.stopPropagation(); + }); + + document.body.appendChild(div); + + this.div = div; + + var selected = This._readFromTarget() || new DayPilot.Date().getDatePart(); + + navigator.startDate = selected; + navigator._pickerTimePart = selected.getTimePart(); + // navigator.selectionStart = selected.getDatePart(); + navigator.selectionDay = selected.getDatePart(); + navigator.init(); + + if (align === "right") { + var left = (position.x + element.offsetWidth - navigator.nav.top.offsetWidth); + div.style.left = left + "px"; + } + + this._visible = true; + if (this.onShow) { + this.onShow(); + } + }; + + this.prepare(); // prepare only called once, in the constructor + this.init(); + }; + +})(); diff --git a/static/src/js/src/daypilot-menu.src.js b/static/src/js/src/daypilot-menu.src.js new file mode 100644 index 0000000..e46d93c --- /dev/null +++ b/static/src/js/src/daypilot-menu.src.js @@ -0,0 +1,974 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function(DayPilot) { + 'use strict'; + + if (typeof DayPilot.Menu !== 'undefined' && DayPilot.Menu.def) { + return; + } + + var doNothing = function() {}; + + var DayPilotMenu = {}; + + DayPilotMenu.mouse = null; + DayPilotMenu.menu = null; + DayPilotMenu.handlersRegistered = false; + DayPilotMenu.hideTimeout = null; + DayPilotMenu.waitingSubmenu = null; + + DayPilot.Menu = function(items) { + var menu = this; + var initiatorAreaDiv = null; + + this.v = '2024.3.539-lite'; + this.zIndex = 120; // more than 10,001 used by ModalPopupExtender + //this.useShadow = true; + this.cssClassPrefix = "menu_default"; + this.cssOnly = true; + this.menuTitle = null; + this.showMenuTitle = false; + this.hideOnMouseOut = false; + this.hideAfter = 200; + this.theme = null; + + this.onShow = null; + + // hiding internal properties for angular + this._state = function() {}; + //this._state.ref = null; // ref object, used for position + + if (items && DayPilot.isArray(items)) { + this.items = items; + } + + // angular change detection + this.toJSON = function() { + return null; + }; + + this.show = function(e, options) { + options = options || {}; + + var value = null; + if (!e) { + value = null; + } + else if (typeof e.id === 'string' || typeof e.id === 'number') { + value = e.id; + } + else if (typeof e.id === 'function') { + value = e.id(); + } + else if (typeof e.value === 'function') { + value = e.value(); + } + + if (typeof(DayPilot.Bubble) !== 'undefined') { // hide any bubble if active + DayPilot.Bubble.hideActive(); + } + + if (!options.submenu) { + DayPilotMenu.menuClean(); + } + + // clear old data + this._state.submenu = null; + + if (DayPilotMenu.mouse === null) { // not possible to execute before mouse move (TODO) + return; + } + + if (!menu.cssOnly) { + menu.cssOnly = true; + } + + var source = null; + if (e && e.isRow && e.$.row.task) { + source = new DayPilot.Task(e.$.row.task, e.calendar); + source.menuType = "resource"; + } + else if (e && e.isEvent && e.data.task) { + source = new DayPilot.Task(e, e.calendar); + } + else { + source = e; + } + + if (typeof menu.onShow === "function") { + var args = {}; + args.source = source; + args.menu = menu; + args.preventDefault = function () { + args.preventDefault.value = true; + }; + menu.onShow(args); + if (args.preventDefault.value) { + return; + } + } + + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.top = "0px"; + div.style.left = "0px"; + div.style.display = 'none'; + div.style.overflow = 'hidden'; + div.style.zIndex = this.zIndex + 1; + div.className = this._applyCssClass('main'); + div.onclick = function(ev) { + ev.cancelBubble = true; + this.parentNode.removeChild(this); + }; + + if (this.hideOnMouseOut) { + div.onmousemove = function(ev) { + clearTimeout(DayPilotMenu.hideTimeout); + }; + div.onmouseleave = function(ev) { + menu.delayedHide({"hideParent": true}); + }; + } + + if (!this.items || this.items.length === 0) { + throw "No menu items defined."; + } + + if (this.showMenuTitle) { + var title = document.createElement("div"); + title.innerHTML = this.menuTitle; + title.className = this._applyCssClass("title"); + div.appendChild(title); + } + + for (var i = 0; i < this.items.length; i++) { + var mi = this.items[i]; + var item = document.createElement("div"); + DayPilot.Util.addClass(item, this._applyCssClass("item")); + if (mi.items) { + DayPilot.Util.addClass(item, this._applyCssClass("item_haschildren")); + DayPilot.Util.addClass(div, this._applyCssClass(("withchildren"))); + } + + if (typeof mi === 'undefined') { + continue; + } + + if (mi.hidden) { + continue; + } + + + if (mi.text === '-') { + var separator = document.createElement("div"); + separator.addEventListener("click", function(ev) { + ev.stopPropagation(); + }); + + item.appendChild(separator); + } + else { + var link = document.createElement("a"); + link.style.position = 'relative'; + link.style.display = "block"; + + if (mi.cssClass) { + DayPilot.Util.addClass(link, mi.cssClass); + } + + if (mi.disabled) { + DayPilot.Util.addClass(link, menu._applyCssClass("item_disabled")); + } + else { + if (mi.onclick || mi.onClick) { + link.item = mi; + link.onclick = (function(mi, link) { + return function (e) { + if (typeof mi.onClick === "function") { + var args = {}; + args.item = mi; + args.source = link.source; + args.originalEvent = e; + args.preventDefault = function () { + args.preventDefault.value = true; + }; + mi.onClick(args); + if (args.preventDefault.value) { + return; + } + } + if (mi.onclick) { + mi.onclick.call(link, e); + } + }; + })(mi, link); + + var assignTouchEnd = function(mi, link) { + return function(e) { + e.stopPropagation(); + e.preventDefault(); + + var cleanup = function() { + window.setTimeout(function() { + link.source.calendar.internal.touch.active = false; + }, 500); + }; + + if (typeof mi.onClick === "function") { + var args = {}; + args.item = mi; + args.source = link.source; + args.originalEvent = e; + args.preventDefault = function() { + args.preventDefault.value = true; + }; + mi.onClick(args); + if (args.preventDefault.value) { + cleanup(); + return; + } + } + + if (mi.onclick) { + mi.onclick.call(link, e); + } + + DayPilotMenu.menuClean(); + cleanup(); + }; + }; + + DayPilot.reNonPassive(link, "touchstart", function(ev) { + ev.stopPropagation(); + ev.preventDefault(); + + link.source.calendar.internal.touch.active = true; + }); + DayPilot.reNonPassive(link, "touchend", assignTouchEnd(mi, link)); + + // link.ontouchend = assignTouchEnd(mi, link); + } + + + if (mi.items && !mi.disabled) { + var assign = function(mi, link) { + return function(ev) { + ev.preventDefault(); + ev.stopPropagation(); + menu._showSubmenu(mi, link); + }; + }; + link.ontouchend = assign(mi, link); + } + + if (mi.onclick) { + doNothing(); + } + else if (mi.href) { + link.href = mi.href.replace(/\x7B0\x7D/gim, value); // for NavigateUrl actions, only for backwards compatibility + if (mi.target) { + link.setAttribute("target", mi.target); + } + } + else if (mi.command) { + var assign = function(mi, link) { + return function(e) { + var source = link.source; + var item = mi; + item.action = item.action ? item.action : 'CallBack'; + var cal = source.calendar || source.root; + + if (source instanceof DayPilot.Link) { + cal.internal.linkMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Selection) { + cal.internal.timeRangeMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Event) { + cal.internal.eventMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Selection) { + cal.internal.timeRangeMenuClick(item.command, source, item.action); + return; + } + else if (source instanceof DayPilot.Task) { + if (source.menuType === "resource") { + cal.internal.resourceHeaderMenuClick(item.command, link.menuSource, item.action); + } + else { + cal.internal.eventMenuClick(item.command, link.menuSource, item.action); + } + return; + } + else { + switch (source.menuType) { // TODO legacy, remove + case 'resource': + cal.internal.resourceHeaderMenuClick(item.command, source, item.action); + return; + case 'selection': // fully replaced + cal.internal.timeRangeMenuClick(item.command, source, item.action); + return; + default: // fully replaced + cal.internal.eventMenuClick(item.command, source, item.action); + return; + } + } + + e.preventDefault(); + }; + }; + link.onclick = assign(mi, link); + link.ontouchend = assign(mi, link); + } + + } + + + if (mi.items) { + link.addEventListener("click", function(ev) { + ev.stopPropagation(); + }); + } + + link.source = source; + link.menuSource = e; + + var span = document.createElement("span"); + span.className = menu._applyCssClass("item_text"); + span.innerHTML = DayPilot.Util.escapeTextHtml(mi.text, mi.html); + link.appendChild(span); + + if (mi.image) { + var image = document.createElement("img"); + image.src = mi.image; + image.style.position = 'absolute'; + image.style.top = '0px'; + image.style.left = '0px'; + + link.appendChild(image); + } + + if (mi.icon) { + var icon = document.createElement("span"); + icon.className = menu._applyCssClass("item_icon"); + + var iel = document.createElement("i"); + iel.className = mi.icon; + icon.appendChild(iel); + + link.appendChild(icon); + } + + if (mi.symbol) { + var ns = "http://www.w3.org/2000/svg"; + var svg = document.createElementNS(ns,"svg"); + svg.setAttribute("width", "100%"); + svg.setAttribute("height", "100%"); + var use = document.createElementNS(ns,"use"); + use.setAttribute("href", mi.symbol); + svg.appendChild(use); + + var svgWrap = document.createElement("span"); + svgWrap.className = menu._applyCssClass("item_symbol"); + svgWrap.style.position = "absolute"; + svgWrap.style.top = "0px"; + svgWrap.style.left = "0px"; + svgWrap.appendChild(svg); + + link.appendChild(svgWrap); + } + + var assignOnMouseOver = function(mi, link) { + return function() { + var source = link.source; + var item = mi; + + var ws = DayPilotMenu.waitingSubmenu; + if (ws) { + if (ws.parent === item) { + return; + } + else { + clearTimeout(ws.timeout); + DayPilotMenu.waitingSubmenu = null; + } + } + + if (mi.disabled) { + return; + } + + DayPilotMenu.waitingSubmenu = {}; + DayPilotMenu.waitingSubmenu.parent = item; + DayPilotMenu.waitingSubmenu.timeout = setTimeout(function() { + + DayPilotMenu.waitingSubmenu = null; + + menu._showSubmenu(item, link); + + }, 300); + }; + }; + + link.onmouseover = assignOnMouseOver(mi, link); + + item.appendChild(link); + } + + div.appendChild(item); + + } + + var delayedDismiss = function(e) { + window.setTimeout(function() { + DayPilotMenu.menuClean(); + DayPilot.MenuBar.deactivate(); + }, 100); + }; + + div.onclick = delayedDismiss; + div.ontouchend = delayedDismiss; + + div.onmousedown = function(e) { + e = e || window.event; + e.cancelBubble = true; + if (e.stopPropagation) + e.stopPropagation(); + }; + div.oncontextmenu = function() { + return false; + }; + + document.body.appendChild(div); + menu._state.visible = true; + menu._state.source = e; + + div.style.display = ''; + var height = div.offsetHeight; + var width = div.offsetWidth; + div.style.display = 'none'; + + // don't show the menu outside of the visible window + var windowHeight = document.documentElement.clientHeight; + // required for ipad with zoom instead of document.documentElement.clientWidth + var windowWidth = window.innerWidth; + + var windowMargin = (typeof options.windowMargin == "number") ? options.windowMargin : 5; + + (function showInitiator() { + var initiator = options.initiator; + // initiator = options.initiator; + if (!initiator) { + return; + } + var div = initiator.div; + var e = initiator.e; + var area = initiator.area; + + var v = area.visibility || area.v || "Visible"; + var a = initiator.a; + if (v !== "Visible") { + // make sure the source area is visible + a = DayPilot.Areas.createArea(div, e, area); + div.appendChild(a); + // will be used to remove it on hide + initiatorAreaDiv = a; + } + + if (a) { + var abs = DayPilot.abs(a); + options.x = abs.x; + options.y = abs.y + abs.h + 2; + } + + })(); + + + (function adjustPosition() { + + // don't show it exactly under the cursor + var x = (typeof options.x === "number") ? options.x : DayPilotMenu.mouse.x + 1; + var y = (typeof options.y === "number") ? options.y : DayPilotMenu.mouse.y + 1; + + var topOffset = document.body.scrollTop || document.documentElement.scrollTop; + var leftOffset = document.body.scrollLeft || document.documentElement.scrollLeft; + + if (y - topOffset > windowHeight - height && windowHeight !== 0) { + var offsetY = y - topOffset - (windowHeight - height) + windowMargin; + div.style.top = (y - offsetY) + 'px'; + } + else { + div.style.top = y + 'px'; + } + + if (options.align === "right") { + x -= width; + } + + if (x - leftOffset > windowWidth - width && windowWidth !== 0) { + var offsetX = x - leftOffset - (windowWidth - width) + windowMargin; + div.style.left = (x - offsetX) + 'px'; + } + else { + div.style.left = x + 'px'; + } +/* + if (DayPilotMenu.mouse.clientY > windowHeight - height && windowHeight !== 0) { + var offsetY = DayPilotMenu.mouse.clientY - (windowHeight - height) + 5; + div.style.top = (y - offsetY) + 'px'; + } + else { + div.style.top = y + 'px'; + } + + if (DayPilotMenu.mouse.clientX > windowWidth - width && windowWidth !== 0) { + var offsetX = DayPilotMenu.mouse.clientX - (windowWidth - width) + 5; + div.style.left = (x - offsetX) + 'px'; + } + else { + div.style.left = x + 'px'; + } +*/ + })(); + + if (options.parentLink) { + + var parent = options.parentLink; + + var verticalOffset = parseInt(new DayPilot.StyleReader(div).get("border-top-width")); + + var pos = DayPilot.abs(options.parentLink.parentNode); + var x = pos.x + parent.offsetWidth; + var y = pos.y - verticalOffset; + + if (x + width > windowWidth) { + x = Math.max(0, pos.x - width); + } + + var docScrollTop = document.body.scrollTop + document.documentElement.scrollTop; + if (y + height - docScrollTop > windowHeight) { + y = Math.max(0, windowHeight - height + docScrollTop); + } + + div.style.left = x + "px"; + div.style.top = y + "px"; + + } + div.style.display = ''; + + this.addShadow(div); + this._state.div = div; + + if (!options.submenu) { + DayPilot.Menu.active = this; + } + + //this._initiator = null; + + }; + + this._showSubmenu = function(item, link) { + var mi = item; + var source = link.source; + + if (menu._state.submenu && menu._state.submenu.item === item) { // already visible + return; + } + + if (menu._state.submenu && menu._state.submenu.item !== item) { // hide submenus of other items + DayPilot.Util.removeClass(menu._state.submenu.link.parentNode, menu._applyCssClass("item_haschildren_active")); + menu._state.submenu.menu.hide(); + menu._state.submenu = null; + } + + if (!item.items) { // no submenu for this item + return; + } + + var options = menu.cloneOptions(); + options.items = item.items; + + menu._state.submenu = {}; + menu._state.submenu.menu = new DayPilot.Menu(options); + menu._state.submenu.menu._parentMenu = menu; + menu._state.submenu.menu.show(source, {"submenu": true, "parentLink": link, "parentItem": mi}); + menu._state.submenu.item = item; + menu._state.submenu.link = link; + DayPilot.Util.addClass(link.parentNode, menu._applyCssClass("item_haschildren_active")); + + }; + + this._applyCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + var sep = (this.cssOnly ? "_" : ""); + if (prefix) { + return prefix + sep + part; + } + else { + return ""; + } + }; + + this.cloneOptions = function() { + return DayPilot.Util.copyProps(options, {}, ["cssClassPrefix", "theme", "hideAfter", "hideOnMouseOut", "zIndex"]); + }; + + this.hide = function(props) { + props = props || {}; + + if (this._state.submenu) { + this._state.submenu.menu.hide(); + } + + var ws = DayPilotMenu.waitingSubmenu; + if (ws) { + DayPilotMenu.waitingSubmenu = null; + clearTimeout(ws.timeout); + } + + this.removeShadow(); + if (this._state.div && this._state.div.parentNode === document.body) { + document.body.removeChild(this._state.div); + } + +/* + if (this._initiator) { + DayPilot.de(this._initiator); + this._initiator = null; + } +*/ + + if (initiatorAreaDiv) { + DayPilot.de(initiatorAreaDiv); + initiatorAreaDiv = null; + } + + menu._state.visible = false; + menu._state.source = null; + + if (menu._parentMenu && props.hideParent) { + menu._parentMenu.hide(props); + } + + if (DayPilot.Menu.active === menu) { + DayPilot.Menu.active = null; + } + + if (typeof this.onHide === "function") { + var args = {}; + this.onHide(args); + } + + }; + + this.delayedHide = function(props) { + DayPilotMenu.hideTimeout = setTimeout(function() { + menu.hide(props); + }, menu.hideAfter); + }; + + this.cancelHideTimeout = function() { + clearTimeout(DayPilotMenu.hideTimeout); + }; + + // detects the mouse position, use when creating menu right before opening (.show) + this.init = function(ev) { + DayPilotMenu.mouseMove(ev); + return this; + }; + + // disabled + this.addShadow = function(object) {}; + + // disabled + this.removeShadow = function() { + /* if (!this._state.shadows) { + return; + } + + for (var i = 0; i < this._state.shadows.length; i++) { + document.body.removeChild(this._state.shadows[i]); + } + this._state.shadows = [];*/ + }; + + + var options = DayPilot.isArray(items) ? null : items; + if (options) { + for (var name in options) { + this[name] = options[name]; + } + } + + }; + + DayPilot.MenuBar = function(id, options) { + var menubar = this; + + options = options || {}; + + this.items = []; + this.theme = "menubar_default"; + this.windowMargin = 0; + + this.nav = {}; + this.elements = {}; + this.elements.items = DayPilot.list(); + + this._active = null; + this._initialized = false; + + for (var name in options) { + this[name] = options[name]; + } + + this._cssClass = function(cl) { + return this.theme + "_" + cl; + }; + + this._show = function() { + this.nav.top = document.getElementById(id); + + var top = this.nav.top; + top.className = this._cssClass("main"); + + DayPilot.list(menubar.items).forEach(function(item) { + var div = document.createElement("span"); + div.innerHTML = DayPilot.Util.escapeTextHtml(item.text, item.html); + div.className = menubar._cssClass("item"); + if (item.cssClass) { + div.classList.add(item.cssClass); + } + div.data = item; + div.onclick = function(e) { + if (menubar.active && menubar.active.item === item) { + menubar._hideActive(); + } + else if (item.children) { + menubar._activate(div); + return; + } + + if (typeof item.onClick === "function") { + var args = {}; + args.item = item; + args.originalEvent = e; + item.onClick(args); + } + }; + div.onmousedown = function(ev) { + ev.stopPropagation(); + }; + div.onmouseover = function() { + if (menubar.active && menubar.active.item !== item) { + menubar._activate(div); + } + }; + + top.appendChild(div); + menubar.elements.items.push(div); + }); + }; + + this._hideActive = function() { + var activeCss = menubar._cssClass("item_active"); + menubar.elements.items.forEach(function(div) { + DayPilot.Util.removeClass(div, activeCss); + }); + + if (menubar.active && menubar.active.menu) { + menubar.active.menu.hide(); + } + menubar.active = null; + }; + + this._isActive = function(div) { + if (!menubar.active) { + return false; + } + return menubar.active.item === div.data; + }; + + this._activate = function(div) { + if (menubar._isActive(div)) { + return; + } + + menubar._hideActive(); + + var item = div.data; + var a = menubar.active = {}; + a.item = item; + a.div = div; + + var activeCss = menubar._cssClass("item_active"); + DayPilot.Util.addClass(div, activeCss); + + var abs = DayPilot.abs(div); + + if (item.children) { + a.menu = new DayPilot.Menu({"items": item.children}); + // a.menu.show(null, { "x": abs.x + abs.w, "y": abs.y + abs.h, "align": item.align, "windowMargin": menubar.windowMargin}); + var x = abs.x; + if (item.align === "right") { + x += abs.w; + } + a.menu.show(null, { "x": x, "y": abs.y + abs.h, "align": item.align, "windowMargin": menubar.windowMargin}); + } + + DayPilot.MenuBar.active = menubar; + }; + + this.init = function() { + this._show(); + this._initialized = true; + return this; + }; + + this.dispose = function() { + if (!this._initialized) { + return; + } + this.nav.top.innerHTML = ""; + this.elements.items = []; + }; + + }; + + DayPilot.MenuBar.deactivate = function() { + if (DayPilot.MenuBar.active) { + DayPilot.MenuBar.active._hideActive(); + DayPilot.MenuBar.active = null; + } + }; + + DayPilotMenu.menuClean = function() { + if (typeof(DayPilot.Menu.active) === 'undefined') + return; + + if (DayPilot.Menu.active) { + DayPilot.Menu.active.hide(); + DayPilot.Menu.active = null; + } + + }; + + DayPilotMenu.mouseDown = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + DayPilotMenu.menuClean(); + + DayPilot.MenuBar.deactivate(); + }; + + DayPilotMenu.mouseMove = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + DayPilotMenu.mouse = DayPilotMenu.mousePosition(ev); + }; + + DayPilotMenu.touchMove = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev); + }; + + DayPilotMenu.touchStart = function(ev) { + if (typeof(DayPilotMenu) === 'undefined') { + return; + } + //DayPilotMenu.menuClean(); + DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev); + }; + + DayPilotMenu.touchEnd = function(ev) { + // do not call menuClean() here, it doesn't work with eventTapAndHoldHandling="ContextMenu" + // DayPilotMenu.menuClean(); + }; + + DayPilotMenu.touchPosition = function(ev) { + if (!ev || !ev.touches) { + return null; + } + var touch = ev.touches[0]; + var mouse = {}; + mouse.x = touch.pageX; + mouse.y = touch.pageY; + return mouse; + }; + + DayPilotMenu.mousePosition = function(e) { + return DayPilot.mo3(null, e); + }; + + DayPilot.Menu.touchPosition = function(ev) { + if (ev.touches) { + DayPilotMenu.mouse = DayPilotMenu.touchPosition(ev); + } + }; + // publish the API + + DayPilot.Menu.hide = function(options) { + options = options || {}; + + if (options.calendar) { + var active = DayPilot.Menu.active; + if (active) { + var source = active._state.source; + if (source && source.calendar === options.calendar) { + DayPilotMenu.menuClean(); + } + } + } + else { + DayPilotMenu.menuClean(); + } + }; + + // current + //DayPilot.Menu = DayPilotMenu.Menu; + if (!DayPilotMenu.handlersRegistered && typeof document !== 'undefined') { + DayPilot.re(document, 'mousemove', DayPilotMenu.mouseMove); + DayPilot.re(document, 'mousedown', DayPilotMenu.mouseDown); + DayPilot.re(document, 'touchmove', DayPilotMenu.touchMove); + DayPilot.re(document, 'touchstart', DayPilotMenu.touchStart); + DayPilot.re(document, 'touchend', DayPilotMenu.touchEnd); + DayPilotMenu.handlersRegistered = true; + } + + DayPilot.Menu.def = {}; + +})(DayPilot); diff --git a/static/src/js/src/daypilot-modal.src.js b/static/src/js/src/daypilot-modal.src.js new file mode 100644 index 0000000..72acfdc --- /dev/null +++ b/static/src/js/src/daypilot-modal.src.js @@ -0,0 +1,3650 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). + +v3.15.0 +https://modal.daypilot.org/ + +*/ + +if (typeof(DayPilot) === 'undefined') { + DayPilot = {}; +} + +(function(DayPilot) { + 'use strict'; + + // modal.js -> 1482 + + if (DayPilot.ModalStatic) { + return; + } + + DayPilot.ModalStatic = {}; + + DayPilot.ModalStatic.list = []; + + // hide the last one + DayPilot.ModalStatic.hide = function() { + if (this.list.length > 0) { + var last = this.list.pop(); + if (last) { + last.hide(); + } + } + }; + + DayPilot.ModalStatic.remove = function(modal) { + var list = DayPilot.ModalStatic.list; + for (var i = 0; i < list.length; i++) { + if (list[i] === modal) { + list.splice(i, 1); + return; + } + } + }; + + DayPilot.ModalStatic.close = function(result) { + DayPilot.ModalStatic.result(result); + DayPilot.ModalStatic.hide(); + }; + + DayPilot.ModalStatic.result = function(r) { + var list = DayPilot.ModalStatic.list; + if (list.length > 0) { + list[list.length - 1].result = r; + } + }; + + DayPilot.ModalStatic.displayed = function(modal) { + var list = DayPilot.ModalStatic.list; + for (var i = 0; i < list.length; i++) { + if (list[i] === modal) { + return true; + } + } + return false; + }; + + DayPilot.ModalStatic.stretch = function() { + if (this.list.length > 0) { + var last = this.list[this.list.length - 1]; + if (last) { + last.stretch(); + } + } + }; + + DayPilot.ModalStatic.last = function() { + var list = DayPilot.ModalStatic.list; + if (list.length > 0) { + return list[list.length - 1]; + } + return null; + }; + + var Sheet = function() { + + if (typeof window === "undefined") { + // next.js server-side rendering + var sheet = {}; + sheet.add = function() {}; + sheet.commit = function() {}; + return sheet; + } + + var style = document.createElement("style"); + style.setAttribute("type", "text/css"); + if (!style.styleSheet) { // ie + style.appendChild(document.createTextNode("")); + } + + var h = document.head || document.getElementsByTagName('head')[0]; + h.appendChild(style); + + var oldStyle = !! style.styleSheet; // old ie + + var sheet = {}; + sheet.rules = []; + sheet.commit = function() { + try { + if (oldStyle) { + style.styleSheet.cssText = this.rules.join("\n"); + } + } + catch (e) { + //alert("Error registering the built-in stylesheet (IE stylesheet limit reached). Stylesheet count: " + document.styleSheets.length); + } + }; + + sheet.add = function(selector, rules, index) { + if (oldStyle) { + this.rules.push(selector + "{" + rules + "\u007d"); + return; + } + if(style.sheet.insertRule) { // normal browsers, ie9+ + if (typeof index === "undefined") { + index = style.sheet.cssRules.length; + } + style.sheet.insertRule(selector + "{" + rules + "\u007d", index); + } + else if (style.sheet.addRule) { + style.sheet.addRule(selector, rules, index); + } + else { + throw "No CSS registration method found"; + } + }; + return sheet; + }; + + var iconCalendar = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB3aWR0aD0iMTAiCiAgIGhlaWdodD0iMTUiCj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDUpIj4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojY2NjY2NjO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjM4MDM3MzM2O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDE5MjgiCiAgICAgICB3aWR0aD0iOS45MTUzMDYxIgogICAgICAgaGVpZ2h0PSIxMS4zNjkzNyIKICAgICAgIHg9IjAuMTE3MTg3NSIKICAgICAgIHk9Ii0zLjAwOTk5NTciCiAgICAgICByeT0iMS4zMTE4NTA1IiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNjY2NjY2M7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNTk4MTQwMTI7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MTkzMCIKICAgICAgIHdpZHRoPSIxLjUzNDQxMzYiCiAgICAgICBoZWlnaHQ9IjIuMjE5ODI1IgogICAgICAgeD0iMi4xNTU4NDgzIgogICAgICAgeT0iLTQuMzkzNzAwMSIKICAgICAgIHJ5PSIwLjY3MTc4OTE3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSItMS4xNjU4NDY2IgogICAgICAgeD0iMS41MjM5NTA2IgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QxOTQ4IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjY3MTc4OTE3IgogICAgICAgeT0iLTQuMzkzNzAwMSIKICAgICAgIHg9IjYuNDUyNzIzNSIKICAgICAgIGhlaWdodD0iMi4yMTk4MjUiCiAgICAgICB3aWR0aD0iMS41MzQ0MTM2IgogICAgICAgaWQ9InJlY3QyMDAzIgogICAgICAgc3R5bGU9ImZpbGw6I2NjY2NjYztmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS41OTgxNDAxMjtzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MjAwNSIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHg9IjQuMjE5MjYzMSIKICAgICAgIHk9Ii0xLjE2NTg0NjYiCiAgICAgICByeT0iMC4yOTYwMTQ3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSItMS4xNjU4NDY2IgogICAgICAgeD0iNi45OTI3MDA2IgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QyMDA3IgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogICAgPHJlY3QKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICAgIGlkPSJyZWN0MjAxMyIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHg9IjEuNTIzOTUwNiIKICAgICAgIHk9IjEuODAyOTAzNCIKICAgICAgIHJ5PSIwLjI5NjAxNDciIC8+CiAgICA8cmVjdAogICAgICAgcnk9IjAuMjk2MDE0NyIKICAgICAgIHk9IjEuODAyOTAzNCIKICAgICAgIHg9IjQuMjE5MjYzMSIKICAgICAgIGhlaWdodD0iMS44Mjk5MDkxIgogICAgICAgd2lkdGg9IjEuODM0MjI1MSIKICAgICAgIGlkPSJyZWN0MjAxNSIKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjEuNDIxODkxOTM7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIgLz4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjQyMTg5MTkzO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDIwMTciCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB4PSI2Ljk5MjcwMDYiCiAgICAgICB5PSIxLjgwMjkwMzQiCiAgICAgICByeT0iMC4yOTYwMTQ3IiAvPgogICAgPHJlY3QKICAgICAgIHJ5PSIwLjI5NjAxNDciCiAgICAgICB5PSI0LjczMjU5MDciCiAgICAgICB4PSIxLjU2MzAxMzEiCiAgICAgICBoZWlnaHQ9IjEuODI5OTA5MSIKICAgICAgIHdpZHRoPSIxLjgzNDIyNTEiCiAgICAgICBpZD0icmVjdDIwMTkiCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDoxLjQyMTg5MTkzO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiIC8+CiAgICA8cmVjdAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgaWQ9InJlY3QyMDIxIgogICAgICAgd2lkdGg9IjEuODM0MjI1MSIKICAgICAgIGhlaWdodD0iMS44Mjk5MDkxIgogICAgICAgeD0iNC4yNTgzMjU2IgogICAgICAgeT0iNC43MzI1OTA3IgogICAgICAgcnk9IjAuMjk2MDE0NyIgLz4KICAgIDxyZWN0CiAgICAgICByeT0iMC4yOTYwMTQ3IgogICAgICAgeT0iNC43MzI1OTA3IgogICAgICAgeD0iNy4wMzE3NjMxIgogICAgICAgaGVpZ2h0PSIxLjgyOTkwOTEiCiAgICAgICB3aWR0aD0iMS44MzQyMjUxIgogICAgICAgaWQ9InJlY3QyMDIzIgogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MS40MjE4OTE5MztzdHJva2UtbGluZWNhcDpidXR0O3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIiAvPgogIDwvZz4KPC9zdmc+Cg=="; + var iconExpand = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB3aWR0aD0iMTAiCiAgIGhlaWdodD0iMTUiCj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLDUpIj4KICAgIDxwYXRoCiAgICAgICBpZD0icGF0aDMxNzMiCiAgICAgICBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojOTk5OTk5O3N0cm9rZS13aWR0aDoxLjg1MTk2ODUzO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIKICAgICAgIGQ9Ik0gMC45NTQxNDgzOCwwLjY4MTYwMzEgNS4wMzkwNjI1LDUuNDExNTM4NiA5LjEyMzk3NjYsMC42ODE2MDMxIgogICAgICAgIC8+CiAgPC9nPgo8L3N2Zz4K"; + + var sheet = new Sheet(); + sheet.add(".modal_default_main", "border: 10px solid #ccc; max-width: 90%;"); + sheet.add(".modal_default_main:focus", "outline: none;"); + sheet.add(".modal_default_content", "padding: 10px 0px;"); + sheet.add(".modal_default_inner", "padding: 20px;"); + sheet.add(".modal_default_input", "padding: 10px 0px;"); + sheet.add(".modal_default_buttons", "margin-top: 10px;"); + sheet.add(".modal_default_buttons", "padding: 10px 0px;"); + sheet.add(".modal_default_form_item", "padding: 10px 0px; position: relative;"); + sheet.add(".modal_default_form_item_level1", "border-left: 2px solid #ccc; margin-left: 10px; padding-left: 20px;"); + sheet.add(".modal_default_form_item.modal_default_form_title", "font-size: 1.5rem; font-weight: bold;"); + sheet.add(".modal_default_form_item input[type=text]", "width: 100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item textarea", "width: 100%; height: 200px; box-sizing: border-box;"); + sheet.add(".modal_default_form_item input[type=select]", "width: 100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item label", "display: block;"); + sheet.add(".modal_default_form_item select", "width: 100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item_label", "margin: 2px 0px;"); + sheet.add(".modal_default_form_item_image img", "max-width: 100%; height: auto;"); + + sheet.add(".modal_default_form_item_invalid", ""); + sheet.add(".modal_default_form_item_invalid_message", "position: absolute; right: 0px; top: 9px; background-color: red; color: #ffffff; padding: 2px; border-radius: 2px;"); + + sheet.add(".modal_default_background", "opacity: 0.5; background-color: #000;"); + sheet.add(".modal_default_ok", "padding: 3px; width: 80px;"); + sheet.add(".modal_default_cancel", "padding: 3px; width: 80px;"); + + sheet.add(".modal_default_form_item_date", "position: relative;"); + sheet.add(".modal_default_form_item_date:after", "content: ''; position: absolute; right: 7px; top: 50%; margin-top: 3px; width: 10px; height: 15px; background-image:url(" + iconCalendar + ")"); + + if (typeof navigator !== "undefined" && navigator.userAgent.indexOf("Edge") !== -1) { + sheet.add(".modal_default_form_item_date input::-ms-clear", "display: none;"); + } + + sheet.add(".modal_default_form_item_scrollable_scroll", "width: 100%; height: 200px; box-sizing: border-box; border: 1px solid #ccc; overflow-y: auto;"); + sheet.add(".modal_default_form_item_scrollable_scroll_content", "padding: 5px;"); + + sheet.add(".modal_default_form_item_searchable", "position: relative;"); + sheet.add(".modal_default_form_item_searchable_icon", ""); + sheet.add(".modal_default_form_item_searchable_icon:after", "content:''; position: absolute; right: 5px; top: 50%; margin-top: -8px; width: 10px; height: 15px; background-image:url(" + iconExpand + ");"); + sheet.add(".modal_default_form_item_searchable_list", "box-sizing: border-box; border: 1px solid #999; max-height: 150px; overflow-y: auto;"); + sheet.add(".modal_default_form_item_searchable_list_item", "background: white; padding: 2px; cursor: default;"); + sheet.add(".modal_default_form_item_searchable_list_item_highlight", "background: #ccc;"); + + sheet.add(".modal_default_form_item_time", "position: relative;"); + sheet.add(".modal_default_form_item_time_icon", ""); + sheet.add(".modal_default_form_item_time_icon:after", "content:''; position: absolute; right: 5px; top: 50%; margin-top: -8px; width: 10px; height: 15px; background-image:url(" + iconExpand + ");"); + sheet.add(".modal_default_form_item_time_list", "box-sizing: border-box; border: 1px solid #999; max-height: 150px; overflow-y: auto;"); + sheet.add(".modal_default_form_item_time_list_item", "background: white; padding: 2px; cursor: default;"); + sheet.add(".modal_default_form_item_time_list_item_highlight", "background: #ccc;"); + + sheet.add(".modal_default_form_item_datetime_parent", "display: flex;"); + sheet.add(".modal_default_form_item_datetime .modal_default_form_item_time_main", "margin-left: 5px;"); + sheet.add(".modal_default_form_item_datetime input[type='text'].modal_default_input_date ", ""); + + sheet.add(".modal_default_form_item_tabular_main", "margin-top: 10px;"); + sheet.add(".modal_default_form_item_tabular_table", "display: table; width: 100%; xbackground-color: #fff; border-collapse: collapse;"); + sheet.add(".modal_default_form_item_tabular_tbody", "display: table-row-group;"); + sheet.add(".modal_default_form_item_tabular_row", "display: table-row;"); + sheet.add(".modal_default_form_item_tabular_row.modal_default_form_item_tabular_header", ""); // used to be bold + sheet.add(".modal_default_form_item_tabular_cell.modal_default_form_item_tabular_rowaction", "padding: 0px; width: 23px;"); // _delete: width + marginLeft + sheet.add(".modal_default_form_item_tabular_cell", "display: table-cell; border: 0px; padding: 2px 2px 2px 0px; cursor: default; vertical-align: bottom;"); + sheet.add(".modal_default_form_item_tabular_header .modal_default_form_item_tabular_cell", "padding-left: 0px; padding-bottom: 0px;"); + sheet.add(".modal_default_form_item_tabular_table input[type=text], .modal_default_form_item_tabular_table input[type=number]", "width:100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item_tabular_table select", "width:100%; height:100%; box-sizing: border-box;"); + sheet.add(".modal_default_form_item_tabular_plus", "display: inline-block; background-color: #ccc; color: white; width: 20px; height: 20px; border-radius: 10px; box-sizing: border-box; position: relative; margin-left: 3px; margin-top: 3px; cursor: pointer;"); + sheet.add(".modal_default_form_item_tabular_plus:after", "content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTAnIGhlaWdodD0nMTAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTSA1LjAgMC41IEwgNS4wIDkuNSBNIDAuNSA1LjAgTCA5LjUgNS4wJyBzdHlsZT0nZmlsbDpub25lO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpidXR0JyAvPjwvc3ZnPg==\")"); + sheet.add(".modal_default_form_item_tabular_delete", "display: inline-block; background-color: #ccc; color: white; width: 20px; height: 20px; border-radius: 10px; box-sizing: border-box; position: relative; margin-left: 3px; margin-top: 3px; cursor: pointer;"); + sheet.add(".modal_default_form_item_tabular_delete:after", "content: ''; position: absolute; left: 5px; top: 5px; width: 10px; height: 10px; background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0nMTAnIGhlaWdodD0nMTAnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTSAwLjUgMC41IEwgOS41IDkuNSBNIDAuNSA5LjUgTCA5LjUgMC41JyBzdHlsZT0nZmlsbDpub25lO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDoyO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbGluZWNhcDpidXR0JyAvPjwvc3ZnPg==\")"); + sheet.add(".modal_default_form_item_tabular_disabled .modal_default_form_item_tabular_plus", "display: none;"); + sheet.add(".modal_default_form_item_tabular_plus_max.modal_default_form_item_tabular_plus", "display: none;"); + sheet.add(".modal_default_form_item_tabular_disabled .modal_default_form_item_tabular_delete", "visibility: hidden;"); + sheet.add(".modal_default_form_item_tabular_empty", "height: 1px; margin: 5px 23px 5px 0px; background-color: #ccc;"); + sheet.add(".modal_default_form_item_tabular_spacer .modal_default_form_item_tabular_cell", "padding: 0px;"); + + sheet.add(".modal_min_main", "border: 1px solid #ccc; max-width: 90%;"); + sheet.add(".modal_min_background", "opacity: 0.5; background-color: #000;"); + sheet.add(".modal_min_ok", "padding: 3px 10px;"); + sheet.add(".modal_min_cancel", "padding: 3px 10px;"); + + + sheet.add(".navigator_modal_main", "border-left: 1px solid #c0c0c0;border-right: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;background-color: white;color: #000000; box-sizing: content-box;"); + sheet.add(".navigator_modal_main *, .navigator_modal_main *:before, .navigator_modal_main *:after", "box-sizing: content-box;"); + sheet.add(".navigator_modal_month", "font-size: 11px;"); + sheet.add(".navigator_modal_day", "color: black;"); + sheet.add(".navigator_modal_weekend", "background-color: #f0f0f0;"); + sheet.add(".navigator_modal_dayheader", "color: black;"); + sheet.add(".navigator_modal_line", "border-bottom: 1px solid #c0c0c0;"); + sheet.add(".navigator_modal_dayother", "color: gray;"); + sheet.add(".navigator_modal_todaybox", "border: 1px solid red;"); + sheet.add(".navigator_modal_title, .navigator_modal_titleleft, .navigator_modal_titleright", 'border-top: 1px solid #c0c0c0;border-bottom: 1px solid #c0c0c0;color: #333;background: #f3f3f3;'); + sheet.add(".navigator_modal_busy", "font-weight: bold;"); + sheet.add(".navigator_modal_cell", "text-align: center;"); + sheet.add(".navigator_modal_select .navigator_modal_cell_box", "background-color: #FFE794; opacity: 0.5;"); + sheet.add(".navigator_modal_title", "text-align: center;"); + sheet.add(".navigator_modal_titleleft, .navigator_modal_titleright", "text-align: center;"); + sheet.add(".navigator_modal_dayheader", "text-align: center;"); + sheet.add(".navigator_modal_weeknumber", "text-align: center;"); + sheet.add(".navigator_modal_cell_text", "cursor: pointer;"); + + sheet.commit(); + + DayPilot.Modal = function(options) { + + // default values + this.autoFocus = true; + this.focus = null; // field to be focused - field id as string or {id, value} + this.autoStretch = true; // height will be increased automatically to avoid scrollbar, until this.maxHeight is reached + this.autoStretchFirstLoadOnly = false; + this.className = null; + this.theme = "modal_default"; + this.disposeOnClose = true; + this.dragDrop = true; + this.loadingHtml = null; + this.maxHeight = null; // if not set, it will stretch until the bottom space is equal to this.top + this.scrollWithPage = true; // modal window will scroll with the page + this.useIframe = true; // only for showHtml() + this.zIndex = 99999; + + this.left = null; // will be centered if null + this.width = 600; + this.top = 20; + this.height = 200; // see also autoStretch + this.locale = null; // used for DayPilot.Modal.form() items with "date" type + + // event handler + this.closed = null; + this.onClose = null; + this.onClosed = null; + this.onShow = null; + + // internal + var This = this; + this.id = '_' + new Date().getTime() + 'n' + (Math.random() * 10); + this._registered = false; + + // drag&drop + this._start = null; + this._coords = null; + + this.showHtml = function(html) { + + if (DayPilot.ModalStatic.displayed(this)) { + throw "This modal dialog is already displayed."; + } + + if (!this.div) { + this._create(); + } + this._update(); + + if (this.useIframe) { + var delayed = function(p, innerHTML) { + return function() { + p.setInnerHTML(p.id + "iframe", innerHTML); + }; + }; + + window.setTimeout(delayed(this, html), 0); + } + else { + if (html.nodeType) { + this.div.appendChild(html); + } + else { + this.div.innerHTML = html; + } + } + + this._update(); + this._register(); + this._doShow(); + + }; + + this.showUrl = function(url) { + + if (DayPilot.ModalStatic.displayed(this)) { + throw "This modal dialog is already displayed."; + } + + //this.useIframe = true; // forced + + if (this.useIframe) { + if (!this.div) { + this._create(); + } + + var loadingHtml = this.loadingHtml; + if (loadingHtml) { + this.iframe.src = "about:blank"; + this.setInnerHTML(this.id + "iframe", loadingHtml); + } + + this.re(this.iframe, "load", this._onIframeLoad); + + this.iframe.src = url; + //this.iframe.contentWindow.modal = This; + + this._update(); + this._register(); + this._doShow(); + } + else { + This._ajax({ + "url": url, + "success": function(args) { + var html = args.request.responseText; + This.showHtml(html); + }, + "error": function(args) { + This.showHtml("Error loading the modal dialog"); + } + }); + } + + }; + + this._doShow = function() { + if (typeof This.onShow === "function") { + var args = {}; + args.root = This._body(); + args.modal = This; + This.onShow(args); + } + }; + + this._body = function() { + return This.iframe ? This.iframe.contentWindow.document : This.div; + }; + + this._ajax = function(object) { + var req = new XMLHttpRequest(); + if (!req) { + return; + } + + var method = object.method || "GET"; + var success = object.success || function() {}; + var error = object.error || function() {}; + var data = object.data; + var url = object.url; + + req.open(method, url, true); + req.setRequestHeader('Content-type', 'text/plain'); + req.onreadystatechange = function() { + if (req.readyState !== 4) + return; + if (req.status !== 200 && req.status !== 304) { + if (error) { + var args = {}; + args.request = req; + error(args); + } + else { + if (window.console) { console.log('HTTP error ' + req.status); } + } + return; + } + var args = {}; + args.request = req; + success(args); + }; + if (req.readyState === 4) { + return; + } + if (typeof data === 'object') { + data = JSON.stringify(data); + } + req.send(data); + }; + + this._update = function() { + + delete this.result; + + var win = window; + var doc = document; + + var scrollY = win.pageYOffset ? win.pageYOffset : ((doc.documentElement && doc.documentElement.scrollTop) ? doc.documentElement.scrollTop : doc.body.scrollTop); + + var height = function() { + return This._windowRect().y; + }; + + //this.hideDiv.style.height = height() + "px"; + if (this.theme) { + this.hideDiv.className = this.theme + "_background"; + } + if (this.zIndex) { + this.hideDiv.style.zIndex = this.zIndex; + } + this.hideDiv.style.display = ''; + + window.setTimeout(function() { + if (This.hideDiv) { + This.hideDiv.onclick = function() { + This.hide({"backgroundClick": true}); + }; + } + }, 500); + + if (this.theme) { + this.div.className = this.theme + "_main"; + } + else { + this.div.className = ""; + } + + if (this.className) { + this.div.className += " " + this.className; + } + if (this.left) { + this.div.style.left = this.left + "px"; + } + else { + this.div.style.marginLeft = '-' + Math.floor(this.width / 2) + "px"; // '-45%' + } + this.div.style.position = 'absolute'; + this.div.style.boxSizing = "content-box"; + this.div.style.top = (scrollY + this.top) + 'px'; + this.div.style.width = this.width + 'px'; // '90%' + if (this.zIndex) { + this.div.style.zIndex = this.zIndex; + } + + if (this.height) { + if (this.useIframe || !this.autoStretch) { + this.div.style.height = this.height + 'px'; + } + else { + this.div.style.height = ''; + } + } + if (this.useIframe && this.height) { + this.iframe.style.height = (this.height) + 'px'; + } + + this.div.style.display = ''; + + this._updateHorizontal(); + + // make sure it's there just once + DayPilot.ModalStatic.remove(this); + DayPilot.ModalStatic.list.push(this); + + /* + if (this.iframe) { + this.iframe.onload = null; + } + */ + }; + + this._onIframeLoad = function() { + This.iframe.contentWindow.modal = This; + if (This.autoStretch) { + This.stretch(); + } + }; + + this.stretch = function() { + var height = function() { + return This._windowRect().y; + }; + + var width = function() { + return This._windowRect().x; + }; + + + if (this.useIframe) { + // width first + var maxWidth = width() - 40; // fixed 20px margin + for (var w = this.width; w < maxWidth && this._hasHorizontalScrollbar(); w += 10) { + //this.iframe.style.width = (w) + 'px'; + this.div.style.width = w + 'px'; + this.div.style.marginLeft = '-' + Math.floor(w / 2) + "px"; // + } + + // height + var maxHeight = this.maxHeight || height() - 2 * this.top; + for (var h = this.height; h < maxHeight && this._hasVerticalScrollbar(); h += 10) { + this.iframe.style.height = (h) + 'px'; + this.div.style.height = h + 'px'; + } + + if (this.autoStretchFirstLoadOnly) { + this.ue(this.iframe, "load", this._onIframeLoad); + } + } + else { + this.div.style.height = ''; + } + + + }; + + this._hasHorizontalScrollbar = function() { + var document = this.iframe.contentWindow.document; + var root = document.compatMode === 'BackCompat' ? document.body : document.documentElement; + + var scrollWidth = root.scrollWidth; + var children = document.body.children; + for (var i = 0; i < children.length; i++) { + var bottom = children[i].offsetLeft + children[i].offsetWidth; + scrollWidth = Math.max(scrollWidth, bottom); + } + + var isHorizontalScrollbar = scrollWidth > root.clientWidth; + return isHorizontalScrollbar; + + }; + + this._hasVerticalScrollbar = function() { + var document = this.iframe.contentWindow.document; + var root = document.compatMode === 'BackCompat' ? document.body : document.documentElement; + + var scrollHeight = root.scrollHeight; + var children = document.body.children; + for (var i = 0; i < children.length; i++) { + var bottom = children[i].offsetTop + children[i].offsetHeight; + scrollHeight = Math.max(scrollHeight, bottom); + } + + var isVerticalScrollbar = scrollHeight > root.clientHeight; + //var isHorizontalScrollbar = root.scrollWidth > root.clientWidth; + return isVerticalScrollbar; + }; + + this._windowRect = function() { + var doc = document; + + if (doc.compatMode === "CSS1Compat" && doc.documentElement && doc.documentElement.clientWidth) { + var x = doc.documentElement.clientWidth; + var y = doc.documentElement.clientHeight; + return { x: x, y: y }; + } + else { + var x = doc.body.clientWidth; + var y = doc.body.clientHeight; + return { x: x, y: y }; + } + }; + + this._register = function() { + if (this._registered) { + return; + } + this.re(window, 'resize', this._onWindowResize); + this.re(window, 'scroll', this._onWindowScroll); + + if (this.dragDrop) { + this.re(document, 'mousemove', this._onMouseMove); + this.re(document, 'mouseup', this._onMouseUp); + } + this._registered = true; + }; + + this._unregister = function() { + this.ue(window, 'resize', this._onWindowResize); + this.ue(window, 'scroll', this._onWindowScroll); + if (this.dragDrop) { + this.ue(document, 'mousemove', this._onMouseMove); + this.ue(document, 'mouseup', this._onMouseUp); + } + this._registered = false; + }; + + this._onDragStart = function(e) { + if (e.target !== This.div) { + return; + } + e.preventDefault(); + This.div.style.cursor = "move"; + This._maskIframe(); + This._coords = This.mc(e || window.event); + This._start = { x: This.div.offsetLeft, y: This.div.offsetTop }; + + }; + + this._onMouseMove = function(e) { + if (!This._coords) { + return; + } + + var e = e || window.event; + var now = This.mc(e); + + var x = now.x - This._coords.x; + var y = now.y - This._coords.y; + + //This.iframe.style.display = 'none'; + This.div.style.marginLeft = '0px'; + This.div.style.top = (This._start.y + y) + "px"; + This.div.style.left = (This._start.x + x) + "px"; + + }; + + this._onMouseUp = function(e) { + // no drag&drop + if (!This._coords) { + return; + } + //This.iframe.style.display = ''; + This._unmaskIframe(); + This.div.style.cursor = null; + + This._coords = null; + }; + + this._maskIframe = function() { + if (!this.useIframe) { + return; + } + + var opacity = 80; + + var mask = document.createElement("div"); + mask.style.backgroundColor = "#ffffff"; + mask.style.filter = "alpha(opacity=" + opacity + ")"; + mask.style.opacity = "0." + opacity; + mask.style.width = "100%"; + mask.style.height = this.height + "px"; + mask.style.position = "absolute"; + mask.style.left = '0px'; + mask.style.top = '0px'; + + this.div.appendChild(mask); + this.mask = mask; + }; + + this._unmaskIframe = function() { + if (!this.useIframe) { + return; + } + + this.div.removeChild(this.mask); + this.mask = null; + }; + + this._onWindowResize = function() { + This._updateTop(); + This._updateHorizontal(); + }; + + this._onWindowScroll = function() { + This._updateTop(); + }; + + this._updateHorizontal = function() { + if (This.left) { + return; + } + + if (!This.div) { + return; + } + + var width = This.div.offsetWidth; + This.div.style.marginLeft = '-' + Math.floor(width / 2) + "px"; // '-45%' + }; + + this._updateTop = function() { + if (!This.hideDiv) { + return; + } + if (!This.div) { + return; + } + if (This.hideDiv.style.display === 'none') { + return; + } + if (This.div.style.display === 'none') { + return; + } + + var scrollY = This._parent.scrollY(); + + + //This.hideDiv.style.height = height() + "px"; + if (!This.scrollWithPage) { + This.div.style.top = (scrollY + This.top) + 'px'; + } + }; + + this._parent = {}; + this._parent.container = function() { + return This.container || document.body; + }; + this._parent.scrollY = function() { + var c = This._parent.container(); + if (c === document.body) { + return window.pageYOffset ? window.pageYOffset : ((document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop); + } + else { + return c.scrollTop; + } + }; + + // already available in common.js but this file should be standalone + this.re = function(el, ev, func) { + if (el.addEventListener) { + el.addEventListener(ev, func, false); + } else if (el.attachEvent) { + el.attachEvent("on" + ev, func); + } + }; + + // unregister event + this.ue = function(el, ev, func) { + if (el.removeEventListener) { + el.removeEventListener(ev, func, false); + } else if (el.detachEvent) { + el.detachEvent("on" + ev, func); + } + }; + + // mouse coords + this.mc = function(ev) { + if (ev.pageX || ev.pageY) { + return { x: ev.pageX, y: ev.pageY }; + } + return { + x: ev.clientX + document.documentElement.scrollLeft, + y: ev.clientY + document.documentElement.scrollTop + }; + }; + + // absolute element position on page + this.abs = function(element) { + var r = { + x: element.offsetLeft, + y: element.offsetTop + }; + + while (element.offsetParent) { + element = element.offsetParent; + r.x += element.offsetLeft; + r.y += element.offsetTop; + } + + return r; + }; + + this._create = function() { + + var container = This._parent.container(); + var isRoot = container === document.body; + var position = isRoot ? "fixed" : "absolute"; + + var hide = document.createElement("div"); + hide.id = this.id + "hide"; + hide.style.position = position; + hide.style.left = "0px"; + hide.style.top = "0px"; + hide.style.right = "0px"; + hide.style.bottom = "0px"; + hide.oncontextmenu = function() { return false; }; + hide.onmousedown = function() { return false; }; // prevent selecting + + container.appendChild(hide); + + var div = document.createElement("div"); + div.id = this.id + 'popup'; + div.style.position = position; + div.style.left = '50%'; + div.style.top = '0px'; + div.style.backgroundColor = 'white'; + div.style.width = "50px"; + div.style.height = "50px"; + if (this.dragDrop) { + div.onmousedown = this._onDragStart; + } + div.addEventListener("keydown", function(e) { + // prevent interaaction with the document using keyboard + e.stopPropagation(); + }); + + var defaultHeight = 50; + + var iframe = null; + if (this.useIframe) { + iframe = document.createElement("iframe"); + iframe.id = this.id + "iframe"; + iframe.name = this.id + "iframe"; + iframe.frameBorder = '0'; + iframe.style.width = '100%'; + iframe.style.height = defaultHeight + 'px'; + div.appendChild(iframe); + } + + container.appendChild(div); + + this.div = div; + this.iframe = iframe; + this.hideDiv = hide; + }; + + this.setInnerHTML = function(id, innerHTML) { + var frame = window.frames[id]; + + var doc = frame.contentWindow || frame.document || frame.contentDocument; + if (doc.document) { + doc = doc.document; + } + + if (doc.body == null) { // null in IE + doc.write(""); + } + + if (innerHTML.nodeType) { + doc.body.appendChild(innerHTML); + } + else { + doc.body.innerHTML = innerHTML; + } + + if (This.autoStretch) { + if (!This.autoStretchFirstLoadOnly || !This._stretched) { + This.stretch(); + This._stretched = true; + } + } + }; + + this.close = function(result) { + this.result = result; + this.hide(); + }; + + this.closeSerialized = function() { + var ref = This._body(); + var fields = ref.querySelectorAll("input, textarea, select"); + var result = {}; + for (var i = 0; i < fields.length; i++) { + var field = fields[i]; + var name = field.name; + if (!name) { + continue; + } + var value = field.value; + /*if (field.picker) { + value = field.picker.date ? field.picker.date.toString() : null; + } + else*/ /*if (field.table) { + value = field.table.save(); + } + else*/ /*if (field.searchable) { + value = field.searchable.selected && field.searchable.selected.id; + } + else *//*if (field.tagName === "SELECT") { + var option = field.options[field.selectedIndex]; + if (option && typeof option._originalValue !== "undefined") { + value = option._originalValue; + } + } + else*/ /*if (field.type === "radio") { + if (!field.checked) { + continue; + } + value = field._originalValue; + } + else*/ /*if (field.type === "checkbox") { + value = field.checked; + }*/ + result[name] = value; + } + This.close(result); + }; + + this.hide = function(options) { + + options = options || {}; + + var args = {}; + args.backgroundClick = !!options.backgroundClick; + args.result = this.result; + args.canceled = typeof this.result === "undefined"; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof this.onClose === "function") { + this.onClose(args); + if (args.preventDefault.value) { + return; + } + } + + if (this.div) { + this.div.style.display = 'none'; + this.hideDiv.style.display = 'none'; + if (!this.useIframe) { + this.div.innerHTML = null; + } + } + + // return focus to the main window (Firefox) + window.focus(); + + //DayPilot.ModalStatic = null; + DayPilot.ModalStatic.remove(this); + + if (typeof this.onClosed === "function") { + this.onClosed(args); + } + else if (this.closed) { + this.closed(); + } + + delete this.result; + + if (this.disposeOnClose) { + + This._unregister(); + + This._de(This.div); + This._de(This.hideDiv); + + This.div = null; + This.hideDiv = null; + This.iframe = null; + } + }; + + this._de = function(e) { + if (!e) { + return; + } + e.parentNode && e.parentNode.removeChild(e); + }; + + this._applyOptions = function() { + if (!options) { + return; + } + + for (var name in options) { + this[name] = options[name]; + } + }; + + this._applyOptions(); + + }; + + DayPilot.Modal.alert = function(message, options) { + options = options || {}; + options.height = options.height || 40; + options.useIframe = false; + + var okText = options.okText || "OK"; + var cancelText = options.cancelText || "Cancel"; + + return DayPilot.getPromise(function(success, failure) { + options.onClosed = function(args) { + success(args); + /* + if (typeof args.result === "undefined") { + failure(args); + } + else { + + }*/ + }; + + var modal = new DayPilot.Modal(options); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + // div.style.padding = "10px"; + + var text = document.createElement("div"); + text.className = modal.theme + "_content"; + text.innerHTML = message; + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + // buttons.style.margin = "10px 0px"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + buttonOK.onclick = function(e) { + DayPilot.ModalStatic.close("OK"); + }; + + buttons.appendChild(buttonOK); + + div.appendChild(text); + div.appendChild(buttons); + + //var buttons = "
"; + + modal.showHtml(div); + + if (modal.autoFocus) { + buttonOK.focus(); + } + }); + + }; + + DayPilot.Modal.confirm = function(message, options) { + options = options || {}; + options.height = options.height || 40; + options.useIframe = false; + + var okText = options.okText || "OK"; + var cancelText = options.cancelText || "Cancel"; + + return DayPilot.getPromise(function(success, failure) { + options.onClosed = function(args) { + success(args); + }; + + var modal = new DayPilot.Modal(options); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + // div.style.padding = "10px"; + + var text = document.createElement("div"); + text.className = modal.theme + "_content"; + text.innerHTML = message; + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + // buttons.style.margin = "10px 0px"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + buttonOK.onclick = function(e) { + DayPilot.ModalStatic.close("OK"); + }; + + var space = document.createTextNode(" "); + + var buttonCancel = document.createElement("button"); + buttonCancel.innerText = cancelText; + buttonCancel.className = modal.theme + "_cancel"; + buttonCancel.onclick = function(e) { + DayPilot.ModalStatic.close(); + }; + + buttons.appendChild(buttonOK); + buttons.appendChild(space); + buttons.appendChild(buttonCancel); + + div.appendChild(text); + div.appendChild(buttons); + + modal.showHtml(div); + + if (modal.autoFocus) { + buttonOK.focus(); + } + + }); + }; + + + DayPilot.Modal.prompt = function(message, defaultValue, options) { + if (typeof defaultValue === "object") { + options = defaultValue; + defaultValue = ""; + } + + options = options || {}; + options.height = options.height || 40; + options.useIframe = false; + + var okText = options.okText || "OK"; + var cancelText = options.cancelText || "Cancel"; + + var inputText = defaultValue || ""; + + return DayPilot.getPromise(function(success, failure) { + options.onClosed = function(args) { + success(args); + }; + + var modal = new DayPilot.Modal(options); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + + var text = document.createElement("div"); + text.className = modal.theme + "_content"; + text.innerHTML = message; + + var inputs = document.createElement("div"); + inputs.className = modal.theme + "_input"; + //inputs.style.margin = "10px 0px"; + + var input = document.createElement("input"); + input.value = inputText; + input.style.width = "100%"; + input.onkeydown = function(e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: + modal.close(this.value); + break; + case 27: + modal.close(); + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + inputs.appendChild(input); + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + //buttons.style.margin = "10px 0px"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + buttonOK.onclick = function(e) { + modal.close(input.value); + }; + + var space = document.createTextNode(" "); + + var buttonCancel = document.createElement("button"); + buttonCancel.innerText = cancelText; + buttonCancel.className = modal.theme + "_cancel"; + buttonCancel.onclick = function(e) { + modal.close(); + }; + + buttons.appendChild(buttonOK); + buttons.appendChild(space); + buttons.appendChild(buttonCancel); + + + div.appendChild(text); + div.appendChild(inputs); + div.appendChild(buttons); + + modal.showHtml(div); + + if (modal.autoFocus) { + input.focus(); + } + + }); + }; + + var isArray = function(arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; + }; + + function setPathValue(target, path, value) { + var iodot = path.indexOf("."); + if (iodot === -1) { + if (path !== "__proto__" && path !== "constructor") { + target[path] = value; + } + return; + } + var segment = path.substring(0, iodot); + if (segment === "__proto__" || segment === "constructor") { + return; + } + var remainder = path.substring(iodot + 1); + var child = target[segment]; + if (typeof child !== "object" || child === null) { + target[segment] = {}; + child = target[segment]; + } + setPathValue(child, remainder, value); + } + + // form = array of items + // data = object with properties + // options = standard modal properties + // DayPilot.Modal.form([]); // form only - new data + // DayPilot.Modal.form({}); // data only - automatic form + // + DayPilot.Modal.form = function(form, data, options) { + if (arguments.length === 1) { + var arg = form; + var isa = isArray(arg); + + if (isa) { + data = {}; + } + else if (typeof arg === "object") { + data = form; + form = []; + for (var name in data) { + var item = {}; + item.name = name; + item.id = name; + form.push(item); + } + } + else { + throw "Invalid DayPilot.Modal.form() parameter"; + } + + } + + // make a copy + var opts = {}; + for (var name in options) { + opts[name] = options[name]; + } + + // options = options || {}; + opts.height = opts.height || 40; + opts.useIframe = false; + + /* if (typeof opts.autoFocus === "undefined") { + opts.autoFocus = false; + }*/ + + var okText = opts.okText || "OK"; + var cancelText = opts.cancelText || "Cancel"; + + // var message = opts.message || ""; + + return DayPilot.getPromise(function(success, failure) { + opts.onClosed = function(args) { + + if (args.result) { + // deep copy + var mergedResult = JSON.parse(JSON.stringify(data)); + + // unflatten + for (var name in args.result) { + setPathValue(mergedResult, name, args.result[name]); + } + args.result = mergedResult; + } + + success(args); + }; + + var modal = new DayPilot.Modal(opts); + + var div = document.createElement("div"); + div.className = modal.theme + "_inner"; + + var inputs = document.createElement("div"); + inputs.className = modal.theme + "_input"; + + var f = new Form({ + theme: modal.theme, + form: form, + data: data, + zIndex: modal.zIndex, + locale: modal.locale, + plugins: modal.plugins, + onKey: function(args) { + switch (args.key) { + case "Enter": + // modal.closeSerialized(); + // modal.close(f.serialize()); + if (f.validate()) { + modal.close(f.serialize()); + } + break; + case "Escape": + modal.close(); + break; + } + }, + onChange: function(args) { + if (typeof modal.onChange === "function") { + modal.onChange(args); + } + } + }); + var el = f.create(); + + inputs.append(el); + + var buttons = document.createElement("div"); + buttons.className = modal.theme + "_buttons"; + + var buttonOK = document.createElement("button"); + buttonOK.innerText = okText; + buttonOK.className = modal.theme + "_ok"; + + if (opts.okDisabled) { + buttonOK.disabled = true; + } + buttonOK.onclick = function(e) { + if (f.validate()) { + modal.close(f.serialize()); + } + // modal.closeSerialized(); + }; + + var space = document.createTextNode(" "); + + var buttonCancel = document.createElement("button"); + buttonCancel.innerText = cancelText; + buttonCancel.className = modal.theme + "_cancel"; + buttonCancel.onclick = function(e) { + modal.close(); + }; + buttonCancel.onmousedown = function(e) { + f.canceling = true; + }; + + buttons.appendChild(buttonOK); + buttons.appendChild(space); + buttons.appendChild(buttonCancel); + + + // div.appendChild(text); + div.appendChild(inputs); + div.appendChild(buttons); + + modal.showHtml(div); + + modal.div.setAttribute("tabindex", "-1"); + modal.div.addEventListener("keydown", function(e) { + switch (e.keyCode) { + case 27: + modal.close(); + break; + case 13: + if (f.validate()) { + modal.close(f.serialize()); + } + // modal.closeSerialized(); + break; + } + }); + + if (modal.focus) { + var toBeFocused = null; + if (typeof modal.focus === "object") { + var id = modal.focus.id; + var value = modal.focus.value; + toBeFocused = f.findViewById(id, value); + } + else if (typeof modal.focus === "string") { + toBeFocused = f.findViewById(modal.focus) + } + if (toBeFocused) { + toBeFocused.focus(); + } + } + else { + var first = f.firstFocusable(); + if (modal.autoFocus && first) { + first.focus(); + } + else { + modal.div.focus(); + } + } + + }); + }; + + DayPilot.Modal.close = function(result) { + var opener = DayPilot.Modal.opener(); + if (!opener) { + return; + } + opener.close(result); + }; + + DayPilot.Modal.stretch = function(result) { + var opener = DayPilot.Modal.opener(); + if (!opener) { + throw "Unable to find the opener DayPilot.Modal instance."; + } + opener.stretch(); + }; + + DayPilot.Modal.closeSerialized = function() { + var last = DayPilot.Modal.opener() || DayPilot.ModalStatic.last(); + if (last) { + last.closeSerialized(); + } + }; + + DayPilot.Modal.opener = function() { + if (typeof DayPilot !== "undefined" && typeof DayPilot.ModalStatic !== "undefined" && DayPilot.ModalStatic.list.length > 0) { + return DayPilot.ModalStatic.list[DayPilot.ModalStatic.list.length - 1]; + } + return parent && parent.DayPilot && parent.DayPilot.ModalStatic && parent.DayPilot.ModalStatic.list[parent.DayPilot.ModalStatic.list.length - 1]; + }; + + DayPilot.Modal.Experimental = {}; + DayPilot.Modal.Experimental.Form = Form; + + if (typeof DayPilot.getPromise === "undefined") { + DayPilot.getPromise = function(f) { + if (typeof Promise !== 'undefined') { + return new Promise(f); + } + + DayPilot.Promise = function(f) { + var p = this; + + this.then = function(onFulfilled, onRejected) { + onFulfilled = onFulfilled || function() {}; + onRejected = onRejected || function() {}; + f(onFulfilled, onRejected); + return DayPilot.getPromise(f); + }; + + this['catch'] = function(onRejected) { + p.then(null, onRejected); + return DayPilot.getPromise(f); + }; + }; + + return new DayPilot.Promise(f); + + }; + } + + // end of modal.js + + // form.js -> 2877 + + var Form = function (options) { + + // properties + this.form = []; + this.data = {}; + this.theme = "form_default"; + this.zIndex = 99999; + this.locale = "en-us"; + this.plugins = {}; + + // events + this.onKey = null; + + // state + this._rows = []; + this._newRows = null; + this.canceling = false; + + this._validationTimeouts = []; + + // view + this._views = []; + this._div = null; + + options = options || {}; + + for (var name in options) { + this[name] = options[name]; + } + }; + + Form.prototype.create = function () { + this.load(); + this.render(); + + return this._div; + }; + + Form.prototype.render = function () { + var form = this; + this._div = document.createElement("div"); + this._rows.forEach(function (row) { + form.createView(row); + }); + this.applyState(); + }; + + Form.prototype.createView = function (row) { + var theme = this.theme; + var form = this; + + var div = document.createElement("div"); + div.className = theme + "_form_item " + theme + "_form_item_level" + row.level; + if (!row.interactive && row.type === "title") { + /* + if (row.type === "title") { + div.className += " " + theme + "_form_title"; + } + */ + div.className += " " + theme + "_form_title"; + } + else { + div.className += " " + theme + "_form_item_" + row.type; + } + if (row.data.cssClass) { + div.className += " " + row.data.cssClass; + } + + if (!row.isValue) { + var label = document.createElement("div"); + label.className = theme + "_form_item_label"; + label.innerText = row.text; + div.appendChild(label); + } + + var interactive = this.createInteractive(row); + interactive.onInput = function(options) { + options = options || {}; + form._validateInteractive(interactive, { + "debounce": !options.immediate + }); + if (typeof form.onChange === "function") { + var args = {}; + args.result = form.serialize(); + form.onChange(args); + } + }; + interactive.onBlur = function() { + if (!form.canceling) { + form._validateInteractive(interactive); + } + }; + interactive.apply(row); + interactive._div = div; + interactive.row = row; + + if (interactive.element) { + div.appendChild(interactive.element); + } + + this._views.push(interactive); + + this._div.appendChild(div); + + }; + + Form.prototype.validate = function() { + var form = this; + var valid = true; + this._views.forEach(function(interactive) { + var iv = form._validateInteractive(interactive); + valid = valid && iv; + }); + return valid; + }; + + Form.prototype._validateInteractive = function(interactive, options) { + options = options || {}; + var debounce = options.debounce; + var silent = options.silent; + + + var row = interactive.row; + var valid = true; + + var onValidate = typeof row.data.onValidate === "function" ? row.data.onValidate : null; + var validate = typeof row.data.validate === "function" ? row.data.validate : null; // legacy + + var validateHandler = onValidate || validate; + + if (validateHandler) { + + var args = {}; + args.valid = true; + args.value = interactive.save()[row.field]; + args.message = "Error"; + args.values = this.serialize(); // legacy + args.result = this.serialize(); + + validateHandler(args); + + var cssClassInvalid = this.theme + "_form_item_invalid"; + var cssClassMessage = this.theme + "_form_item_invalid_message"; + if (args.valid) { + clearTimeout(this._validationTimeouts[row.field]); + + if (interactive._errorMsg) { + interactive._errorMsg.remove(); + interactive._errorMsg = null; + } + interactive._div.classList.remove(cssClassInvalid); + } + else { + + function showInvalid() { + if (interactive._errorMsg) { + interactive._errorMsg.remove(); + interactive._errorMsg = null; + } + + interactive._div.classList.add(cssClassInvalid); + var msg = document.createElement("div"); + msg.classList.add(cssClassMessage); + msg.innerText = args.message; + + interactive._errorMsg = msg; + + interactive._div.appendChild(msg); + } + + if (!silent) { + if (debounce) { + + var debounceDelay = 1000; + + clearTimeout(this._validationTimeouts[row.field]); + + this._validationTimeouts[row.field] = setTimeout(function() { + showInvalid(); + }, debounceDelay); + } + else { + showInvalid(); + } + + } + + } + valid = args.valid; + } + return valid; + }; + + Form.prototype.load = function () { + // transform this.form + this.data into state (_rows) + var t = this; + this.form.forEach(function (item) { + t.processFormItem(item, 0); + }); + + var flat; + // sanity check (especially for circular references) + try { + var stringified = JSON.stringify(this.data); + var rebuilt = JSON.parse(stringified); + flat = flatten(rebuilt); + } + catch (e) { + throw new Error("The 'data' object is not serializable (it may contain circular dependencies): " + e); + } + + // set values + for (var name in flat) { + this.setValue(name, flat[name]); + } + + // set state depending on values + // this.updateDependentState(); + }; + + Form.prototype.setValue = function (name, value) { + this._rows.forEach(function (row) { + row.applyValue(name, value); + }); + }; + + Form.prototype.updateDependentState = function () { + var form = this; + var enabled = [true]; + + var source = this._newRows ? this._newRows : this._rows; + + source.forEach(function (row) { + + var updatedRow = form.updateState(row, { + enabled: enabled[row.level] && !row.data.disabled + }); + + if (updatedRow.isValue) { + enabled[updatedRow.level + 1] = updatedRow.enabled && updatedRow.checked; + } + }); + }; + + Form.prototype.processFormItem = function (item, level) { + var form = this; + var type = this.getFieldType(item); + + var rows = []; + + if (type === "radio") { + + if (item.name) { + var row = new RowModel(); + row.field = item.id; + row.data = item; + row.level = level; + row.type = "label"; + row.interactive = false; + row.text = item.name; + form._rows.push(row); + rows.push(row); + } + + item.options.forEach(function (option) { + var row = new RowModel(); + row.field = item.id; + row.data = option; + row.level = level; + row.type = type; + row.isValue = true; + row.text = option.name; + row.resolved = option.id; + form._rows.push(row); + rows.push(row); + + if (option.children) { + option.children.forEach(function (child) { + var childRows = form.processFormItem(child, level + 1); + rows = rows.concat(childRows); + }) + } + }); + } + else if (type === "title") { + var row = new RowModel(); + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = item.name; + form._rows.push(row); + rows.push(row); + } + else if (type === "image") { + var row = new RowModel(); + row.isValue = true; + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = null; + form._rows.push(row); + rows.push(row); + } + else if (type === "html") { + var row = new RowModel(); + row.isValue = true; + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = null; + form._rows.push(row); + rows.push(row); + } + else if (type === "scrollable") { + var row = new RowModel(); + row.isValue = true; + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.interactive = false; + row.text = null; + form._rows.push(row); + rows.push(row); + } + else { + var row = new RowModel(); + row.field = item.id; + row.data = item; + row.level = level; + row.type = type; + row.text = item.name; + row.children = []; + form._rows.push(row); + rows.push(row); + } + + if (type === "checkbox") { + row.isValue = true; + row.resolved = true; + + if (item.children) { + item.children.forEach(function (child) { + var childRows = form.processFormItem(child, level + 1); + rows = rows.concat(childRows); + }) + } + } + + return rows; + + }; + + Form.prototype.doOnKey = function (key) { + if (typeof this.onKey === "function") { + var args = { + key: key + }; + this.onKey(args); + } + }; + + Form.prototype.createInteractive = function (row) { + var form = this; + var views = { + "label": function () { + return new Interactive(); + }, + "title": function () { + return new Interactive(); + }, + "image": function() { + var interactive = new Interactive(); + + var image = document.createElement("img"); + image.src = row.data.image; + + interactive.element = image; + + return interactive; + }, + "html": function() { + var interactive = new Interactive(); + + var div = document.createElement("div"); + if (typeof row.data.text === "string") { + div.innerText = row.data.text; + } + else if (typeof row.data.html === "string") { + div.innerHTML = row.data.html; + } + + interactive.element = div; + + return interactive; + }, + "scrollable": function() { + var interactive = new Interactive(); + + var scroll = document.createElement("div"); + scroll.className = form.theme + "_form_item_scrollable_scroll"; + + if (row.data.height) { + scroll.style.height = row.data.height + "px"; + } + + var div = document.createElement("div"); + div.className = form.theme + "_form_item_scrollable_scroll_content"; + if (typeof row.data.text === "string") { + div.innerText = row.data.text; + } + else if (typeof row.data.html === "string") { + div.innerHTML = row.data.html; + } + + scroll.appendChild(div); + + interactive.element = scroll; + + return interactive; + }, + "text": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + + var input = interactive.element; + input.value = row.value; + input.disabled = !row.enabled; + }; + + var input = document.createElement("input"); + input.name = row.field; + input.type = "text"; + input.autocomplete = "off"; + input.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: + form.doOnKey("Enter"); + break; + case 27: + form.doOnKey("Escape"); + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + input.oninput = function(e) { + interactive.onInput(); + }; + input.onblur = function(e) { + interactive.onBlur(); + } + + interactive.element = input; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + interactive.element.setSelectionRange(0, interactive.element.value.length); + }; + interactive.save = function() { + var result = {}; + result[row.field] = input.value; + return result; + }; + + return interactive; + }, + "textarea": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + + var input = interactive.element; + input.value = row.value; + input.disabled = !row.enabled; + }; + + var textarea = document.createElement("textarea"); + textarea.name = row.field; + if (row.data.height) { + textarea.style.height = row.data.height + "px"; + } + // input.type = "text"; + textarea.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: + // form.doOnKey("Enter"); + if (e.ctrlKey || e.metaKey) { + form.doOnKey("Enter"); + } + letcontinue = false; + break; + case 27: + form.doOnKey("Escape"); + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + // e.preventDefault(); + e.stopPropagation(); + } + }; + + textarea.oninput = function(e) { + interactive.onInput(); + }; + textarea.onblur = function(e) { + interactive.onBlur(); + } + + interactive.element = textarea; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + interactive.element.setSelectionRange(0, 0); + }; + interactive.save = function() { + var result = {}; + result[row.field] = textarea.value; + return result; + }; + + return interactive; + }, + "date": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var input = interactive.element; + var picker = interactive.picker; + + if (row.data.dateFormat) { + picker.pattern = row.data.dateFormat; + } + var locale = row.data.locale || form.locale; + if (locale) { + picker.locale = locale; + } + + input.disabled = !row.enabled; + + picker.date = new DayPilot.Date(row.value); + var formatted = new DayPilot.Date(row.value).toString(row.data.dateFormat || picker.pattern, picker.locale); + input.value = formatted; + }; + + var input = document.createElement("input"); + input.name = row.field; + + var picker = new DayPilot.DatePicker({ + target: input, + theme: "navigator_modal", + zIndex: form.zIndex + 1, + resetTarget: false, + targetAlignment: "left", + onTimeRangeSelect: function(args) { + interactive.onInput({"immediate": true}); + } + }); + + // required for serialization - to get the normalized value + input.picker = picker; + input.className = form.theme + "_input_date"; + input.type = "text"; + input.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: // enter + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Enter"); + } + break; + case 27: // escape + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Escape"); + } + break; + case 9: // tab + picker.close(); + letcontinue = true; + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + input.onfocus = function () { + picker.show(); + }; + + input.onclick = function () { + picker.show(); + }; + + /* + input.onblur = function () { + // input.picker.close(); + }; + */ + + input.oninput = function(e) { + interactive.onInput(); + }; + input.onblur = function(e) { + interactive.onBlur(); + } + + interactive.element = input; + interactive.picker = picker; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + }; + interactive.save = function() { + var value = picker.date ? picker.date.toString() : null; + var result = {}; + result[row.field] = value; + return result; + }; + return interactive; + }, + "time": function () { + return form._createInteractiveTime(row); + }, + "datetime": function() { + return form._createInteractiveDateTime(row); + }, + "select": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var select = interactive.element; + + select.value = row.value; + select.disabled = !row.enabled; + }; + + var select = document.createElement("select"); + select.name = row.field; + + if (row.data.options && row.data.options.forEach) { + row.data.options.forEach(function (i) { + var option = document.createElement("option"); + option.innerText = i.name || i.id; + option.value = i.id; + option._originalValue = i.id; + select.appendChild(option); + }); + } + + select.onchange = function(e) { + interactive.onInput({"immediate": true}); + }; + select.onblur = function(e) { + interactive.onBlur(); + }; + + interactive.element = select; + interactive.canFocus = function() { + return !interactive.element.disabled; + }; + interactive.focus = function () { + interactive.element.focus(); + }; + interactive.save = function() { + var value = null; + var option = select.options[select.selectedIndex]; + if (option && typeof option._originalValue !== "undefined") { + value = option._originalValue; + } + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + + }, + "searchable": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var searchable = interactive.searchable; + + searchable.disabled = !row.enabled; + searchable.select(row.value); + }; + + var searchable = new Searchable({ + data: row.data.options || [], + name: row.field, + theme: form.theme + "_form_item_searchable", + listZIndex: form.zIndex + 1, + // disabled: !row.enabled + onSelect: function(args) { + if (args.ui) { + interactive.onInput({"immediate": true}); + } + } + }); + + var element = searchable.create(); + + interactive.element = element; + interactive.searchable = searchable; + interactive.canFocus = function() { + return !interactive.searchable.disabled; + }; + interactive.focus = function () { + interactive.searchable.focus(); + }; + interactive.save = function() { + var value = searchable.selected && searchable.selected.id; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + }, + "radio": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var radio = interactive.radio; + + radio.checked = row.checked; + radio.disabled = !row.enabled; + }; + + var label = document.createElement("label"); + + var radio = document.createElement("input"); + radio.type = "radio"; + radio.name = row.field; + radio._originalValue = row.resolved; + + radio.onchange = function (ev) { + // activation only + + var row = interactive.row; + form.findRowsByField(row.field).forEach(function (row) { + form.updateState(row, { + checked: false + }); + }); + form.updateState(row, { + checked: true + }); + + form.applyState(); + + interactive.onInput({"immediate": true}); + }; + + radio.onblur = function(e) { + interactive.onBlur(); + }; + + label.appendChild(radio); + + var text = document.createTextNode(row.text); + label.append(text); + + interactive.element = label; + interactive.radio = radio; + interactive.canFocus = function() { + return false; + }; + interactive.focus = function () { + interactive.radio.focus(); + } + interactive.save = function() { + if (!radio.checked) { + return {}; + } + var value = radio._originalValue; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + }, + "checkbox": function () { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var checkbox = interactive.checkbox; + + checkbox.checked = row.checked; + checkbox.disabled = !row.enabled; + }; + + var label = document.createElement("label"); + + var checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.name = row.field; + checkbox._originalValue = row.resolved; + + checkbox.onchange = function (ev) { + var row = interactive.row; + form.updateState(row, { + checked: this.checked + }); + form.applyState(); + + interactive.onInput({"immediate": true}); + }; + + checkbox.onblur = function(e) { + interactive.onBlur(); + }; + + label.appendChild(checkbox); + + var text = document.createTextNode(row.text); + label.append(text); + + interactive.element = label; + interactive.checkbox = checkbox; + interactive.canFocus = function() { + return false; + }; + interactive.focus = function () { + interactive.checkbox.focus(); + } + interactive.save = function() { + var value = checkbox.checked; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + }, + "table": function() { + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var table = interactive.table; + + table.disabled = !row.enabled; + table.load(row.value || []); + + /* + if (row.value) { + table.load(row.value); + } + */ + }; + + var table = new Table({ + name: row.field, + // form: row.data.columns, + form: form, + theme: form.theme + "_form_item_tabular", + item: row.data, + onInput: function(args) { + interactive.onInput(); + } + }); + + var element = table.create(); + + interactive.element = element; + interactive.table = table; + interactive.canFocus = function() { + // return !interactive.table.disabled; + return false; + }; + interactive.focus = function () { + interactive.table.focus(); + }; + interactive.save = function() { + var value = table.save(); + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + } + }; + if (form.plugins && form.plugins[row.type]) { + return form.plugins[row.type](row); + } + return views[row.type](); + }; + + Form.prototype._createInteractiveTime = function(row) { + var form = this; + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var searchable = interactive.searchable; + + searchable.disabled = !row.enabled; + searchable.select(row.value); + }; + + var data = []; + + var interval = row.data.timeInterval || 15; // allowed values: 1, 5, 10, 15, 20, 30, 60 + var allowedIntervals = [1, 5, 10, 15, 20, 30, 60]; + if (!allowedIntervals.includes(interval)) { + interval = 15; + } + var perHour = 60 / interval; + + var localeStr = row.data.locale || form.locale; + var locale = DayPilot.Locale.find(localeStr) || DayPilot.Locale.US; + + var date = DayPilot.Date.today(); + + for (var i = 0; i < 24*perHour; i++) { + var time = date.addMinutes(interval*i); + var item = {}; + item.name = time.toString(row.data.timeFormat || locale.timePattern, locale); + item.id = time.toString("HH:mm"); + data.push(item); + } + + var searchable = new Searchable({ + data: data, + name: row.field, + theme: form.theme + "_form_item_time", + listZIndex: form.zIndex + 1, + strategy: "startsWith", + // disabled: !row.enabled + onSelect: function(args) { + if (args.ui) { + interactive.onInput({"immediate": true}); + } + } + }); + + var element = searchable.create(); + + interactive.element = element; + interactive.searchable = searchable; + interactive.canFocus = function() { + return !interactive.searchable.disabled; + }; + interactive.focus = function () { + interactive.searchable.focus(); + }; + interactive.save = function() { + var value = searchable.selected && searchable.selected.id; + var result = {}; + result[row.field] = value; + return result; + }; + + return interactive; + + }; + + Form.prototype._createInteractiveDateTime = function(row) { + var form = this; + var interactive = new Interactive(); + interactive.apply = function (row) { + interactive.row = row; + var searchable = interactive.searchable; + + searchable.disabled = !row.enabled; + + var timePart = new DayPilot.Date(row.value).toString("HH:mm"); + + searchable.select(timePart); + + var input = interactive.dateInput; + var picker = interactive.picker; + + if (row.data.dateFormat) { + picker.pattern = row.data.dateFormat; + } + var localeStr = row.data.locale || form.locale; + if (localeStr) { + var locale = DayPilot.Locale.find(localeStr) || DayPilot.Locale.US; + picker.locale = localeStr; + picker.pattern = locale.datePattern; + } + + input.disabled = !row.enabled; + + picker.date = new DayPilot.Date(row.value); + var formatted = new DayPilot.Date(row.value).toString(row.data.dateFormat || picker.pattern, picker.locale); + input.value = formatted; + + }; + + var dateElement = (function createDatePicker() { + var input = document.createElement("input"); + input.name = row.field; + + var picker = new DayPilot.DatePicker({ + target: input, + theme: "navigator_modal", + zIndex: form.zIndex + 1, + resetTarget: false, + targetAlignment: "left", + onTimeRangeSelect: function(args) { + interactive.onInput({"immediate": true}); + } + }); + + // required for serialization - to get the normalized value + input.picker = picker; + input.className = form.theme + "_input_date"; + input.type = "text"; + input.onkeydown = function (e) { + var letcontinue = false; + switch (e.keyCode) { + case 13: // enter + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Enter"); + } + break; + case 27: // escape + if (picker.visible) { + picker.close(); + } else { + form.doOnKey("Escape"); + } + break; + case 9: // tab + picker.close(); + letcontinue = true; + break; + default: + letcontinue = true; + break; + } + if (!letcontinue) { + e.preventDefault(); + e.stopPropagation(); + } + }; + + input.onfocus = function () { + picker.show(); + }; + + input.onclick = function () { + picker.show(); + }; + + input.oninput = function(e) { + interactive.onInput(); + }; + input.onblur = function(e) { + interactive.onBlur(); + } + + interactive.dateInput = input; + interactive.picker = picker; + + return input; + })(); + + + var timeElement = (function createTimePicker() { + var data = []; + + var interval = row.data.timeInterval || 15; // allowed values: 1, 5, 10, 15, 20, 30, 60 + var allowedIntervals = [1, 5, 10, 15, 20, 30, 60]; + if (!allowedIntervals.includes(interval)) { + interval = 15; + } + var perHour = 60 / interval; + + var localeStr = row.data.locale || form.locale; + var locale = DayPilot.Locale.find(localeStr) || DayPilot.Locale.US; + + var date = DayPilot.Date.today(); + + for (var i = 0; i < 24*perHour; i++) { + var time = date.addMinutes(interval*i); + var item = {}; + item.name = time.toString(row.data.timeFormat || locale.timePattern, locale); + item.id = time.toString("HH:mm"); + data.push(item); + } + + var searchable = new Searchable({ + data: data, + name: row.field, + theme: form.theme + "_form_item_time", + listZIndex: form.zIndex + 1, + strategy: "startsWith", + // disabled: !row.enabled + onSelect: function(args) { + if (args.ui) { + interactive.onInput({"immediate": true}); + } + } + }); + + interactive.searchable = searchable; + return searchable.create(); + + })(); + + + var element = document.createElement("div"); + element.className = form.theme + "_form_item_datetime_parent"; + element.appendChild(dateElement); + element.appendChild(timeElement); + + interactive.element = element; + interactive.canFocus = function() { + return !interactive.searchable.disabled; + }; + interactive.focus = function () { + interactive.dateInput.focus(); + }; + interactive.save = function() { + var timeValue = interactive.searchable.selected && interactive.searchable.selected.id; + var dateValue = interactive.picker.date ? interactive.picker.date.toString() : null; + + var date = new DayPilot.Date(dateValue).getDatePart(); + var value = DayPilot.Date.parse(date.toString("yyyy-dd-MM ") + timeValue, "yyyy-dd-MM HH:mm"); + + var result = {}; + result[row.field] = value; + return result; + + }; + + return interactive; + + }; + + Form.prototype.findRowsByField = function (field) { + return this._rows.filter(function (row) { + return row.field === field; + }); + }; + + // ooptional value param applies to radio which can have multiple views, one for each value + Form.prototype.findViewById = function (id, value) { + return this._views.find(function (v) { + if (v.row.field === id) { + if (v.row.type === "radio") { + return v.row.resolved === value; + } else { + return true; + } + } + return false; + }); + }; + + Form.prototype.firstFocusable = function () { + return this._views.find(function (v) { + return v.canFocus && v.canFocus(); + }); + }; + + Form.prototype.updateState = function (row, props) { + var source = this._newRows ? this._newRows : this._rows; + var index = source.indexOf(row); + this._newRows = source.map(function (srow) { + if (srow !== row) { + return srow; + } + // our row + if (row.propsEqual(props)) { + return row; + } + var cloned = row.clone(); + for (var name in props) { + cloned[name] = props[name]; + } + return cloned; + }); + return this._newRows[index]; + }; + + // dirty row received, a member of _newRows + Form.prototype.updateInteractive = function (row) { + var index = this._newRows.indexOf(row); + this._views[index].apply(row); + }; + + Form.prototype.applyState = function () { + var form = this; + + this.updateDependentState(); + + if (!this._newRows) { + return; + } + + var dirtyRows = this._newRows.filter(function (row, i) { + return form._rows[i] !== row; + }); + + dirtyRows.forEach(function (row) { + form.updateInteractive(row); + }); + + this._rows = this._newRows; + + this._newRows = null; + }; + + Form.prototype.getFieldType = function (item) { + + var known = ["text", "date", "select", "searchable", "radio", "checkbox", "table", "title", "image", "html", "textarea", "scrollable", "time", "datetime"]; + if (known.indexOf(item.type) !== -1) { + return item.type; + } + + if (item.type && this.plugins && this.plugins[item.type]) { + return item.type; + } + + if (item.image) { + return "image"; + } + + if (item.html || item.text) { + return "html"; + } + + if (!item.id) { + return "title"; + } + + if (item.options) { + return "searchable"; + } + + if (item.dateFormat) { + return "date"; + } + + if (item.columns) { + return "table"; + } + + return "text"; + }; + + Form.prototype.serialize = function() { + var result = {}; + + this._views.forEach(function(interactive) { + var out = interactive.save(); + for (var name in out) { + result[name] = out[name]; + } + }); + + return result; + }; + + var RowModel = function () { + this.id = this.guid(); + this.field = null; + this.data = null; + this.type = null; + this.level = 0; + this.enabled = true; + this.value = null; + this.text = null; + + this.interactive = true; + + this.isValue = false; + this.checked = false; + this.resolved = null; // value resolves to + }; + + RowModel.prototype.clone = function () { + var rm = new RowModel(); + for (var name in this) { + if (name === "id") { + continue; + } + rm[name] = this[name]; + } + return rm; + }; + + RowModel.prototype.propsEqual = function (props) { + for (var name in props) { + if (this[name] !== props[name]) { + return false; + } + } + return true; + }; + + RowModel.prototype.guid = function () { + var S4 = function () { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + }; + return ("" + S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); + }; + + RowModel.prototype.applyValue = function (name, value) { + if (this.field !== name) { + return; + } + this.value = value; + if (this.isValue && value === this.resolved) { + this.checked = true; + } + }; + + var Interactive = function () { + // this.row = row; + this.element = null; + + // only used for autofocus + this.canFocus = function() { + return false; + }; + this.apply = function (row) { + }; + this.focus = function () { + }; + this.save = function() { + return {}; + } + }; + + function flatten(object, result, prefix) { + result = result || {}; + prefix = prefix || ""; + for (var name in object) { + var src = object[name]; + if (typeof src === "object") { + if (Object.prototype.toString.call(src) === '[object Array]') { + result[prefix + name] = src; + } + else if (src && src.toJSON) { + result[prefix + name] = src.toJSON(); + } + else { + flatten(src, result, prefix + name + "."); + } + } + else { + result[prefix + name] = src; + } + } + return result; + } + + // end of form.js + + // searchable.js -> 3265 + var Searchable = function(options) { + + // properties + this.data = []; + this.name = null; + this.theme = "searchable_default"; + this._disabled = false; + this.listZIndex = 100000; + + + // events + this.onSelect = null; + + // state + this._selected = null; + this._highlighted = null; + this._collapsed = false; + // this._focused = false; + // this._filter = null; + + // view + this._input = null; + this._list = null; + this._options = []; + this._hidden = null; + + options = options || {}; + + var t = this; + + var specialHandling = { + "selected": { + post: function(val) { + if (typeof val === "object" && val.id) { + t._selected = val; + } + else if (typeof val === "string" || typeof val === "number") { + t.select(val); + } + } + } + }; + + Object.defineProperty(this, "selected", { + get: function() { + return this._selected; + }, + }); + + Object.defineProperty(this, "disabled", { + get: function() { + return this._disabled; + }, + set: function(val) { + this._disabled = val; + if (this._input) { + this._input.disabled = val; + if (val) { + // verify + this._cancel(); + } + } + } + }); + + for (var name in options) { + if (!specialHandling[name]) { + this[name] = options[name]; + } + } + + for (var name in options) { + if (specialHandling[name]) { + specialHandling[name].post(options[name]); + } + } + + }; + + Searchable.prototype.select = function(id) { + this._selected = this.data.find(function(item) { return item.id === id }); + this._doOnSelect(false); + return this; + }; + + + Searchable.prototype.create = function() { + var component = this; + var t = this; + + var div = document.createElement("div"); + div.className = this.theme + "_main"; + div.style.position = "relative"; + + var icon = document.createElement("div"); + icon.className = this.theme + "_icon"; + icon.style.position = "absolute"; + icon.style.right = "0"; + icon.style.top = "0"; + icon.style.bottom = "0"; + icon.style.width = "20px"; + icon.addEventListener("mousedown", function(ev) { + ev.preventDefault(); + if (component._collapsed) { + component.focus(); + expand(); + } + else { + cancel(); + collapse(); + } + }); + + var list = document.createElement("div"); + list.className = this.theme + "_list"; + list.style.display = "none"; + list.style.position = "absolute"; + list.style.zIndex = this.listZIndex; + + var hidden = document.createElement("input"); + hidden.type = "hidden"; + hidden.name = this.name; + hidden.searchable = t; + this._hidden = hidden; + + var input = document.createElement("input"); + input.type = "text"; + input.className = this.theme + "_input"; + input.disabled = this._disabled; + input.addEventListener("click", function(ev) { + // console.log("click"); + expand(); + }); + input.addEventListener("focus", function(ev) { + // do not call expand() here, the readonly status has to stay + // input.value = ""; + // console.log("focus"); + filter("all"); + }); + input.addEventListener("input", function(ev) { + filter(); + }); + input.addEventListener("blur", function(ev) { + input.removeAttribute("readonly"); + cancel(); + }); + + input.addEventListener("keydown", function(ev) { + if (component._collapsed) { + if (ev.key === "Enter") { + return; + } + if (ev.key === "Esc" || ev.key === "Escape") { + return; + } + expand(); + } + + if (ev.key === "ArrowDown") { + var index = t._options.indexOf(t._highlighted); + if (index + 1 < t._options.length) { + t._highlighted = t._options[index + 1]; + } + updateHiglight(); + } else if (ev.key === "ArrowUp") { + var index = t._options.indexOf(t._highlighted); + if (index - 1 >= 0) { + t._highlighted = t._options[index - 1]; + } + updateHiglight(); + } else if (ev.key === "Enter") { + if (component._highlighted) { + ev.stopPropagation(); + selectOption(component._highlighted); + } + else { + ev.stopPropagation(); + // t._cancel(); + cancel(); + collapse(); + } + } else if (ev.key === "Esc" || ev.key === "Escape") { + ev.stopPropagation(); + cancel(); + collapse(); + } + }); + this._input = input; + this._list = list; + + if (!this._selected) { + this._selected = this.data[0]; + if (this._selected) { + input.value = this._selected.name; + } + } + + function filter(strategy) { + // component._collapsed = false; + + var defaultStrategy = component.strategy; + if (component.strategy !== "includes" && component.strategy !== "startsWith") { + defaultStrategy = "includes"; + } + + strategy = strategy || defaultStrategy || "includes"; + + list.style.display = ""; + list.style.top = input.offsetHeight + "px"; + list.style.left = "0px"; + list.style.width = input.offsetWidth + "px"; + list.innerHTML = ""; + + // allow scrollbar access + list.addEventListener("mousedown", function(ev) { + ev.preventDefault(); + }); + + component._highlighted = null; + + component._options = []; + + var first = null; + + component.data.forEach(function(item) { + + var name = item.name || item.id; + + if (strategy === "includes") { + if (name.toLowerCase().indexOf(input.value.toLowerCase()) === -1) { + return; + } + } + else if (strategy === "startsWith") { + if (name.toLowerCase().indexOf(input.value.toLowerCase()) !== 0) { + return; + } + } + else if (strategy === "all") { + // don't skip + } + + + var option = document.createElement("div"); + option.className = component.theme + "_list_item"; + option.innerText = name; + + option.item = item; + + if (item === component._selected) { + component._highlighted = option; + } + if (!first) { + first = option; + } + + // "mousedown" goes before blur, "click" goes after + option.addEventListener("mousedown", function(ev) { + selectOption(option); + ev.preventDefault(); + }); + + option.addEventListener("mousemove", function(ev) { + if (component._highlighted === option) { + return; + } + component._highlighted = option; + updateHiglight({dontScroll: true}); + }); + + list.appendChild(option); + + component._options.push(option); + }); + + if (!component._highlighted) { + component._highlighted = first; + } + updateHiglight(); + } + + function updateHiglight(options) { + options = options || {}; + var scrollIntoView = !options.dontScroll; + + // redo, avoid selectors + var previous = document.querySelectorAll("." + component.theme + "_list_item_highlight"); + previous.forEach(function(p) { + p.className = p.className.replace(component.theme + "_list_item_highlight", ""); + }); + + if (component._highlighted) { + component._highlighted.className += " " + component.theme + "_list_item_highlight"; + + if (scrollIntoView && !isScrolledIntoView(component._highlighted, list)) { + component._highlighted.scrollIntoView(); + } + } + } + + function isScrolledIntoView(target, viewport) { + var tRect = target.getBoundingClientRect(); + var vRect = viewport.getBoundingClientRect(); + return tRect.top >= vRect.top && tRect.bottom <= vRect.bottom; + } + + function selectOption(option) { + var item = option.item; + + // input.value = option.innerText; + component._selected = item; + component._doOnSelect(true); + hide(); + collapse(); + } + + function cancel() { + component._cancel(); + } + + function hide() { + component._hide(); + } + + function collapse() { + component._collapsed = true; + input.setAttribute("readonly", "readonly"); + input.focus(); + } + + function expand() { + component._collapsed = false; + input.removeAttribute("readonly"); + // input.value = ""; + input.select(); + filter("all"); + } + + div.appendChild(input); + div.appendChild(icon); + div.appendChild(hidden); + div.appendChild(list); + return div; + }; + + Searchable.prototype._cancel = function() { + this._hide(); + if (!this._selected) { + this._input.value = ""; + // not sure about this: + this._doOnSelect(true); + } else { + this._input.value = this._selected.name; + } + // collapse(); + } + + Searchable.prototype.focus = function() { + // this._input.focus(); + + this._collapsed = true; + this._input.setAttribute("readonly", "readonly"); + this._input.focus(); + this._cancel(); + }; + + Searchable.prototype._hide = function() { + this._list.style.display = "none"; + }; + + Searchable.prototype._doOnSelect = function(byUser) { + this._hidden.value = this.selected ? this.selected.id : null; + if (this._selected) { + this._input.value = this._selected.name; + } + else { + this._input.value = ""; + } + + if (typeof this.onSelect === "function") { + var args = { + control: this, + ui: byUser + }; + this.onSelect(args); + } + }; + + // end of searchable.js + + // table.js -> 3641 + var Table = function(options) { + + this.form = null; // Form instance + this.item = null; // table def from form + this.data = null; + this.name = null; + this.theme = "edit_table_default"; + this.onInput = null; + + this.nav = {}; + + this._activeEdit = null; + this._rows = []; + + options = options || {}; + + for (var name in options) { + this[name] = options[name]; + } + + }; + + Table.prototype.create = function() { + var table = this; + + var div = document.createElement("div"); + div.className = this.theme + "_main"; + div.style.position = "relative"; + + var hidden = document.createElement("input"); + hidden.type = "hidden"; + hidden.name = table.name; + hidden.table = this; + div.appendChild(hidden); + + var tableElement = document.createElement("div"); + tableElement.className = this.theme + "_table"; + var header = this._createHeader(); + tableElement.appendChild(header); + + var spacerRow = table._createRowState({}); + spacerRow.spacer = true; + var spacer = this._renderRow(spacerRow); + // spacer.style.visibility = "hidden"; + spacer.classList.add(table.theme + "_spacer"); + tableElement.appendChild(spacer); + + var body = document.createElement("div"); + body.className = table.theme + "_tbody"; + tableElement.appendChild(body); + + div.appendChild(tableElement); + + var after = document.createElement("div"); + div.appendChild(after); + + this.nav.body = body; + this.nav.table = tableElement; + this.nav.main = div; + this.nav.after = after; + + var add = document.createElement("div"); + var plus = document.createElement("span"); + plus.className = this.theme + "_plus"; + + plus.addEventListener("click", function(ev) { + if (table.disabled) { + return; + } + + var generate = table.item.onNewRow; + var value = {}; + if (typeof generate === "function") { + var args = {}; + args.result = table.form.serialize(); + args.value = {}; + generate(args); + value = args.value; + } + + var row = table._createRowState(value); + table._rows.push(row); + table._render(); + table._doOnInput(); + }); + + this.nav.plus = plus; + + add.appendChild(plus); + div.appendChild(add); + + return div; + }; + + Table.prototype._createHeader = function() { + var table = this; + var row = document.createElement("div"); + row.classList.add(this.theme + "_row"); + row.classList.add(this.theme + "_header"); + this.item.columns.forEach(function(item) { + var cell = document.createElement("div"); + cell.classList.add(table.theme + "_cell"); + cell.innerText = item.name; + row.appendChild(cell); + }); + return row; + }; + + Table.prototype._maxRowsReached = function() { + var max = this.item.max || 0; + if (max && this._rows.length >= max) { + return true; + } + return false; + }; + + Table.prototype.save = function() { + var table = this; + var data = []; + + table._rows.forEach(function(row) { + var item = {}; + row.cells.forEach(function(cell) { + item[cell.id] = cell.value; + }); + data.push(item); + }); + + return data; + }; + + Table.prototype.load = function(data) { + var table = this; + + var isArray = Object.prototype.toString.call(data) === '[object Array]'; + if (!isArray) { + throw new Error("Array expected"); + } + + this.data = data; + + this._createState(); + this._render(); + }; + + Table.prototype._updateCss = function() { + if (this.disabled) { + this.nav.main.classList.add(this.theme + "_disabled"); + } + else { + this.nav.main.classList.remove(this.theme + "_disabled"); + } + + var maxReached = this._maxRowsReached(); + if (maxReached) { + this.nav.plus.classList.add(this.theme + "_plus_max"); + } + else { + this.nav.plus.classList.remove(this.theme + "_plus_max"); + } + }; + + Table.prototype._createState = function() { + var table = this; + this._rows = []; + this.data.forEach(function(dataRow) { + var row = table._createRowState(dataRow); + table._rows.push(row); + }); + }; + + Table.prototype._removeRow = function(row) { + var table = this; + + var index = table._rows.indexOf(row); + table._rows.splice(index, 1); + }; + + Table.prototype._createRowState = function(dataRow) { + var table = this; + + var row = {}; + row.data = dataRow; + row.cells = []; + + table.item.columns.forEach(function(formItem) { + var id = formItem.id; + var value = dataRow[id]; + + var type = table._formItemType(formItem); + if (typeof value === "undefined") { + if (type === "text") { + value = ""; + } + else if (type === "number") { + value = 0; + } + else if (type === "select") { + var options = formItem.options; + value = options && options[0].id; + } + } + + var cell = {}; + cell.id = id; + cell.value = value; + cell.type = type; + cell.data = formItem; + row.cells.push(cell); + }); + + return row; + }; + + Table.prototype._formItemType = function(formItem) { + var type = formItem.type; + if (!type) { + if (formItem.options) { + type = "select"; + } + else { + type = "text"; + } + } + return type; + }; + + Table.prototype._render = function() { + + var table = this; + this.nav.body.innerHTML = ""; + this.nav.after.innerHTML = ""; + + this._rows.forEach(function(row) { + var el = table._renderRow(row); + table.nav.body.appendChild(el); + }); + + if (this._rows.length === 0) { + var el = table._renderEmpty(); + table.nav.after.appendChild(el); + } + + this._updateCss(); + }; + + Table.prototype._renderEmpty = function() { + var div = document.createElement("div"); + div.className = this.theme + "_empty"; + + return div; + }; + + Table.prototype._renderRow = function(row) { + var table = this; + var el = document.createElement("div"); + el.className = table.theme + "_row"; + + row.cells.forEach(function(cell) { + + var cellEl = document.createElement("div"); + cellEl.className = table.theme + "_cell"; + var interactive = table._renderCell(cell); + + if (row.spacer) { + var wrap = document.createElement("div"); + wrap.style.height = "0px"; + wrap.style.overflow = "hidden"; + wrap.appendChild(interactive); + + cellEl.appendChild(wrap); + } + else { + cellEl.appendChild(interactive); + + } + + el.appendChild(cellEl); + }); + + var cell = document.createElement("div"); + cell.classList.add(table.theme + "_cell"); + cell.classList.add(table.theme + "_rowaction"); + + var span = document.createElement("span"); + span.className = this.theme + "_delete"; + + span.addEventListener("click", function(ev) { + if (table.disabled) { + return; + } + table._removeRow(row); + table._render(); + table._doOnInput(); + }); + + if (!row.spacer) { + cell.appendChild(span); + } + + + el.appendChild(cell); + + return el; + }; + + Table.prototype._doOnInput = function() { + var table = this; + if (typeof table.onInput === "function") { + var args = {} + table.onInput(args); + } + }; + + Table.prototype._renderCell = function(cell) { + var table = this; + var type = cell.type; + if (type === "text" || type === "number") { + var input = document.createElement("input"); + input.type = type; + if (table.disabled) { + input.disabled = true; + } + if (cell.value) { + input.value = cell.value; + } + input.addEventListener("keyup", function(ev) { + if (type === "number") { + cell.value = Number(this.value); + } + else { + cell.value = this.value; + } + table._doOnInput(); + }); + return input; + } + else if (type === "select") { + var select = document.createElement("select"); + if (table.disabled) { + select.disabled = true; + } + + cell.data.options.forEach(function(item) { + var option = document.createElement("option"); + option.innerText = item.name; + option.value = item.id; + option._originalValue = item.id; + + select.appendChild(option); + + if (cell.value === item.id) { + option.setAttribute("selected", true); + } + }); + + select.addEventListener("change", function(ev) { + var option = select.options[select.selectedIndex]; + if (option && typeof option._originalValue !== "undefined") { + cell.value = option._originalValue; + } + table._doOnInput(); + }); + + return select; + } + + throw new Error("Unsupported item type: " + type); + }; + + Table.prototype.focus = function() { + }; + + // end of table.js + +})(DayPilot); diff --git a/static/src/js/src/daypilot-month.src.js b/static/src/js/src/daypilot-month.src.js new file mode 100644 index 0000000..e851482 --- /dev/null +++ b/static/src/js/src/daypilot-month.src.js @@ -0,0 +1,2440 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function() { + + var doNothing = function() { }; + + if (typeof DayPilot.Month !== 'undefined' && DayPilot.Month.events) { + return; + } + + var DayPilotMonth = {}; + + DayPilotMonth.Month = function(placeholder, options) { + this.v = '2024.3.539-lite'; + this.nav = {}; + + var calendar = this; + + this.id = placeholder; + this.isMonth = true; + + // this.angularAutoApply = false; + this.api = 2; + this.backendUrl = null; + this.cellHeaderHeight = 24; + this.cellHeight = 100; // default cell height is 100 pixels (it's a minCellHeight, it will be extended if needed) + this.cellMarginBottom = 0; + this.contextMenu = null; + this.cssClassPrefix = "month_default"; + this.eventBarVisible = true; + this.eventHeight = 25; + this.eventsLoadMethod = "GET"; + this.headerHeight = 30; + this.hideUntilInit = true; + this.lineSpace = 1; + this.locale = "en-us"; + this.showToolTip = true; + this.startDate = new DayPilot.Date(); // today + this.theme = null; + this.visible = true; + this.weekStarts = "Auto"; + this.width = '100%'; // default width is 100% + this.xssProtection = "Enabled"; + + this.afterRender = function() { }; + + this.cellHeaderClickHandling = "Enabled"; + this.eventClickHandling = "Enabled"; + this.eventDeleteHandling = "Disabled"; + this.eventMoveHandling = "Update"; + this.eventResizeHandling = "Update"; + this.eventRightClickHandling = "ContextMenu"; + this.headerClickHandling = "Enabled"; + this.timeRangeSelectedHandling = "Enabled"; + + this.onCellHeaderClick = null; + this.onCellHeaderClicked = null; + this.onEventClick = null; + this.onEventClicked = null; + this.onEventDelete = null; + this.onEventDeleted = null; + this.onEventMove = null; + this.onEventMoved = null; + this.onEventResize = null; + this.onEventResized = null; + this.onEventRightClick = null; + this.onEventRightClicked = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + + this.onBeforeEventRender = null; + this.onBeforeCellRender = null; + + this.cellEvents = []; + + this.elements = {}; + this.elements.events = []; + + this.cache = {}; + + this._disposed = false; + + this._updateView = function(result, context) { + + var result = JSON.parse(result); + + if (result.CallBackRedirect) { + document.location.href = result.CallBackRedirect; + return; + } + + if (result.UpdateType === "None") { + calendar.fireAfterRenderDetached(result.CallBackData, true); + return; + } + + calendar.events.list = result.Events; + + if (result.UpdateType === "Full") { + + // properties + calendar.startDate = result.StartDate; + // calendar.headerBackColor = result.HeaderBackColor ? result.HeaderBackColor : calendar.headerBackColor; + // calendar.backColor = result.BackColor ? result.BackColor : calendar.backColor; + // calendar.nonBusinessBackColor = result.NonBusinessBackColor ? result.NonBusinessBackColor : calendar.nonBusinessBackColor; + calendar.timeFormat = result.TimeFormat ? result.TimeFormat : calendar.timeFormat; + if (typeof result.WeekStarts !== 'undefined') { calendar.weekStarts = result.WeekStarts; } // number, can be 0 + + calendar.hashes = result.Hashes; + } + + calendar._deleteEvents(); + calendar._prepareRows(); + calendar._loadEvents(); + + if (result.UpdateType === "Full") { + calendar._clearTable(); + calendar._drawTable(); + } + calendar._updateHeight(); + + calendar.show(); + + calendar._drawEvents(); + + calendar.fireAfterRenderDetached(result.CallBackData, true); + + }; + + this.fireAfterRenderDetached = function(data, isCallBack) { + var afterRenderDelayed = function(data, isc) { + return function() { + if (calendar.afterRender) { + calendar.afterRender(data, isc); + } + }; + }; + + window.setTimeout(afterRenderDelayed(data, isCallBack), 0); + }; + + this.lineHeight = function() { + return this.eventHeight + this.lineSpace; + }; + + this.events = {}; + //this.events.list = []; + + this.events.add = function(e) { + + var data = null; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + data = e; + } + else { + throw "DayPilot.Month.events.add() expects an object or DayPilot.Event instance."; + } + + // e.calendar = calendar; + + if (!calendar.events.list) { + calendar.events.list = []; + } + + calendar.events.list.push(data); + calendar.update(); + calendar._angular.notify(); + }; + + this.events.find = function(id) { + if (!calendar.events.list) { + return null; + } + + if (typeof id === "function") { + var fn = id; + for (var i = 0; i < calendar.events.list.length; i++) { + var e = new DayPilot.Event(calendar.events.list[i], calendar); + if (fn(e)) { + return e; + } + } + return null; + } + + for (var i = 0; i < calendar.events.list.length; i++) { + var data = calendar.events.list[i]; + if (data.id === id) { + return new DayPilot.Event(data, calendar); + } + } + return null; + }; + + this.events.update = function(e) { + if (e instanceof DayPilot.Event) { + e.commit(); + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + var index = DayPilot.indexOf(calendar.events.list, target.data); + calendar.events.list.splice(index, 1, e); + } + } + + calendar.update(); + calendar._angular.notify(); + }; + + this.events.remove = function(e) { + var data; + if (e instanceof DayPilot.Event) { + data = e.data; + } + else if (typeof e === "object") { + var target = calendar.events.find(e.id); + if (target) { + data = target.data; + } + } + else if (typeof e === "string" || typeof e === "number") { + var target = calendar.events.find(e); + if (target) { + data = target.data; + } + } + + var index = DayPilot.indexOf(calendar.events.list, data); + calendar.events.list.splice(index, 1); + calendar.update(); + calendar._angular.notify(); + }; + + this.events.load = function(url, success, error) { + var onError = function (args) { + var largs = {}; + largs.exception = args.exception; + largs.request = args.request; + + if (typeof error === 'function') { + error(largs); + } + }; + + var onSuccess = function (args) { + var r = args.request; + var data; + + // it's supposed to be JSON + try { + data = JSON.parse(r.responseText); + } + catch (e) { + var fargs = {}; + fargs.exception = e; + onError(fargs); + return; + } + + if (DayPilot.isArray(data)) { + var sargs = {}; + sargs.preventDefault = function () { + this.preventDefault.value = true; + }; + sargs.data = data; + if (typeof success === "function") { + success(sargs); + } + + if (sargs.preventDefault.value) { + return; + } + + calendar.events.list = data; + if (calendar._initialized) { + calendar.update(); + } + } + }; + + var usePost = calendar.eventsLoadMethod && calendar.eventsLoadMethod.toUpperCase() === "POST"; + + if (usePost) { + DayPilot.Http.ajax({ + "method": "POST", + "data": {"start": calendar.visibleStart().toString(), "end": calendar.visibleEnd().toString()}, + "url": url, + "success": onSuccess, + "error": onError + }); + } + else { + var fullUrl = url; + var queryString = "start=" + calendar.visibleStart().toString() + "&end=" + calendar.visibleEnd().toString(); + if (fullUrl.indexOf("?") > -1) { + fullUrl += "&" + queryString; + } + else { + fullUrl += "?" + queryString; + } + + DayPilot.Http.ajax({ + "method": "GET", + "url": fullUrl, + "success": onSuccess, + "error": onError + }); + } + }; + + this.update = function(options) { + + calendar._loadOptions(options); + + if (!this._initialized) { + return; + } + + if (calendar._disposed) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Month instance that has been disposed."); + } + + if (!this.cells) { + return; + } + + var full = true; + + calendar._deleteEvents(); + calendar._prepareRows(); + calendar._loadEvents(); + + if (full) { + calendar._clearTable(); + calendar._drawTable(); + } + calendar._updateHeight(); + calendar._show(); + calendar._drawEvents(); + + if (this.visible) { + this.show(); + } + else { + this.hide(); + } + }; + + this._specialHandling = null; + this._loadOptions = function(options) { + if (!options) { + return; + } + var specialHandling = { + "events": { + "preInit": function() { + var events = this.data || []; + if (DayPilot.isArray(events.list)) { + calendar.events.list = events.list; + } + else { + calendar.events.list = events; + } + } + } + }; + this._specialHandling = specialHandling; + + for (var name in options) { + if (specialHandling[name]) { + var item = specialHandling[name]; + item.data = options[name]; + if (item.preInit) { + item.preInit(); + } + } + else { + calendar[name] = options[name]; + } + } + + }; + + this._postInit = function() { + var specialHandling = this._specialHandling; + for (var name in specialHandling) { + var item = specialHandling[name]; + if (item.postInit) { + item.postInit(); + } + } + }; + + this._cache = {}; + this._cache.events = []; + + this._doBeforeEventRender = function(i) { + var cache = this._cache.events; + var data = this.events.list[i]; + var evc = {}; + + // make a copy + for (var name in data) { + evc[name] = data[name]; + } + + if (typeof this.onBeforeEventRender === 'function') { + var args = {}; + args.control = calendar; + args.data = evc; + this.onBeforeEventRender(args); + } + + cache[i] = evc; + + }; + + this._loadEvents = function() { + var events = this.events.list; + + if (!events) { + return; + } + + if (!DayPilot.isArray(events)) { + throw new DayPilot.Exception("DayPilot.Month.events.list expects an array object. You supplied: " + (typeof events)); + } + + if (typeof this.onBeforeEventRender === 'function') { + for (var i = 0; i < events.length; i++) { + this._doBeforeEventRender(i); + } + } + + // prepare rows and columns + for (var x = 0; x < events.length; x++) { + var data = events[x]; + + if (typeof data !== "object") { + throw new DayPilot.Exception("Event data item must be an object"); + } + if (!data.start) { + throw new DayPilot.Exception("Event data item must specify 'start' property"); + } + if (!data.end) { + throw new DayPilot.Exception("Event data item must specify 'end' property"); + } + + var start = new DayPilot.Date(data.start); + var end = new DayPilot.Date(data.end); + if (start.getTime() > end.getTime()) { // skip invalid events, zero duration allowed + continue; + } + for (var i = 0; i < this.rows.length; i++) { + var row = this.rows[i]; + var ep = new DayPilot.Event(data, this); + if (row.belongsHere(ep)) { + row.events.push(ep); + + if (typeof this.onBeforeEventRender === 'function') { + ep.cache = this._cache.events[x]; + } + } + } + } + + // arrange events into lines + for (var ri = 0; ri < this.rows.length; ri++) { + var row = this.rows[ri]; + row.events.sort(this._eventComparer); + + for (var ei = 0; ei < this.rows[ri].events.length; ei++) { + var ev = row.events[ei]; + var colStart = row.getStartColumn(ev); + var colWidth = row.getWidth(ev); + var line = row.putIntoLine(ev, colStart, colWidth, ri); + } + } + }; + + + this._deleteEvents = function() { + for (var i = 0; i < this.elements.events.length; i++) { + var e = this.elements.events[i]; + e.event = null; + e.click = null; + e.parentNode.removeChild(e); + } + + this.elements.events = []; + + }; + + this._drawEvents = function() { + //this.cache.events = {}; // reset DayPilotMonth.Event object cache + + this._drawEventsRows(); + }; + + this._drawEventsRows = function() { + this.elements.events = []; + + // draw events + for (var ri = 0; ri < this.rows.length; ri++) { + var row = this.rows[ri]; + + for (var li = 0; li < row.lines.length; li++) { + var line = row.lines[li]; + + for (var pi = 0; pi < line.length; pi++) { + this._drawEvent(line[pi]); + } + } + } + + }; + + this._eventComparer = function(a, b) { + if (!a || !b || !a.start || !b.start) { + return 0; // no sorting, invalid arguments + } + + var byStart = a.start().getTime() - b.start().getTime(); + if (byStart !== 0) { + return byStart; + } + + var byEnd = b.end().getTime() - a.end().getTime(); // desc + return byEnd; + }; + + this.drawShadow = function(x, y, line, width, offset, e) { + + if (!offset) { + offset = 0; + } + + var remains = width; + + this.shadow = {}; + this.shadow.list = []; + this.shadow.start = { x: x, y: y }; + this.shadow.width = width; + + // something before the first day + var hidden = y * 7 + x - offset; + if (hidden < 0) { + //document.title = hidden + ' ' + new Date(); + remains += hidden; + x = 0; + y = 0; + } + + var remainingOffset = offset; + while (remainingOffset >= 7) { + y--; + remainingOffset -= 7; + } + if (remainingOffset > x) { + var plus = 7 - this.getColCount(); + if (remainingOffset > (x + plus)) { + y--; + x = x + 7 - remainingOffset; + } + else { + remains = remains - remainingOffset + x; + x = 0; + } + } + else { + x -= remainingOffset; + } + + if (y < 0) { + y = 0; + x = 0; + } + + var cursor = null; + if (DayPilotMonth.resizingEvent) { + cursor = 'w-resize'; + } + else if (DayPilotMonth.movingEvent) { + cursor = "move"; + } + + this.nav.top.style.cursor = cursor; + + while (remains > 0 && y < this.rows.length) { + var drawNow = Math.min(this.getColCount() - x, remains); + var row = this.rows[y]; + + + var top = this.getRowTop(y); + var height = row.getHeight(); + + var shadow = document.createElement("div"); + shadow.setAttribute("unselectable", "on"); + shadow.style.position = 'absolute'; + shadow.style.left = (this.getCellWidth() * x) + '%'; + shadow.style.width = (this.getCellWidth() * drawNow) + '%'; + shadow.style.top = (top) + 'px'; + shadow.style.height = (height) + 'px'; + shadow.style.cursor = cursor; + shadow.classList.add(calendar._prefixCssClass("_shadow")); + + var inside = document.createElement("div"); + inside.setAttribute("unselectable", "on"); + shadow.appendChild(inside); + + inside.style.position = "absolute"; + inside.style.top = "0px"; + inside.style.right = "0px"; + inside.style.left = "0px"; + inside.style.bottom = "0px"; + inside.classList.add(calendar._prefixCssClass("_shadow_inner")); + + // inside.style.backgroundColor = "#aaaaaa"; + // inside.style.opacity = 0.5; + // inside.style.filter = "alpha(opacity=50)"; + //inside.style.border = '2px solid #aaaaaa'; + /* + if (e) { + inside.style.overflow = 'hidden'; + inside.style.fontSize = this.eventFontSize; + inside.style.fontFamily = this.eventFontFamily; + inside.style.color = this.eventFontColor; + inside.innerHTML = e.client.html(); + } + */ + + this.nav.top.appendChild(shadow); + this.shadow.list.push(shadow); + + remains -= (drawNow + 7 - this.getColCount()); + x = 0; + y++; + } + + }; + + this.clearShadow = function() { + if (this.shadow) { + for (var i = 0; i < this.shadow.list.length; i++) { + this.nav.top.removeChild(this.shadow.list[i]); + } + this.shadow = null; + this.nav.top.style.cursor = ''; + } + }; + + this.getEventTop = function(row, line) { + var top = this.headerHeight; + for (var i = 0; i < row; i++) { + top += this.rows[i].getHeight(); + } + top += this.cellHeaderHeight; // space on top + top += line * this.lineHeight(); + return top; + }; + + this.getDateFromCell = function(x, y) { + //return DayPilot.Date.addDays(this.firstDate, y * 7 + x); + return this.firstDate.addDays(y * 7 + x); + }; + + this._drawEvent = function(e) { + /* + + supported properties: + * cssClass + * backColor + * borderColor + * barColor + * barHidden + * fontColor + * html + * toolTip + * + * clickEnabled + */ + + var data = e.cache || e.data; + + //var ev = eventPart.event; + var row = e.part.row; + var line = e.part.line; + var colStart = e.part.colStart; + var colWidth = e.part.colWidth; + + var left = this.getCellWidth() * (colStart); + var width = this.getCellWidth() * (colWidth); + var top = this.getEventTop(row, line); + + var div = document.createElement("div"); + div.setAttribute("unselectable", "on"); + div.style.height = this.eventHeight + 'px'; + div.className = this._prefixCssClass("_event"); + + if (data.cssClass) { + DayPilot.Util.addClass(div, data.cssClass); + } + + if (!e.part.startsHere) { + DayPilot.Util.addClass(div, this._prefixCssClass("_event_continueleft")); + } + + if (!e.part.endsHere) { + DayPilot.Util.addClass(div, this._prefixCssClass("_event_continueright")); + } + + div.event = e; + + div.style.width = width + '%'; + div.style.position = 'absolute'; + div.style.left = left + '%'; + div.style.top = top + 'px'; // plus space on top + + if (this.showToolTip && e.client.toolTip()) { + div.title = e.client.toolTip(); + } + + div.onclick = calendar._eventClickDispatch; + div.oncontextmenu = calendar._onEventContextMenu; + div.onmousedown = function(ev) { + ev = ev || window.event; + var button = ev.which || ev.button; + + ev.cancelBubble = true; + if (ev.stopPropagation) { + ev.stopPropagation(); + } + + if (button === 1) { + + DayPilotMonth.movingEvent = null; + if (this.style.cursor === 'w-resize' || this.style.cursor === 'e-resize') { + var resizing = {}; + resizing.start = {}; + resizing.start.x = colStart; + resizing.start.y = row; + resizing.event = div.event; + resizing.width = DayPilot.DateUtil.daysSpan(resizing.event.start(), resizing.event.end()) + 1; + resizing.direction = this.style.cursor; + DayPilotMonth.resizingEvent = resizing; + } + else if (this.style.cursor === 'move' || e.client.moveEnabled()) { + calendar.clearShadow(); + + var coords = DayPilot.mo3(calendar.nav.top, ev); + if (!coords) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + + var hidden = DayPilot.DateUtil.daysDiff(e.start(), calendar.rows[row].start); + var offset = (cell.y * 7 + cell.x) - (row * 7 + colStart); + if (hidden) { + offset += hidden; + } + + var moving = {}; + moving.start = {}; + moving.start.x = colStart; + moving.start.y = row; + moving.start.line = line; + moving.offset = calendar.eventMoveToPosition ? 0 : offset; + moving.colWidth = colWidth; + moving.event = div.event; + moving.coords = coords; + DayPilotMonth.movingEvent = moving; + + } + + } + }; + + div.onmousemove = function(ev) { + if (typeof (DayPilotMonth) === 'undefined') { + return; + } + + if (DayPilotMonth.movingEvent || DayPilotMonth.resizingEvent) { + return; + } + + // position + var offset = DayPilot.mo3(div, ev); + if (!offset) { + return; + } + + if (div.deleteIcon) { + div.deleteIcon.style.display = ""; + } + + var resizeMargin = 6; + + if (offset.x <= resizeMargin && e.client.resizeEnabled()) { + if (e.part.startsHere) { + div.style.cursor = "w-resize"; + div.dpBorder = 'left'; + } + else { + div.style.cursor = 'not-allowed'; + } + } + else if (div.clientWidth - offset.x <= resizeMargin && e.client.resizeEnabled()) { + if (e.part.endsHere) { + div.style.cursor = "e-resize"; + div.dpBorder = 'right'; + } + else { + div.style.cursor = 'not-allowed'; + } + } + else if (e.client.clickEnabled()) { + div.style.cursor = "pointer"; + } + else { + div.style.cursor = 'default'; + } + + }; + + div.onmouseleave = function(ev) { + if (div.deleteIcon) { + div.deleteIcon.style.display = "none"; + } + div.style.cursor = ''; + }; + + div.onmouseenter = function(ev) { + if (div.deleteIcon) { + div.deleteIcon.style.display = ""; + } + }; + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.className = this._prefixCssClass("_event_inner"); + + if (data.borderColor === "darker" && data.backColor) { + inner.style.borderColor = DayPilot.ColorUtil.darker(data.backColor, 2); + } + else { + inner.style.borderColor = data.borderColor; + } + + if (data.backColor) { + inner.style.background = data.backColor; + } + + if (data.fontColor) { + inner.style.color = data.fontColor; + } + + + inner.innerHTML = e.client.html(); + + div.appendChild(inner); + + if (e.client.barVisible()) { + + var bar = document.createElement("div"); + bar.setAttribute("unselectable", "on"); + bar.className = this._prefixCssClass("_event_bar"); + bar.style.position = "absolute"; + + var barInner = document.createElement("div"); + barInner.setAttribute("unselectable", "on"); + barInner.className = this._prefixCssClass("_event_bar_inner"); + barInner.style.top = "0%"; + barInner.style.height = "100%"; + + if (data.barColor) { + barInner.style.backgroundColor = data.barColor; + } + + bar.appendChild(barInner); + div.appendChild(bar); + } + + + if (e.client.deleteEnabled()) { + var dheight = 18; + var dwidth = 18; + var dtop = Math.floor(calendar.eventHeight / 2 - dheight / 2); + + var del = document.createElement("div"); + del.style.position = "absolute"; + del.style.right = "2px"; + del.style.top = dtop + "px"; + del.style.width = dwidth + "px"; + del.style.height = dheight + "px"; + del.className = calendar._prefixCssClass("_event_delete"); + del.onmousedown = function(ev) { + ev.stopPropagation(); + }; + del.onclick = function(ev) { + ev.stopPropagation(); + var e = this.parentNode.event; + if (e) { + calendar._eventDeleteDispatch(e); + } + }; + del.style.display = "none"; + div.deleteIcon = del; + div.appendChild(del); + } + + // areas + var areas = data.areas ? DayPilot.Areas.copy(data.areas) : []; + DayPilot.Areas.attach(div, e, {"areas": areas}); + + if (typeof calendar.onAfterEventRender === 'function') { + var args = {}; + args.e = div.event; + args.div = div; + + calendar.onAfterEventRender(args); + } + + this.elements.events.push(div); + + this.nav.events.appendChild(div); + }; + + + // returns DayPilot.Date object + this.lastVisibleDayOfMonth = function() { + return this.startDate.lastDayOfMonth(); + }; + + this._prepareRows = function() { + + if (typeof this.startDate === 'string') { + this.startDate = new DayPilot.Date(this.startDate); + } + this.startDate = this.startDate.firstDayOfMonth(); + + this.firstDate = this.startDate.firstDayOfWeek(this.getWeekStart()); + + var firstDayOfMonth = this.startDate; + + var rowCount; + + var lastVisibleDayOfMonth = this.lastVisibleDayOfMonth(); + var count = DayPilot.DateUtil.daysDiff(this.firstDate, lastVisibleDayOfMonth) + 1; + rowCount = Math.ceil(count / 7); + + this.days = rowCount * 7; + + this.rows = []; + for (var x = 0; x < rowCount; x++) { + var r = {}; + r.start = this.firstDate.addDays( x * 7); // start point + r.end = r.start.addDays(this.getColCount()); // end point + r.events = []; // collection of events + r.lines = []; // collection of lines + r.index = x; // row index + r.minHeight = this.cellHeight; // default, can be extended during events loading + r.calendar = this; + + r.belongsHere = function(ev) { + if (ev.end().getTime() === ev.start().getTime() && ev.start().getTime() === this.start.getTime()) { + return true; + } + return !(ev.end().getTime() <= this.start.getTime() || ev.start().getTime() >= this.end.getTime()); + }; + + r.getPartStart = function(ev) { + return DayPilot.DateUtil.max(this.start, ev.start()); + }; + + r.getPartEnd = function(ev) { + return DayPilot.DateUtil.min(this.end, ev.end()); + }; + + r.getStartColumn = function(ev) { + var partStart = this.getPartStart(ev); + return DayPilot.DateUtil.daysDiff(this.start, partStart); + }; + + r.getWidth = function(ev) { + return DayPilot.DateUtil.daysSpan(this.getPartStart(ev), this.getPartEnd(ev)) + 1; + }; + + r.putIntoLine = function(ev, colStart, colWidth, row) { + var thisRow = this; + + for (var i = 0; i < this.lines.length; i++) { + var line = this.lines[i]; + if (line.isFree(colStart, colWidth)) { + line.addEvent(ev, colStart, colWidth, row, i); + return i; + } + } + + var line = []; + line.isFree = function(colStart, colWidth) { + var free = true; + + for (var i = 0; i < this.length; i++) { + if (!(colStart + colWidth - 1 < this[i].part.colStart || colStart > this[i].part.colStart + this[i].part.colWidth - 1)) { + free = false; + } + } + + return free; + }; + + line.addEvent = function(ep, colStart, colWidth, row, index) { + //var eventPart = {}; + //eventPart.event = ev; + ep.part.colStart = colStart; + ep.part.colWidth = colWidth; + ep.part.row = row; + ep.part.line = index; + ep.part.startsHere = thisRow.start.getTime() <= ep.start().getTime(); + //if (confirm('r.start: ' + thisRow.start + ' ev.Start: ' + ev.Start)) thisRow = null; + ep.part.endsHere = thisRow.end.getTime() >= ep.end().getTime(); + + this.push(ep); + }; + + line.addEvent(ev, colStart, colWidth, row, this.lines.length); + + this.lines.push(line); + + return this.lines.length - 1; + }; + + r.getStart = function() { + var start = 0; + for (var i = 0; i < calendar.rows.length && i < this.index; i++) { + start += calendar.rows[i].getHeight(); + } + }; + + r.getHeight = function() { + return Math.max(this.lines.length * calendar.lineHeight() + calendar.cellHeaderHeight + calendar.cellMarginBottom, this.calendar.cellHeight); + }; + + this.rows.push(r); + } + + //this.endDate = DayPilot.Date.addDays(this.firstDate, rowCount * 7); + this.endDate = this.firstDate.addDays(rowCount * 7); + }; + + this.visibleStart = function() { + return calendar.firstDate; + }; + + this.visibleEnd = function() { + return calendar.endDate; + }; + + this.getHeight = function() { + var height = this.headerHeight; + for (var i = 0; i < this.rows.length; i++) { + height += this.rows[i].getHeight(); + } + return height; + }; + + this.getWidth = function(start, end) { + var diff = (end.y * 7 + end.x) - (start.y * 7 + start.x); + return diff + 1; + }; + + this.getMinCoords = function(first, second) { + if ((first.y * 7 + first.x) < (second.y * 7 + second.x)) { + return first; + } + else { + return second; + } + }; + + this._prefixCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + if (prefix) { + return prefix + part; + } + else { + return ""; + } + }; + + this._drawTop = function() { + var relative = this.nav.top; + //this.nav.top = relative; + relative.setAttribute("unselectable", "on"); + relative.style.MozUserSelect = 'none'; + relative.style.KhtmlUserSelect = 'none'; + relative.style.WebkitUserSelect = 'none'; + relative.style.position = 'relative'; + if (this.width) { + relative.style.width = this.width; + } + relative.style.height = this.getHeight() + 'px'; + relative.onselectstart = function(e) { return false; }; // prevent text cursor in Chrome during drag&drop + + + if (this.hideUntilInit) { + relative.style.visibility = 'hidden'; + } + + if (!this.visible) { + relative.style.display = "none"; + } + + relative.className = this._prefixCssClass("_main"); + + var cells = document.createElement("div"); + this.nav.cells = cells; + cells.style.position = "absolute"; + cells.style.left = "0px"; + cells.style.right = "0px"; + cells.setAttribute("unselectable", "on"); + relative.appendChild(cells); + + var events = document.createElement("div"); + this.nav.events = events; + events.style.position = "absolute"; + events.style.left = "0px"; + events.style.right = "0px"; + events.setAttribute("unselectable", "on"); + relative.appendChild(events); + + relative.onmousemove = function(ev) { + + if (DayPilotMonth.resizingEvent) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + if (!coords) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + calendar.clearShadow(); + var resizing = DayPilotMonth.resizingEvent; + + var original = resizing.start; + var width, start; + + if (resizing.direction === 'w-resize') { + start = cell; + + var endDate = resizing.event.end(); + //if (DayPilot.Date.getDate(endDate).getTime() === endDate.getTime()) { + if (endDate.getDatePart() === endDate) { + endDate = endDate.addDays(-1); + } + + var end = calendar.getCellFromDate(endDate); + width = calendar.getWidth(cell, end); + } + else { + start = calendar.getCellFromDate(resizing.event.start()); + width = calendar.getWidth(start, cell); + } + + if (width < 1) { + width = 1; + } + + calendar.drawShadow(start.x, start.y, 0, width); + + } + else if (DayPilotMonth.movingEvent) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + if (!coords) { + return; + } + + // not actually moved, Chrome bug + if (coords.x === DayPilotMonth.movingEvent.coords.x && coords.y === DayPilotMonth.movingEvent.coords.y) { + return; + } + + var minDistance = 3; + var distance = Math.abs(coords.x - DayPilotMonth.movingEvent.coords.x) + Math.abs(coords.y - DayPilotMonth.movingEvent.coords.y); + if (distance <= minDistance) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + + calendar.clearShadow(); + + var event = DayPilotMonth.movingEvent.event; + var offset = DayPilotMonth.movingEvent.offset; + var width = calendar.cellMode ? 1 : DayPilot.DateUtil.daysSpan(event.start(), event.end()) + 1; + + if (width < 1) { + width = 1; + } + calendar.drawShadow(cell.x, cell.y, 0, width, offset, event); + } + else if (DayPilotMonth.timeRangeSelecting) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + if (!coords) { + return; + } + + var cell = calendar.getCellBelowPoint(coords.x, coords.y); + + calendar.clearShadow(); + + var start = DayPilotMonth.timeRangeSelecting; + + var startIndex = start.y * 7 + start.x; + var cellIndex = cell.y * 7 + cell.x; + + var width = Math.abs(cellIndex - startIndex) + 1; + + if (width < 1) { + width = 1; + } + + var shadowStart = startIndex < cellIndex ? start : cell; + + DayPilotMonth.timeRangeSelecting.from = { x: shadowStart.x, y: shadowStart.y }; + DayPilotMonth.timeRangeSelecting.width = width; + DayPilotMonth.timeRangeSelecting.moved = true; + + calendar.drawShadow(shadowStart.x, shadowStart.y, 0, width, 0, null); + + } + + }; + + //this.nav.top.appendChild(this.vsph); + }; + + this._updateHeight = function() { + this.nav.top.style.height = this.getHeight() + 'px'; + + for (var x = 0; x < this.cells.length; x++) { + for (var y = 0; y < this.cells[x].length; y++) { + this.cells[x][y].style.top = this.getRowTop(y) + 'px'; + this.cells[x][y].style.height = this.rows[y].getHeight() + 'px'; + } + } + }; + + this.getCellBelowPoint = function(x, y) { + var columnWidth = Math.floor(this.nav.top.clientWidth / this.getColCount()); + var column = Math.min(Math.floor(x / columnWidth), this.getColCount() - 1); + + var row = null; + + var height = this.headerHeight; + var relativeY = 0; + for (var i = 0; i < this.rows.length; i++) { + var baseHeight = height; + height += this.rows[i].getHeight(); + if (y < height) { + relativeY = y - baseHeight; + row = i; + break; + } + } + if (row === null) { + row = this.rows.length - 1; // might be a pixel below the last line + } + + var cell = {}; + cell.x = column; + cell.y = row; + cell.relativeY = relativeY; + + return cell; + }; + + this.getCellFromDate = function(date) { + var width = DayPilot.DateUtil.daysDiff(this.firstDate, date); + var cell = { x: 0, y: 0 }; + while (width >= 7) { + cell.y++; + width -= 7; + } + cell.x = width; + return cell; + }; + + this._drawTable = function() { + + var table = document.createElement("div"); + table.oncontextmenu = function() { return false; }; + this.nav.cells.appendChild(table); + + this.cells = []; + + for (var x = 0; x < this.getColCount(); x++) { + + this.cells[x] = []; + var headerProperties = null; + + var header = document.createElement("div"); + header.setAttribute("unselectable", "on"); + header.style.position = 'absolute'; + + header.style.left = (this.getCellWidth() * x) + '%'; + header.style.width = (this.getCellWidth()) + '%'; + header.style.top = '0px'; + header.style.height = (this.headerHeight) + 'px'; + + var dayIndex = x + this.getWeekStart(); + if (dayIndex > 6) { + dayIndex -= 7; + } + + header.className = this._prefixCssClass("_header"); + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + inner.innerHTML = resolved.locale().dayNames[dayIndex]; + + header.appendChild(inner); + + inner.style.position = "absolute"; + inner.style.top = "0px"; + inner.style.bottom = "0px"; + inner.style.left = "0px"; + inner.style.right = "0px"; + inner.className = this._prefixCssClass("_header_inner"); + + inner.innerHTML = resolved.locale().dayNames[dayIndex]; + + table.appendChild(header); + + for (var y = 0; y < this.rows.length; y++) { + this._drawCell(x, y, table); + } + + } + + }; + + this._clearTable = function() { + + // clear event handlers + for (var x = 0; x < this.cells.length; x++) { + for (var y = 0; y < this.cells[x].length; y++) { + this.cells[x][y].onclick = null; + } + } + + this.nav.cells.innerHTML = ''; + + }; + + this._api2 = function() { + return calendar.api === 2; + }; + this._drawCell = function(x, y, table) { + + var row = this.rows[y]; + var d = this.firstDate.addDays(y * 7 + x); + + var date = d.getDay(); + var headerHtml = null; + if (date === 1) { + headerHtml = resolved.locale().monthNames[d.getMonth()] + ' ' + date; + } + else { + headerHtml = "" + date; + } + var business = !calendar.isWeekend(d); + + var args = {}; + args.control = calendar; + args.cell = {}; + args.cell.start = d; + args.cell.end = d.addDays(1); + args.cell.properties = { + "headerHtml": headerHtml, + "backColor": null, + "business": business, + "html": null + }; + if (typeof calendar.onBeforeCellRender === "function") { + calendar.onBeforeCellRender(args); + } + + var props = args.cell.properties; + + var cell = document.createElement("div"); + cell.setAttribute("unselectable", "on"); + cell.style.position = 'absolute'; + cell.style.cursor = 'default'; + cell.style.left = (this.getCellWidth() * x) + '%'; + cell.style.width = (this.getCellWidth()) + '%'; + cell.style.top = (this.getRowTop(y)) + 'px'; + cell.style.height = (row.getHeight()) + 'px'; + cell.className = this._prefixCssClass("_cell"); + + if (props.business) { + var business = this._prefixCssClass("_cell_business"); + DayPilot.Util.addClass(cell, business); + } + + var previousMonth = this.startDate.addMonths(-1).getMonth(); + var nextMonth = this.startDate.addMonths(1).getMonth(); + + var thisMonth = this.startDate.getMonth(); + + var inner = document.createElement("div"); + inner.setAttribute("unselectable", "on"); + cell.appendChild(inner); + + inner.style.position = "absolute"; + inner.style.left = "0px"; + inner.style.right = "0px"; + inner.style.top = "0px"; + inner.style.bottom = "0px"; + inner.className = this._prefixCssClass("_cell_inner"); + + if (props.backColor) { + inner.style.backgroundColor = args.cell.properties.backColor; + } + + cell.onmousedown = function(e) { + if (calendar.timeRangeSelectedHandling !== 'Disabled') { + calendar.clearShadow(); + DayPilotMonth.timeRangeSelecting = { "root": calendar, "x": x, "y": y, "from": { x: x, y: y }, "width": 1 }; + } + }; + + cell.onclick = function() { + + var single = function(d) { + var start = new DayPilot.Date(d); + var end = start.addDays(1); + calendar._timeRangeSelectedDispatch(start, end); + }; + + if (calendar.timeRangeSelectedHandling !== 'Disabled') { + single(d); + return; + } + + }; + + var day = document.createElement("div"); + day.setAttribute("unselectable", "on"); + day.style.height = this.cellHeaderHeight + "px"; + day.className = this._prefixCssClass("_cell_header"); + + day.onclick = function(ev) { + + if (calendar.cellHeaderClickHandling !== "Enabled") { + return; + } + + ev.stopPropagation(); + + var args = {}; + args.control = calendar; + args.start = d; + args.end = d.addDays(1); + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onCellHeaderClick === "function") { + calendar.onCellHeaderClick(args); + if (args.preventDefault.value) { + return; + } + } + + if (typeof calendar.onCellHeaderClicked === "function") { + calendar.onCellHeaderClicked(args); + } + + }; + + day.innerHTML = props.headerHtml; + + inner.appendChild(day); + + if (props.html) { + var html = document.createElement("div"); + html.style.height = (row.getHeight() - this.cellHeaderHeight) + 'px'; + html.style.overflow = 'hidden'; + html.innerHTML = props.html; + inner.appendChild(html); + } + + this.cells[x][y] = cell; + + table.appendChild(cell); + }; + + this.getWeekStart = function() { + if (calendar.weekStarts === 'Auto') { + var locale = resolved.locale(); + if (locale) { + return locale.weekStarts; + } + else { + return 0; // Sunday + } + } + else { + return calendar.weekStarts || 0; + } + return resolved.locale().weekStarts; + }; + + this.getColCount = function() { + return 7; + }; + + this.getCellWidth = function() { + return 14.285; + }; + + this.getRowTop = function(index) { + var top = this.headerHeight; + for (var i = 0; i < index; i++) { + top += this.rows[i].getHeight(); + } + return top; + }; + + this._callBack2 = function(action, data, parameters) { + + var envelope = {}; + + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + DayPilot.JSON.stringify(envelope); + + if (this.backendUrl) { + DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this.ajaxError); + } + }; + + this._callBackResponse = function(response) { + calendar._updateView(response.responseText); + }; + + this._getCallBackHeader = function() { + var h = {}; + h.control = "dpm"; + h.id = this.id; + h.v = this.v; + + h.visibleStart = new DayPilot.Date(this.firstDate); + h.visibleEnd = h.visibleStart.addDays(this.days); + + h.startDate = calendar.startDate; + // h.headerBackColor = this.headerBackColor; + // h.backColor = this.backColor; + // h.nonBusinessBackColor = this.nonBusinessBackColor; + h.timeFormat = this.timeFormat; + h.weekStarts = this.weekStarts; + + return h; + }; + + this.eventClickCallBack = function(e, data) { + this._callBack2('EventClick', data, e); + }; + + this._eventClickDispatch = function(e) { + + DayPilotMonth.movingEvent = null; + DayPilotMonth.resizingEvent = null; + + var div = this; + + var e = e || window.event; + var ctrlKey = e.ctrlKey; + + e.cancelBubble = true; + if (e.stopPropagation) { + e.stopPropagation(); + } + + calendar.eventClickSingle(div, e); + }; + + + this.eventClickSingle = function(div, ev) { + var e = div.event; + if (!e) { + return; + } + if (!e.client.clickEnabled()) { + return; + } + + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.control = calendar; + args.div = div; + args.originalEvent = ev; + args.meta = ev.metaKey; + args.ctrl = ev.ctrlKey; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventClick === 'function') { + calendar._angular.apply(function() { + calendar.onEventClick(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventClickHandling) { + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(e); + } + } + break; } + + if (typeof calendar.onEventClicked === 'function') { + calendar._angular.apply(function() { + calendar.onEventClicked(args); + }); + } + } + else { + switch (calendar.eventClickHandling) { + case 'CallBack': + calendar.eventClickCallBack(e); + break; + case 'JavaScript': + calendar.onEventClick(e); + break; + } + } + }; + + this._onEventContextMenu = function() { + var e = this; + calendar._eventRightClickDispatch(e.event); + return false; + }; + + this._eventRightClickDispatch = function(e) { + + this.event = e; + + if (!e.client.rightClickEnabled()) { + return false; + } + + var args = {}; + args.e = e; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventRightClick === 'function') { + calendar.onEventRightClick(args); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventRightClickHandling) { + case 'ContextMenu': + var menu = e.client.contextMenu(); + if (menu) { + menu.show(e); + } + else { + if (calendar.contextMenu) { + calendar.contextMenu.show(this.event); + } + } + break; + } + + if (typeof calendar.onEventRightClicked === 'function') { + calendar.onEventRightClicked(args); + } + + + return false; + }; + + + this._eventDeleteDispatch = function (e) { + if (calendar._api2()) { + + var args = {}; + args.e = e; + args.control = calendar; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventDelete === 'function') { + calendar._angular.apply(function() { + calendar.onEventDelete(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventDeleteHandling) { + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'Update': + calendar.events.remove(e); + break; + } + + if (typeof calendar.onEventDeleted === 'function') { + calendar._angular.apply(function() { + calendar.onEventDeleted(args); + }); + } + } + else { + switch (calendar.eventDeleteHandling) { + case 'PostBack': + calendar.eventDeletePostBack(e); + break; + case 'CallBack': + calendar.eventDeleteCallBack(e); + break; + case 'JavaScript': + calendar.onEventDelete(e); + break; + } + } + + }; + + this.eventDeleteCallBack = function(e, data) { + this._callBack2('EventDelete', data, e); + }; + + this.eventDeletePostBack = function(e, data) { + this._postBack2('EventDelete', data, e); + }; + + this.eventMoveCallBack = function(e, newStart, newEnd, data, position) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + params.position = position; + + this._callBack2('EventMove', data, params); + }; + + this._eventMoveDispatch = function(e, x, y, offset, ev, position) { + + var startOffset = e.start().getTimePart(); + + var endDate = e.end().getDatePart(); + if (endDate.getTime() !== e.end().getTime()) { + endDate = endDate.addDays(1); + } + var endOffset = DayPilot.DateUtil.diff(e.end(), endDate); + + var boxStart = this.getDateFromCell(x, y); + boxStart = boxStart.addDays(-offset); + var width = DayPilot.DateUtil.daysSpan(e.start(), e.end()) + 1; + + var boxEnd = boxStart.addDays(width); + + var newStart = boxStart.addTime(startOffset); + var newEnd = boxEnd.addTime(endOffset); + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.control = calendar; + args.newStart = newStart; + args.newEnd = newEnd; + args.ctrl = ev.ctrlKey; + args.shift = ev.shiftKey; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventMove === 'function') { + calendar._angular.apply(function() { + calendar.onEventMove(args); + }); + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventMoveHandling) { + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventMoved === 'function') { + calendar._angular.apply(function() { + calendar.onEventMoved(args); + }); + } + } + else { + switch (calendar.eventMoveHandling) { + case 'CallBack': + calendar.eventMoveCallBack(e, newStart, newEnd); + break; + case 'JavaScript': + calendar.onEventMove(e, newStart, newEnd); + break; + } + } + }; + + this.eventResizeCallBack = function(e, newStart, newEnd, data) { + if (!newStart) + throw 'newStart is null'; + if (!newEnd) + throw 'newEnd is null'; + + var params = {}; + params.e = e; + params.newStart = newStart; + params.newEnd = newEnd; + + this._callBack2('EventResize', data, params); + }; + + this._eventResizeDispatch = function(e, start, width) { + var startOffset = e.start().getTimePart(); + + var endDate = e.end().getDatePart(); + if (endDate.getTime() !== e.end().getTime()) { + endDate = endDate.addDays(1); + } + var endOffset = DayPilot.DateUtil.diff(e.end(), endDate); + + var boxStart = this.getDateFromCell(start.x, start.y); + //var width = DayPilot.Date.daysSpan(e.start(), e.end()) + 1; + var boxEnd = boxStart.addDays(width); + + var newStart = boxStart.addTime(startOffset); + var newEnd = boxEnd.addTime(endOffset); + + if (calendar._api2()) { + // API v2 + var args = {}; + + args.e = e; + args.control = calendar; + args.newStart = newStart; + args.newEnd = newEnd; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onEventResize === 'function') { + calendar._angular.apply(function() { + calendar.onEventResize(args); + }); + + if (args.preventDefault.value) { + return; + } + } + + switch (calendar.eventResizeHandling) { + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'Update': + e.start(newStart); + e.end(newEnd); + calendar.events.update(e); + break; + } + + if (typeof calendar.onEventResized === 'function') { + calendar._angular.apply(function() { + calendar.onEventResized(args); + }); + } + } + else { + switch (calendar.eventResizeHandling) { + case 'CallBack': + calendar.eventResizeCallBack(e, newStart, newEnd); + break; + case 'JavaScript': + calendar.onEventResize(e, newStart, newEnd); + break; + } + } + + }; + + + this.timeRangeSelectedCallBack = function(start, end, data) { + + var range = {}; + range.start = start; + range.end = end; + + this._callBack2('TimeRangeSelected', data, range); + }; + + this._timeRangeSelectedDispatch = function(start, end) { + if (this._api2()) { + var args = {}; + args.control = calendar; + args.start = start; + args.end = end; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onTimeRangeSelect === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelect(args); + }); + + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (calendar.timeRangeSelectedHandling) { + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + } + + if (typeof calendar.onTimeRangeSelected === 'function') { + calendar._angular.apply(function() { + calendar.onTimeRangeSelected(args); + }); + } + } + else { + switch (calendar.timeRangeSelectedHandling) { + case 'CallBack': + calendar.timeRangeSelectedCallBack(start, end); + break; + case 'JavaScript': + calendar.onTimeRangeSelected(start, end); + break; + } + } + }; + + this._angular = {}; + this._angular.scope = null; + this._angular.notify = function() { + if (calendar._angular.scope) { + calendar._angular.scope["$apply"](); + } + }; + this._angular.apply = function(f) { + f(); + + /* + if (calendar.angularAutoApply && calendar._angular.scope) { + calendar._angular.scope["$apply"](f); + } + else { + f(); + }*/ + }; + + this.clearSelection = function() { + calendar.clearShadow(); + }; + + this.commandCallBack = function(command, data) { + + var params = {}; + params.command = command; + + this._callBack2('Command', data, params); + }; + + this.isWeekend = function(date) { + date = new DayPilot.Date(date); + + var sunday = 0; + var saturday = 6; + + if (date.dayOfWeek() === sunday) { + return true; + } + if (date.dayOfWeek() === saturday) { + return true; + } + return false; + }; + + this._resolved = {}; + this._resolved.locale = function() { + var found = DayPilot.Locale.find(calendar.locale); + if (!found) { + return DayPilot.Locale.US; + } + return found; + }; + + this._resolved._xssProtectionEnabled = function() { + return calendar.xssProtection !== "Disabled"; + }; + + + var resolved = this._resolved; + + this.debug = function(msg, append) { + if (!this.debuggingEnabled) { + return; + } + + if (!calendar.debugMessages) { + calendar.debugMessages = []; + } + calendar.debugMessages.push(msg); + + if (typeof console !== 'undefined') { + console.log(msg); + } + }; + + this.dispose = function() { + var c = calendar; + + if (c._disposed) { + return; + } + c._disposed = true; + + c._deleteEvents(); + + c.nav.top.removeAttribute("style"); + c.nav.top.removeAttribute("class"); + c.nav.top.innerHTML = ''; + c.nav.top.dp = null; + + c.nav.top.onmousemove = null; + c.nav.top = null; + + }; + + this.disposed = function() { + return this._disposed; + }; + + this._registerGlobalHandlers = function() { + if (!DayPilotMonth.globalHandlers) { + DayPilotMonth.globalHandlers = true; + DayPilot.re(document, 'mouseup', DayPilotMonth.gMouseUp); + } + }; + + this.loadFromServer = function() { + // make sure it has a place to ask + if (this.backendUrl || typeof WebForm_DoCallback === 'function') { + return (typeof calendar.events.list === 'undefined') || (!calendar.events.list); + } + else { + return false; + } + + }; + + this._show = function() { + if (this.nav.top.style.visibility === 'hidden') { + this.nav.top.style.visibility = 'visible'; + } + }; + + this.show = function() { + calendar.visible = true; + calendar.nav.top.style.display = ''; + }; + + this.hide = function() { + calendar.visible = false; + calendar.nav.top.style.display = 'none'; + }; + + this._loadTop = function() { + if (this.id && this.id.tagName) { + this.nav.top = this.id; + } + else if (typeof this.id === "string") { + this.nav.top = document.getElementById(this.id); + if (!this.nav.top) { + throw "DayPilot.Month: The placeholder element not found: '" + id + "'."; + } + } + else { + throw "DayPilot.Month() constructor requires the target element or its ID as a parameter"; + } + }; + + this._initShort = function() { + + this._prepareRows(); + this._drawTop(); + this._drawTable(); + this._registerGlobalHandlers(); + this._callBack2('Init'); // load events + }; + + this._xssTextHtml = function(text, html) { + + if (calendar._resolved._xssProtectionEnabled()) { + return DayPilot.Util.escapeTextHtml(text, html); + } + + if (!DayPilot.Util.isNullOrUndefined(html)) { + return html; + } + if (DayPilot.Util.isNullOrUndefined(text)) { + return ""; + } + return text; + }; + + this.internal = {}; + this.internal.loadOptions = this._loadOptions; + this.internal.xssTextHtml = calendar._xssTextHtml; + + this.init = function() { + this._loadTop(); + + var loadFromServer = this.loadFromServer(); + + if (loadFromServer) { + this._initShort(); + return; + } + + this._prepareRows(); + this._loadEvents(); + this._drawTop(); + this._drawTable(); + this._show(); + this._drawEvents(); + + this._registerGlobalHandlers(); + + this.fireAfterRenderDetached(null, false); + + this._initialized = true; + + return this; + }; + + this.Init = this.init; + + // API compatibility (common) + Object.defineProperty(this, 'durationBarVisible', { get: function() { return calendar.eventBarVisible; } }); + + this._loadOptions(options); + }; + + DayPilotMonth.gMouseUp = function(ev) { + + if (DayPilotMonth.movingEvent) { + var src = DayPilotMonth.movingEvent; + + if (!src.event) { + return; + } + if (!src.event.calendar) { + return; + } + if (!src.event.calendar.shadow) { + return; + } + if (!src.event.calendar.shadow.start) { + return; + } + + // load ref + var calendar = DayPilotMonth.movingEvent.event.calendar; + var e = DayPilotMonth.movingEvent.event; + var start = calendar.shadow.start; + var position = calendar.shadow.position; + var offset = DayPilotMonth.movingEvent.offset; + + // cleanup + calendar.clearShadow(); + DayPilotMonth.movingEvent = null; + + var ev = ev || window.event; + + // fire the event + calendar._eventMoveDispatch(e, start.x, start.y, offset, ev, position); + + ev.cancelBubble = true; + if (ev.stopPropagation) { + ev.stopPropagation(); + } + DayPilotMonth.movingEvent = null; + return false; + } + else if (DayPilotMonth.resizingEvent) { + var src = DayPilotMonth.resizingEvent; + + if (!src.event) { + return; + } + if (!src.event.calendar) { + return; + } + if (!src.event.calendar.shadow) { + return; + } + if (!src.event.calendar.shadow.start) { + return; + } + + // load ref + var calendar = DayPilotMonth.resizingEvent.event.calendar; + + var e = DayPilotMonth.resizingEvent.event; + var start = calendar.shadow.start; + var width = calendar.shadow.width; + + // cleanup + calendar.clearShadow(); + DayPilotMonth.resizingEvent = null; + + // fire the event + calendar._eventResizeDispatch(e, start, width); + + ev.cancelBubble = true; + DayPilotMonth.resizingEvent = null; + return false; + } + else if (DayPilotMonth.timeRangeSelecting) { + if (DayPilotMonth.timeRangeSelecting.moved) { + var sel = DayPilotMonth.timeRangeSelecting; + var calendar = sel.root; + + var start = new DayPilot.Date(calendar.getDateFromCell(sel.from.x, sel.from.y)); + var end = start.addDays(sel.width); + calendar._timeRangeSelectedDispatch(start, end); + + calendar.clearShadow(); + } + DayPilotMonth.timeRangeSelecting = null; + } + }; + + // publish the API + + // current + DayPilot.Month = DayPilotMonth.Month; + + // experimental jQuery bindings + if (typeof jQuery !== 'undefined') { + (function($) { + $.fn.daypilotMonth = function(options) { + var first = null; + var j = this.each(function() { + if (this.daypilot) { // already initialized + return; + }; + + var daypilot = new DayPilot.Month(this.id); + this.daypilot = daypilot; + for (name in options) { + daypilot[name] = options[name]; + } + daypilot.Init(); + if (!first) { + first = daypilot; + } + }); + if (this.length === 1) { + return first; + } + else { + return j; + } + }; + })(jQuery); + } + + (function registerAngularModule() { + + var app = DayPilot.am(); + + if (!app) { + return; + } + + app.directive("daypilotMonth", ['$parse', function($parse) { + return { + "restrict": "E", + "template": "
", + "replace": true, + "link": function (scope, element, attrs) { + + var calendar = new DayPilot.Month(element[0]); + calendar._angular.scope = scope; + calendar.init(); + + var oattr = attrs["id"]; + if (oattr) { + scope[oattr] = calendar; + } + + // save DayPilot.Calendar object in the specified variable + var pas = attrs["publishAs"]; + if (pas) { + var getter = $parse(pas); + var setter = getter.assign; + setter(scope, calendar); + } + + // bind event handlers from attributes starting with "on" + for (var name in attrs) { + if (name.indexOf("on") === 0) { // event handler + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + scope["$apply"](function() { + f(scope, {"args": args}); + }); + }; + })(name); + } + } + + var watch = scope["$watch"]; + var config = attrs["config"] || attrs["daypilotConfig"]; + var events = attrs["events"] || attrs["daypilotEvents"]; + + //var watch = scope["$watch"]; + + watch.call(scope, config, function (value) { + for (var name in value) { + calendar[name] = value[name]; + } + calendar.update(); + }, true); + + watch.call(scope, events, function(value) { + calendar.events.list = value; + calendar.update(); + }, true); + + } + }; + }]); + })(); + + + if (typeof Sys !== 'undefined' && Sys.Application && Sys.Application.notifyScriptLoaded) { + Sys.Application.notifyScriptLoaded(); + } + + +})(); diff --git a/static/src/js/src/daypilot-navigator.src.js b/static/src/js/src/daypilot-navigator.src.js new file mode 100644 index 0000000..c13bfc6 --- /dev/null +++ b/static/src/js/src/daypilot-navigator.src.js @@ -0,0 +1,1977 @@ +/* +Copyright © 2024 Annpoint, s.r.o. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------- + +NOTE: Requires the following acknowledgement (see also NOTICE): +This software includes DayPilot (https://www.daypilot.org). +*/ + +if (typeof DayPilot === 'undefined') { + var DayPilot = {}; +} + +if (typeof DayPilot.Global === 'undefined') { + DayPilot.Global = {}; +} + +(function() { + + if (typeof DayPilot.Navigator !== 'undefined' && DayPilot.Navigator.nav) { + return; + } + + var DayPilotNavigator = {}; + DayPilot.Navigator = function(id, options) { + this.v = '2024.3.539-lite'; + var calendar = this; + this.id = id; + this.api = 2; + this.isNavigator = true; + + this.autoFocusOnClick = true; + this.weekStarts = 'Auto'; // 0 = Sunday, 1 = Monday, ... 'Auto' = according to locale + this.selectMode = 'Day'; // day/week/month/none + this.titleHeight = 30; + this.dayHeaderHeight = 30; + this.bound = null; + this.cellWidth = 30; + this.cellHeight = 30; + this.cssClassPrefix = "navigator_default"; + this.freeHandSelectionEnabled = false; + this.selectionStart = new DayPilot.Date().getDatePart(); // today + this.selectionEnd = null; + this.selectionDay = null; + this.showMonths = 1; + this.skipMonths = 1; + this.command = "navigate"; + this.year = new DayPilot.Date().getYear(); + this.month = new DayPilot.Date().getMonth() + 1; + this.showWeekNumbers = false; + this.weekNumberAlgorithm = 'Auto'; + this.rowsPerMonth = 'Six'; // Six, Auto + this.orientation = "Vertical"; + this.locale = "en-us"; + this.rtl = false; + this.visible = true; + + this.timeRangeSelectedHandling = "Bind"; + this.visibleRangeChangedHandling = "Enabled"; + + this.onVisibleRangeChange = null; + this.onVisibleRangeChanged = null; + this.onTimeRangeSelect = null; + this.onTimeRangeSelected = null; + + this.nav = {}; + + this._cache = {}; + + this._prepare = function() { + + this.root.dp = this; + + this.root.className = this._prefixCssClass('_main'); + + if (this.orientation === "Horizontal") { + this.root.style.width = this.showMonths * (resolved.cellWidth() * 7 + this._weekNumberWidth()) + 'px'; + this.root.style.height = (this.cellHeight*6 + this.titleHeight + this.dayHeaderHeight) + 'px'; + } + else { + this.root.style.width = (resolved.cellWidth() * 7 + this._weekNumberWidth()) + 'px'; + } + //this.root.style.height = (this.showMonths*(this.cellHeight*6 + this.titleHeight + this.dayHeaderHeight)) + 'px'; + + if (this.rtl) { + this.root.style.direction = "rtl"; + } + + this.root.style.position = "relative"; + + if (!this.visible) { + this.root.style.display = "none"; + } + + var vsph = document.createElement("input"); + vsph.type = 'hidden'; + vsph.name = calendar.id + "_state"; + vsph.id = vsph.name; + //vsph.value = result.VsUpdate; + this.root.appendChild(vsph); + this.state = vsph; + + if (!this.startDate) { + this.startDate = DayPilot.Date.fromYearMonthDay(this.year, this.month); + } + else { // make sure it's the first day + this.startDate = new DayPilot.Date(this.startDate).firstDayOfMonth(); + } + + this.calendars = []; + this.selected = []; + this.months = []; + }; + + this._api2 = function() { + return calendar.api === 2; + }; + + this._clearTable = function() { + // TODO do something smarter here + this.root.innerHTML = ''; + }; + + this._prefixCssClass = function(part) { + var prefix = this.theme || this.cssClassPrefix; + if (prefix) { + return prefix + part; + } + else { + return ""; + } + }; + + this._addClass = function(object, name) { + var fullName = this._prefixCssClass("_" + name); + DayPilot.Util.addClass(object, fullName); + }; + + this._removeClass = function(object, name) { + var fullName = this._prefixCssClass("_" + name); + DayPilot.Util.removeClass(object, fullName); + }; + + this._drawTable = function(j, showLinks) { + var month = {}; + month.cells = []; + month.days = []; + month.weeks = []; + + var startDate = this.startDate.addMonths(j); + + var showBefore = showLinks.before; + var showAfter = showLinks.after; + + var firstOfMonth = startDate.firstDayOfMonth(); + var first = firstOfMonth.firstDayOfWeek(resolved.weekStarts()); + + var last = firstOfMonth.addMonths(1); + var days = DayPilot.DateUtil.daysDiff(first, last); + + var rowCount = (this.rowsPerMonth === "Auto") ? Math.ceil(days / 7) : 6; + month.rowCount = rowCount; + var today = (new DayPilot.Date()).getDatePart(); + + var width = resolved.cellWidth() * 7 + this._weekNumberWidth(); + month.width = width; + var height = this.cellHeight * rowCount + this.titleHeight + this.dayHeaderHeight; + month.height = height; + + var main = document.createElement("div"); + main.style.width = (width) + 'px'; + main.style.height = (height) + 'px'; + + + if (this.orientation === "Horizontal") { + main.style.position = "absolute"; + main.style.left = (width * j) + "px"; + main.style.top = "0px"; + + month.top = 0; + month.left = width * j; + } + else { + main.style.position = 'relative'; + + var above = j > 0 ? calendar.months[j - 1].top + calendar.months[j - 1].height : 0; + month.top = above; + + month.left = 0; + } + + main.className = this._prefixCssClass('_month'); + main.style.cursor = 'default'; + main.style.MozUserSelect = 'none'; + main.style.KhtmlUserSelect = 'none'; + main.style.WebkitUserSelect = 'none'; + + main.month = month; + + this.root.appendChild(main); + + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + + // title left + var tl = document.createElement("div"); + tl.style.position = 'absolute'; + tl.style.left = '0px'; + tl.style.right = '0px'; // rtl + tl.style.top = '0px'; + tl.style.width = resolved.cellWidth() + 'px'; + tl.style.height = this.titleHeight + 'px'; + tl.style.lineHeight = this.titleHeight + 'px'; + //tl.style.textAlign = 'left'; + tl.setAttribute("unselectable", "on"); + tl.className = this._prefixCssClass('_titleleft'); + if (showLinks.left) { + tl.style.cursor = 'pointer'; + tl.innerHTML = "<"; + tl.onclick = this._clickLeft; + } + main.appendChild(tl); + this.tl = tl; + + // title center + var ti = document.createElement("div"); + ti.style.position = 'absolute'; + ti.style.left = resolved.cellWidth() + 'px'; + ti.style.top = '0px'; + ti.style.width = (resolved.cellWidth() * 5 + this._weekNumberWidth()) + 'px'; + ti.style.height = this.titleHeight + 'px'; + ti.style.lineHeight = this.titleHeight + 'px'; + //ti.style.textAlign = 'center'; + ti.setAttribute("unselectable", "on"); + ti.className = this._prefixCssClass('_title'); + ti.innerHTML = resolved.locale().monthNames[startDate.getMonth()] + ' ' + startDate.getYear(); + main.appendChild(ti); + this.ti = ti; + + // title right + var tr = document.createElement("div"); + tr.style.position = 'absolute'; + tr.style.left = (resolved.cellWidth() * 6 + this._weekNumberWidth()) + 'px'; + tr.style.right = (resolved.cellWidth() * 6 + this._weekNumberWidth()) + 'px'; // rtl + tr.style.top = '0px'; + tr.style.width = resolved.cellWidth() + 'px'; + tr.style.height = this.titleHeight + 'px'; + tr.style.lineHeight = this.titleHeight + 'px'; + //tr.style.textAlign = 'right'; + tr.setAttribute("unselectable", "on"); + tr.className = this._prefixCssClass('_titleright'); + if (showLinks.right) { + tr.style.cursor = 'pointer'; + tr.innerHTML = ">"; + tr.onclick = this._clickRight; + } + main.appendChild(tr); + this.tr = tr; + + + var xOffset = this._weekNumberWidth(); + if (this.showWeekNumbers) { + for (var y = 0; y < rowCount; y++) { + var day = first.addDays(y * 7); + var weekNumber = null; + switch (this.weekNumberAlgorithm) { + case "Auto": + weekNumber = (resolved.weekStarts() === 1) ? day.weekNumberISO() : day.weekNumber(); + break; + case "US": + weekNumber = day.weekNumber(); + break; + case "ISO8601": + weekNumber = day.weekNumberISO(); + break; + default: + throw "Unknown weekNumberAlgorithm value."; + } + + var dh = document.createElement("div"); + dh.style.position = 'absolute'; + dh.style.left = (0) + 'px'; + dh.style.right = (0) + 'px'; + dh.style.top = (y * this.cellHeight + totalHeaderHeight) + 'px'; + dh.style.width = resolved.cellWidth() + 'px'; + dh.style.height = this.cellHeight + 'px'; + dh.style.lineHeight = this.cellHeight + 'px'; + //dh.style.textAlign = 'right'; + dh.setAttribute("unselectable", "on"); + dh.className = this._prefixCssClass('_weeknumber'); + //dh.innerHTML = "" + weekNumber + ""; + dh.innerHTML = "" + weekNumber + ""; + main.appendChild(dh); + month.weeks.push(dh); + } + } + + + for (var x = 0; x < 7; x++) { + month.cells[x] = []; + + // day header + var dh = document.createElement("div"); + dh.style.position = 'absolute'; + dh.style.left = (x * resolved.cellWidth() + xOffset) + 'px'; + dh.style.right = (x * resolved.cellWidth() + xOffset) + 'px'; // rtl + dh.style.top = this.titleHeight + 'px'; + dh.style.width = resolved.cellWidth() + 'px'; + dh.style.height = this.dayHeaderHeight + 'px'; + dh.style.lineHeight = this.dayHeaderHeight + 'px'; + //dh.style.textAlign = 'right'; + dh.setAttribute("unselectable", "on"); + dh.className = this._prefixCssClass('_dayheader'); + dh.innerHTML = "" + this._getDayName(x) + ""; + main.appendChild(dh); + month.days.push(dh); + + for (var y = 0; y < rowCount; y++) { + var day = first.addDays(y * 7 + x); + + var isSelected = this._isSelected(day) && this._selectModeLowerCase() !== 'none'; + var isCurrentMonth = day.firstDayOfMonth() === startDate; + var isPrevMonth = day < startDate; + var isNextMonth = day >= startDate.addMonths(1); + + if (this._selectModeLowerCase() === "month") { + isSelected = isSelected && isCurrentMonth; + } + else if (this._selectModeLowerCase() === "day") { + isSelected = isSelected && (isCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)); + } + else if (this._selectModeLowerCase() === "week") { + //var sd = this.selectionDay || this.selectionStart; + var isSelectionCurrentMonth = day.firstDayOfMonth() === startDate; + isSelected = isSelected && (isSelectionCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)); + } + + var dc = document.createElement("div"); + month.cells[x][y] = dc; + + var cellPos = calendar._cellRelativeCoords(x, y); + var left = cellPos.x; + var top = cellPos.y; + + dc.day = day; + dc.x = x; + dc.y = y; + dc.left = left; + dc.top = top; + dc.isCurrentMonth = isCurrentMonth; + dc.isNextMonth = isNextMonth; + dc.isPrevMonth = isPrevMonth; + dc.showBefore = showBefore; + dc.showAfter = showAfter; + dc.className = this._prefixCssClass((isCurrentMonth ? '_day' : '_dayother')); + calendar._addClass(dc, "cell"); + if (day.getTime() === today.getTime() && isCurrentMonth) { + this._addClass(dc, 'today'); + } + if (day.dayOfWeek() === 0 || day.dayOfWeek() === 6) { + this._addClass(dc, 'weekend'); + } + + dc.style.position = 'absolute'; + dc.style.left = (left) + 'px'; + dc.style.right = (left) + 'px'; // rtl + dc.style.top = (top) + 'px'; + dc.style.width = resolved.cellWidth() + 'px'; + dc.style.height = this.cellHeight + 'px'; + dc.style.lineHeight = this.cellHeight + 'px'; // vertical alignment + //dc.style.textAlign = 'right'; + //dc.style.border = '1px solid white'; + + var inner = document.createElement("div"); + inner.style.position = 'absolute'; + inner.className = (day.getTime() === today.getTime() && isCurrentMonth) ? this._prefixCssClass('_todaybox') : this._prefixCssClass('_daybox'); + calendar._addClass(inner, "cell_box"); + //inner.style.boxSizing = "border-box"; + inner.style.left = '0px'; + inner.style.top = '0px'; + inner.style.right = '0px'; + inner.style.bottom = '0px'; + //inner.style.width = (this.cellWidth - 2) + 'px'; + //inner.style.height = (this.cellHeight - 2) + 'px'; + dc.appendChild(inner); + + /* + if (isCurrentMonth) { + dc.style.cursor = 'pointer'; + } + */ + + var cell = null; + if (this.cells && this.cells[day.toStringSortable()]) { + cell = this.cells[day.toStringSortable()]; + } + + if (typeof calendar.onBeforeCellRender === "function") { + var args = {}; + args.cell = cell || {}; + args.cell.day = day; + args.cell.isCurrentMonth = isCurrentMonth; + args.cell.isToday = day.getTime() === today.getTime() && isCurrentMonth; + args.cell.isWeekend = day.dayOfWeek() === 0 || day.dayOfWeek() === 6; + if (cell) { + args.cell.html = cell.html || day.getDay(); + args.cell.cssClass = cell.css; + } + else { + args.cell.html = day.getDay(); + args.cell.cssClass = null; + } + + calendar.onBeforeCellRender(args); + + cell = args.cell; + } + + if (cell) { + DayPilot.Util.addClass(dc, cell.cssClass || cell.css); + } + + //var span = null; + if (isCurrentMonth || (showBefore && isPrevMonth) || (showAfter && isNextMonth)) { + var text = document.createElement("div"); + text.innerHTML = day.getDay(); + text.style.position = "absolute"; + text.style.left = '0px'; + text.style.top = '0px'; + text.style.right = '0px'; + text.style.bottom = '0px'; + calendar._addClass(text, "cell_text"); + + // dc.style.cursor = 'pointer'; + dc.isClickable = true; + + if (cell && cell.html) { + text.innerHTML = cell.html; + } + + dc.appendChild(text); + } + + + dc.setAttribute("unselectable", "on"); + + dc.onclick = this._cellClick; + + main.appendChild(dc); + + if (isSelected) { + calendar._cellSelect(main, x, y); + this.selected.push(dc); + } + + } + } + + var line = document.createElement("div"); + line.style.position = 'absolute'; + line.style.left = '0px'; + line.style.top = (totalHeaderHeight - 2) + 'px'; + line.style.width = (resolved.cellWidth() * 7 + this._weekNumberWidth()) + 'px'; + line.style.height = '1px'; + line.style.fontSize = '1px'; + line.style.lineHeight = '1px'; + line.className = this._prefixCssClass("_line"); + + main.appendChild(line); + this.months.push(month); + }; + + this._cellRelativeCoords = function(x, y) { + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + var xOffset = this._weekNumberWidth(); + var left = x * resolved.cellWidth() + xOffset; + var top = y * this.cellHeight + totalHeaderHeight; + + return { + "x": left, + "y": top + }; + + }; + + this._cellSelect = function(main, x, y) { + var div = main.month.cells[x][y]; + + calendar._addClass(div, 'select'); + + /* + if (div.selectDiv) { + return; + } + + var xOffset = this._weekNumberWidth(); + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + + // overlay select + var od = document.createElement("div"); + od.style.position = 'absolute'; + od.style.left = (x * this.cellWidth + xOffset) + 'px'; + od.style.top = (y * this.cellHeight + totalHeaderHeight) + 'px'; + od.style.width = this.cellWidth + 'px'; + od.style.height = this.cellHeight + 'px'; + od.className = calendar._prefixCssClass("_selected_overlay"); + + div.selectDiv = od; + + main.appendChild(od); + */ + }; + + this._cellUnselect = function(main, x, y) { + var div = main.month.cells[x][y]; + + calendar._removeClass(div, 'select'); + + /* + DayPilot.de(div.selectDiv); + div.selectDiv = null; + */ + }; + + this._weekNumberWidth = function() { + if (this.showWeekNumbers) { + return resolved.cellWidth(); + } + return 0; + }; + + this._updateFreeBusy = function() { + if (!this.items) { + return; + } + + for (var j = 0; j < this.showMonths; j++) { + for (var x = 0; x < 7; x++) { + for (var y = 0; y < 6; y++) { + var cell = this.months[j].cells[x][y]; + if (!cell) { + continue; + } + if (this.items[cell.day.toStringSortable()] === 1) { + this._addClass(cell, 'busy'); + this._removeClass(cell, 'free'); + } + else { + this._removeClass(cell, 'busy'); + this._addClass(cell, 'free'); + } + } + } + } + }; + + this._saveState = function() { + var s = {}; + s.startDate = calendar.startDate; + s.selectionStart = calendar.selectionStart; + s.selectionEnd = calendar.selectionEnd.addDays(1); + calendar.state.value = JSON.stringify(s); + }; + + this._selectModeLowerCase = function() { + var selectMode = this.selectMode || ""; + return selectMode.toLowerCase(); + }; + + this._adjustSelection = function() { + + var input = this.selectionDay || this.selectionStart; // selectionDay is preferred + if (!input) { + input = DayPilot.Date.today(); + } + input = new DayPilot.Date(input); // make sure it's DayPilot.Date + + // ignores selectionEnd + // uses selectMode + switch (this._selectModeLowerCase()) { + case 'day': + this.selectionStart = input; + this.selectionDay = input; + this.selectionEnd = input; + break; + case 'week': + this.selectionDay = input; + this.selectionStart = input.firstDayOfWeek(resolved.weekStarts()); + this.selectionEnd = this.selectionStart.addDays(6); + break; + case 'month': + this.selectionDay = input; + this.selectionStart = input.firstDayOfMonth(); + this.selectionEnd = this.selectionStart.lastDayOfMonth(); + break; + case 'none': + this.selectionEnd = input; + break; + default: + throw "Unknown selectMode value."; + } + + }; + + this._postponedSelect = null; + + // options.dontFocus, options.dontNotify + this.select = function(a1, a2, a3) { + + var a2IsDate = a2 && (a2 instanceof DayPilot.Date || typeof a2 === "string"); + var a2IsOptions = (a2 && typeof a2 === "object") || typeof a2 === "boolean"; + + var date1 = a1; + var date2 = a2IsDate ? a2 : null; + var options = a2IsOptions ? a2 : a3; + + if (!this._initialized) { + this._postponedSelect = { + "date1": date1, + "date2": date2, + "options": options + }; + return; + } + + var focus = true; + var notify = true; // fire the timeRangeSelected event + + if (options && typeof options === "object") { + if (options.dontFocus) { + focus = false; + } + if (options.dontNotify) { + notify = false; + } + } + else if (typeof options === "boolean") { + focus = !options; + } + + var originalStart = this.selectionStart; + var originalEnd = this.selectionEnd; + + this.selectionStart = new DayPilot.Date(date1).getDatePart(); + this.selectionDay = this.selectionStart; + + var startChanged = false; + if (focus) { + + var newStart = this.startDate; + if (this.selectionStart < this._activeStart() || this.selectionStart >= this._activeEnd()) { + newStart = this.selectionStart.firstDayOfMonth(); + } + + if (newStart.toStringSortable() !== this.startDate.toStringSortable()) { + startChanged = true; + } + + this.startDate = newStart; + } + + if (date2 && calendar.freeHandSelectionEnabled) { + calendar.selectionEnd = new DayPilot.Date(date2); + } + else { + this._adjustSelection(); + } + + // redraw + this._clearTable(); + this._prepare(); + this._drawMonths(); + this._updateFreeBusy(); + this._saveState(); + + if (notify && (!originalStart.equals(this.selectionStart) || !originalEnd.equals(this.selectionEnd))) { + //alert('time range'); + this._timeRangeSelectedDispatch(); + } + + if (startChanged) { + //alert('visible range'); + this._visibleRangeChangedDispatch(); + } + }; + + this.update = function(options) { + + calendar._loadOptions(options); + +/* + if (!calendar._initialized) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Navigator instance that hasn't been initialized yet."); + } +*/ + if (!this._initialized) { + return; + } + + if (calendar._disposed) { + throw new DayPilot.Exception("You are trying to update a DayPilot.Navigator instance that has been disposed."); + } + + calendar._clearCache(); + + var os = { + "day": calendar.selectionDay, + "start": calendar.selectionStart, + "end": calendar.selectionEnd + }; + + calendar._update(); + + if (os.start !== calendar.selectionStart || os.end != calendar.selectionEnd || os.day !== calendar.selectionDay) { + calendar._timeRangeSelectedDispatch(); + } + }; + + this._update = function () { + // redraw + this._clearTable(); + this._prepare(); + this._adjustSelection(); + this._drawMonths(); + this._loadEvents(); + this._updateFreeBusy(); + this._saveState(); + + if (this.visible) { + this.show(); + } + else { + this.hide(); + } + }; + + this._clearCache = function() { + calendar._cache = {}; + }; + + this._specialHandling = null; + this._loadOptions = function(options) { + if (!options) { + return; + } + var specialHandling = { + "events": { + "preInit": function() { + var events = this.data || []; + if (DayPilot.isArray(events.list)) { + calendar.events.list = events.list; + } + else { + calendar.events.list = events; + } + } + } + }; + this._specialHandling = specialHandling; + + for (var name in options) { + if (specialHandling[name]) { + var item = specialHandling[name]; + item.data = options[name]; + if (item.preInit) { + item.preInit(); + } + } + else { + calendar[name] = options[name]; + } + } + + }; + + this._postInit = function() { + var specialHandling = this._specialHandling; + for (var name in specialHandling) { + var item = specialHandling[name]; + if (item.postInit) { + item.postInit(); + } + } + }; + + + this._callBack2 = function(action, data, parameters) { + var envelope = {}; + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + JSON.stringify(envelope); + + var context = null; + if (this.backendUrl) { + DayPilot.request(this.backendUrl, this._callBackResponse, commandstring, this._ajaxError); + } + else { + WebForm_DoCallback(this.uniqueID, commandstring, this._updateView, context, this.callbackError, true); + } + + }; + + this._ajaxError = function(req) { + if (typeof calendar.onAjaxError === 'function') { + var args = {}; + args.request = req; + calendar.onAjaxError(args); + } + else if (typeof calendar.ajaxError === 'function') { // backwards compatibility + calendar.ajaxError(req); + } + }; + + this._callBackResponse = function(response) { + calendar._updateView(response.responseText); + }; + + this._postBack2 = function(action, data, parameters) { + var envelope = {}; + envelope.action = action; + envelope.parameters = parameters; + envelope.data = data; + envelope.header = this._getCallBackHeader(); + + var commandstring = "JSON" + JSON.stringify(envelope); + __doPostBack(calendar.uniqueID, commandstring); + }; + + this._getCallBackHeader = function() { + var h = {}; + h.v = this.v; + h.startDate = this.startDate; + h.selectionStart = this.selectionStart; + h.showMonths = this.showMonths; + return h; + }; + + this._listen = function(action, data) { + if (action === 'refresh') { + this._visibleRangeChangedDispatch(); + } + }; + + this._getDayName = function(i) { + var x = i + resolved.weekStarts(); + if (x > 6) { + x -= 7; + } + return resolved.locale().dayNamesShort[x]; + + }; + + this._isSelected = function(date) { + if (this.selectionStart === null || this.selectionEnd === null) { + return false; + } + + if (this.selectionStart.getTime() <= date.getTime() && date.getTime() <= this.selectionEnd.getTime()) { + return true; + } + + return false; + }; + + this._getMonthFromCoords = function(coords) { + var month = 0; + //debugger; + for (var i = 0; i < calendar.months.length; i++) { + var m = calendar.months[i]; + if (!m) { + return null; + } + if (coords.x < m.left || m.width < coords.x ) { + return null; + } + + var height = calendar.months[i].height; + if (m.top <= coords.y && coords.y < m.top + m.height) { + return i; + } + } + return null; + + }; + + this._getPosition = function(ev) { + + var coords = DayPilot.mo3(calendar.nav.top, ev); + + var monthIndex = calendar._getMonthFromCoords(coords); + if (monthIndex === null) { + return null; + } + var month = calendar.months[monthIndex]; + + var totalHeaderHeight = this.titleHeight + this.dayHeaderHeight; + if (month.top <= coords.y && coords.y < month.top + totalHeaderHeight) { + return { + "month": monthIndex, + "x": 0, + "y": 0, + "coords": coords, + "header": true + }; + } + + for (var x = 0; x < month.cells.length; x++) { + for (var y = 0; y < month.cells[x].length; y++) { + var cell = month.cells[x][y]; + var top = cell.top + month.top; + var left = cell.left + month.left; + if (left <= coords.x && coords.x < left + calendar.cellWidth) { + if (top <= coords.y && coords.y < top + calendar.cellHeight) { + return { + "month": monthIndex, + "x": x, + "y": y, + "coords": coords + }; + } + } + } + } + + return null; + }; + + this._onTopMouseDown = function(ev) { + var freeHandSelection = calendar.freeHandSelectionEnabled; + if (!freeHandSelection) { + return; + } + var start = calendar._getPosition(ev); + if (start && !start.header) { + ps.start = start; + } + var cell = calendar.months[start.month].cells[start.x][start.y]; + + ev.preventDefault(); + + }; + + this._onTopMouseMove = function(ev) { + if (!ps.start) { + return; + } + var end = calendar._getPosition(ev); + if (ps.end) { + ps.end = end; + } + else if (end) { + var requiredDistance = 3; + var distance = DayPilot.distance(ps.start.coords, end.coords); + + if (distance > requiredDistance) { + ps.end = end; + } + } + + if (ps.end) { + ps.clear(); + ps.draw(); + } + //ps.end = end; + }; + + this._preselection = {}; + var ps = this._preselection; + ps.start = null; + + ps.drawCell = function(pos) { + var month = calendar.months[pos.month]; + + var cellPos = calendar._cellRelativeCoords(pos.x, pos.y); + + var top = month.top + cellPos.y; + var left = month.left + cellPos.x; + + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.left = left + "px"; + div.style.top = top + "px"; + div.style.height = calendar.cellHeight + "px"; + div.style.width = calendar.cellWidth + "px"; + div.style.backgroundColor = "#ccc"; + div.style.opacity = 0.5; + div.style.cursor = "default"; + + calendar.nav.preselection.appendChild(div); + ps.cells.push(div); + }; + + ps.clear = function() { + if (!ps.cells) { + return; + } + + for(var i = 0; i < ps.cells.length; i++) { + calendar.nav.preselection.removeChild(ps.cells[i]); + } + ps.cells = []; + }; + + ps.draw = function() { + var ordered = ps.ordered(); + + var position = new Position(ordered.start); + var end = ordered.end; + + if (!end) { + return; + } + + if (end === ps.end && end.header) { + if (end.month > 0) { + end.month -= 1; + var month = calendar.months[end.month]; + end.x = 6; + end.y = month.rowCount - 1; + } + } + + ps.cells = []; + + while (!position.is(end)) { + ps.drawCell(position); + var next = new Position(position).next(); + if (!next) { + return; + } + position.month = next.month; + position.x = next.x; + position.y = next.y; + } + + // the last one + ps.drawCell(position); + + }; + + ps.ordered = function() { + //var position = new Position(start); + var start = ps.start; + var end = ps.end; + + var result = {}; + if (!end || new Position(start).before(end)) { + result.start = start; + result.end = end; + } + else { + result.start = end; + result.end = start; + } + return result; + }; + + var Position = function(month, x, y) { + + if (month instanceof Position) { + return month; + } + if (typeof month === "object") { + var ref = month; + this.month = ref.month; + this.x = ref.x; + this.y = ref.y; + } + else { + this.month = month; + this.x = x; + this.y = y; + } + this.is = function(ref) { + return this.month === ref.month && this.x === ref.x && this.y === ref.y; + }; + + this.next = function() { + var start = this; + if (start.x < 6) { + return { + "month": start.month, + "x": start.x + 1, + "y": start.y + }; + } + var month = calendar.months[start.month]; + if (start.y < month.rowCount - 1) { + return { + "month": start.month, + "x": 0, + "y": start.y + 1 + }; + } + if (start.month < calendar.months.length - 1) { + return { + "month": start.month + 1, + "x": 0, + "y": 0 + }; + } + return null; + }; + + this.visible = function() { + var cell = this.cell(); + if (cell.isCurrentMonth) { + return true; + } + if (cell.isPrevMonth && cell.showBefore) { + return true; + } + if (cell.isNextMonth && cell.showAfter) { + return true; + } + return false; + }; + + this.nextVisible = function() { + var pos = this; + while (!pos.visible()) { + var next = pos.next(); + if (!next) { + return null; + } + pos = new Position(next); + } + return pos; + }; + + this.previous = function() { + var start = this; + if (start.x > 0) { + return { + "month": start.month, + "x": start.x - 1, + "y": start.y + }; + } + var month = calendar.months[start.month]; + if (start.y > 0) { + return { + "month": start.month, + "x": 6, + "y": start.y - 1 + }; + } + if (start.month > 0) { + var m = calendar.months[start.month - 1]; + return { + "month": start.month - 1, + "x": 6, + "y": m.rowCount - 1 + }; + } + return null; + + }; + + this.previousVisible = function() { + var pos = this; + while (!pos.visible()) { + var previous = pos.previous(); + if (!previous) { + return null; + } + pos = new Position(previous); + } + return pos; + }; + + this.cell = function() { + return calendar.months[this.month].cells[this.x][this.y]; + }; + + this.date = function() { + return this.cell().day; + }; + + this.before = function(ref) { + var thisDate = this.date(); + var refDate = new Position(ref).date(); + return thisDate < refDate; + }; + }; + + + this._cellClick = function(ev) { + var main = this.parentNode; + var month = this.parentNode.month; + + var x = this.x; + var y = this.y; + var day = month.cells[x][y].day; + + if (!month.cells[x][y].isClickable) { + return; + } + + calendar.clearSelection(); + + calendar.selectionDay = day; + + var day = calendar.selectionDay; + switch (calendar._selectModeLowerCase()) { + case 'none': + //var s = month.cells[x][y]; + calendar.selectionStart = day; + calendar.selectionEnd = day; + break; + case 'day': + if (calendar.autoFocusOnClick) { + var start = day; + if (day < calendar._activeStart() || + day >= calendar._activeEnd()) { + calendar.select(day); + return; + } + } + + var s = month.cells[x][y]; + calendar._cellSelect(main, x, y); + //calendar._addClass(s, 'select'); + calendar.selected.push(s); + calendar.selectionStart = s.day; + calendar.selectionEnd = s.day; + + break; + case 'week': + if (calendar.autoFocusOnClick) { + var start = month.cells[0][y].day; + var end = month.cells[6][y].day; + if (start.firstDayOfMonth() === end.firstDayOfMonth()) { + if (start < calendar._activeStart() || + end >= calendar._activeEnd()) { + calendar.select(day); + return; + } + } + } + for (var j = 0; j < 7; j++) { + calendar._cellSelect(main, j, y); + //calendar._addClass(month.cells[j][y], 'select'); + calendar.selected.push(month.cells[j][y]); + } + calendar.selectionStart = month.cells[0][y].day; + calendar.selectionEnd = month.cells[6][y].day; + + break; + case 'month': + if (calendar.autoFocusOnClick) { + var start = day; + if (day < calendar._activeStart() || + day >= calendar._activeEnd()) { + calendar.select(day); + return; + } + } + + var start = null; + var end = null; + for (var y = 0; y < 6; y++) { + for (var x = 0; x < 7; x++) { + var s = month.cells[x][y]; + if (!s) { + continue; + } + if (s.day.getYear() === day.getYear() && s.day.getMonth() === day.getMonth()) { + calendar._cellSelect(main, x, y); + //calendar._addClass(s, 'select'); + calendar.selected.push(s); + if (start === null) { + start = s.day; + } + end = s.day; + } + } + } + calendar.selectionStart = start; + calendar.selectionEnd = end; + break; + default: + throw 'unknown selectMode'; + } + + calendar._saveState(); + + calendar._timeRangeSelectedDispatch(); + }; + + this._timeRangeSelectedDispatch = function(options) { + var start = calendar.selectionStart; + var end = calendar.selectionEnd.addDays(1); + var days = DayPilot.DateUtil.daysDiff(start, end); + var day = calendar.selectionDay; + + options = options || {}; + + + if (calendar._api2()) { + + var args = {}; + args.start = start; + args.end = end; + args.day = day; + args.days = days; + args.mode = options.mode || calendar.selectMode; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onTimeRangeSelect === 'function') { + calendar.onTimeRangeSelect(args); + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (calendar.timeRangeSelectedHandling) { + case 'Bind': + if (typeof bound === "object") { + var selection = {}; + selection.start = start; + selection.end = end; + selection.days = days; + selection.day = day; + bound.commandCallBack(calendar.command, selection); + } + break; + case 'None': + break; + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end, day); + break; + } + + if (typeof calendar.onTimeRangeSelected === 'function') { + calendar.onTimeRangeSelected(args); + } + + } + else { + switch (calendar.timeRangeSelectedHandling) { + case 'Bind': + if (typeof bound === "object") { + var selection = {}; + selection.start = start; + selection.end = end; + selection.days = days; + selection.day = day; + bound.commandCallBack(calendar.command, selection); + } + break; + case 'JavaScript': + calendar.onTimeRangeSelected(start, end, day); + break; + case 'None': + break; + case 'PostBack': + calendar.timeRangeSelectedPostBack(start, end, day); + break; + } + } + + + }; + + this.timeRangeSelectedPostBack = function(start, end, data, day) { + var params = {}; + params.start = start; + params.end = end; + params.day = day; + + this._postBack2('TimeRangeSelected', data, params); + }; + + this._clickRight = function(ev) { + calendar._moveMonth(calendar.skipMonths); + }; + + this._clickLeft = function(ev) { + calendar._moveMonth(-calendar.skipMonths); + }; + + this._moveMonth = function(i) { + this.startDate = this.startDate.addMonths(i); + this._clearTable(); + this._prepare(); + this._drawMonths(); + + this._saveState(); + + this._visibleRangeChangedDispatch(); + this._updateFreeBusy(); + }; + + this._activeStart = function() { + return calendar.startDate.firstDayOfMonth(); + }; + + this._activeEnd = function() { + return calendar.startDate.firstDayOfMonth().addMonths(this.showMonths); + }; + + this.visibleStart = function() { + return calendar.startDate.firstDayOfMonth().firstDayOfWeek(resolved.weekStarts()); + }; + + this.visibleEnd = function() { + return calendar.startDate.firstDayOfMonth().addMonths(this.showMonths - 1).firstDayOfWeek(resolved.weekStarts()).addDays(42); + }; + + this._visibleRangeChangedDispatch = function() { + var start = this.visibleStart(); + var end = this.visibleEnd(); + + if (calendar._api2()) { + + var args = {}; + args.start = start; + args.end = end; + args.preventDefault = function() { + this.preventDefault.value = true; + }; + + if (typeof calendar.onVisibleRangeChange === 'function') { + calendar.onVisibleRangeChange(args); + if (args.preventDefault.value) { + return; + } + } + + // now perform the default builtin action + switch (this.visibleRangeChangedHandling) { + case "CallBack": + this.visibleRangeChangedCallBack(null); + break; + case "PostBack": + this.visibleRangeChangedPostBack(null); + break; + case "Disabled": + break; + } + + if (typeof calendar.onVisibleRangeChanged === 'function') { + calendar.onVisibleRangeChanged(args); + } + + } + else { + switch (this.visibleRangeChangedHandling) { + case "CallBack": + this.visibleRangeChangedCallBack(null); + break; + case "PostBack": + this.visibleRangeChangedPostBack(null); + break; + case "JavaScript": + this.onVisibleRangeChanged(start, end); + break; + case "Disabled": + break; + } + } + + /* + switch (this.visibleRangeChangedHandling) { + case "CallBack": + this.visibleRangeChangedCallBack(null); + break; + case "PostBack": + this.visibleRangeChangedPostBack(null); + break; + case "JavaScript": + this.onVisibleRangeChanged(start, end); + break; + case "Disabled": + break; + } + */ + }; + + + this.visibleRangeChangedCallBack = function(data) { + var parameters = {}; + this._callBack2("Visible", data, parameters); + }; + + this.visibleRangeChangedPostBack = function(data) { + var parameters = {}; + this._postBack2("Visible", data, parameters); + }; + + this._updateView = function(result, context) { + var result = JSON.parse(result); + calendar.items = result.Items; + calendar.cells = result.Cells; + + if (calendar.cells) { + calendar.update(); + } + else { + calendar._updateFreeBusy(); + } + }; + + this._drawMonths = function() { + for (var j = 0; j < this.showMonths; j++) { + var showLinks = this._getShowLinks(j); + this._drawTable(j, showLinks); + } + + this.root.style.height = this._getHeight() + "px"; + + this.nav.preselection = document.createElement("div"); + this.nav.preselection.style.position = "absolute"; + this.nav.preselection.style.left = "0px"; + this.nav.preselection.style.top = "0px"; + this.root.appendChild(this.nav.preselection); + + /* + var div = document.createElement("div"); + div.style.clear = "left"; + div.style.height = "0px"; + div.style.width = "0px"; + this.root.appendChild(div); + */ + + }; + + + this._getHeight = function() { + if (this.orientation === "Horizontal") { + var max = 0; + for (var i = 0; i < this.months.length; i++) { + var month = this.months[i]; + if (month.height > max) { + max = month.height; + } + } + return max; + } + else { + var total = 0; + for (var i = 0; i < this.months.length; i++) { + var month = this.months[i]; + //total += this.showMonths*(this.cellHeight*month.rowCount + this.titleHeight + this.dayHeaderHeight); + total += month.height; + } + return total; + } + }; + + this._getShowLinks = function(j) { + if (this.internal.showLinks) { + return this.internal.showLinks; + } + + var showLinks = {}; + showLinks.left = (j === 0); + showLinks.right = (j === 0); + showLinks.before = j === 0; + showLinks.after = j === this.showMonths - 1; + + if (this.orientation === "Horizontal") { + showLinks.right = (j === this.showMonths - 1); + } + + return showLinks; + }; + + // not used at the moment - no internal changes to data + + this._angular = {}; + this._angular.scope = null; + this._angular.notify = function() { + if (calendar._angular.scope) { + calendar._angular.scope["$apply"](); + } + }; + + this.internal = {}; + this.internal.loadOptions = calendar._loadOptions; + // ASP.NET + this.internal.initialized = function() { + return calendar._initialized; + }; + + this._resolved = {}; + var resolved = this._resolved; + + resolved.locale = function() { + return DayPilot.Locale.find(calendar.locale); + }; + + resolved.weekStarts = function() { + if (calendar.weekStarts === 'Auto') { + var locale = resolved.locale(); + if (locale) { + return locale.weekStarts; + } + else { + return 0; // Sunday + } + } + else { + return calendar.weekStarts; + } + }; + + resolved.cellWidth = function() { + if (calendar._cache.cellWidth) { + return calendar._cache.cellWidth; + } + var width = calendar._getDimensionsFromCss("_cell_dimensions").width; + if (!width) { + width = calendar.cellWidth; + } + calendar._cache.cellWidth = width; + return width; + }; + + this.clearSelection = function() { + for (var j = 0; j < this.selected.length; j++) { + //this._removeClass(this.selected[j], 'select'); + var div = this.selected[j]; + calendar._cellUnselect(div.parentNode, div.x, div.y); + } + this.selected = []; + }; + + this._isShortInit = function() { + // make sure it has a place to ask + if (this.backendUrl) { + return (typeof calendar.items === 'undefined') || (!calendar.items); + } + else { + return false; + } + }; + + this.events = {}; + + this._loadEvents = function() { + if (!DayPilot.isArray(this.events.list)) { + return; + } + + this.items = {}; + + for(var i = 0; i < this.events.list.length; i++) { + var e = this.events.list[i]; + if (e.hidden) { + continue; + } + var days = this._eventDays(e); + for(var name in days) { + this.items[name] = 1; + } + } + }; + + this._getDimensionsFromCss = function(className) { + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.top = "-2000px"; + div.style.left = "-2000px"; + div.className = this._prefixCssClass(className); + + var container = calendar.root || document.body; + + container.appendChild(div); + var height = div.offsetHeight; + var width = div.offsetWidth; + container.removeChild(div); + + var result = {}; + result.height = height; + result.width = width; + return result; + }; + + this._eventDays = function(e) { + var start = new DayPilot.Date(e.start); + var end = new DayPilot.Date(e.end); + + var days = {}; + + var d = start.getDatePart(); + while (d.getTime() <= end.getTime()) { + days[d.toStringSortable()] = 1; + d = d.addDays(1); + } + + return days; + }; + + this.show = function() { + calendar.visible = true; + calendar.root.style.display = ''; + }; + + this.hide = function() { + calendar.visible = false; + calendar.root.style.display = 'none'; + }; + + this._loadTop = function() { + if (this.id && this.id.tagName) { + this.nav.top = this.id; + } + else if (typeof this.id === "string") { + this.nav.top = document.getElementById(this.id); + if (!this.nav.top) { + throw "DayPilot.Navigator: The placeholder element not found: '" + id + "'."; + } + } + else { + throw "DayPilot.Navigator() constructor requires the target element or its ID as a parameter"; + } + + this.root = this.nav.top; + + }; + + this.init = function() { + this._loadTop(); + + if (this.root.dp) { // already initialized + return; + } + + this._adjustSelection(); + this._prepare(); + this._drawMonths(); + this._loadEvents(); + this._updateFreeBusy(); + this._registerDispose(); + this._registerTopHandlers(); + this._registerGlobalHandlers(); + + //this.select(this.selectionStart); + + var loadFromServer = this._isShortInit(); + if (loadFromServer) { + this._visibleRangeChangedDispatch(); // TODO change to "Init"? + } + this._initialized = true; + this._postInit(); + + if (this._postponedSelect) { + var params = this._postponedSelect; + this.select(params.date1, params.date2, params.options); + this._postponedSelect = null; + } + + return this; + }; + + this._registerTopHandlers = function() { + calendar.nav.top.onmousedown = this._onTopMouseDown; + calendar.nav.top.onmousemove = this._onTopMouseMove; + }; + + this._registerGlobalHandlers = function() { + DayPilot.re(document, 'mouseup', calendar._gMouseUp); + }; + + this._gMouseUp = function(ev) { + if (ps.start && ps.end) { + var coords = DayPilot.mo3(calendar.nav.top, ev); + + // click, cancel + if (coords.x === ps.start.coords.x && coords.y === ps.start.coords.y) { + ps.start = null; + ps.clear(); + return; + } + + ps.clear(); + + var ordered = ps.ordered(); + + ordered.start = new Position(ordered.start).nextVisible(); + ordered.end = new Position(ordered.end).previousVisible(); + + + calendar.selectionDay = new Position(ordered.start).date(); + calendar.selectionStart = calendar.selectionDay; + calendar.selectionEnd = new Position(ordered.end).date(); + + ps.start = null; + ps.end = null; + + // redraw + calendar._clearTable(); + calendar._prepare(); + calendar._drawMonths(); + calendar._updateFreeBusy(); + calendar._saveState(); + + var notify = true; + if (notify) { + calendar._timeRangeSelectedDispatch({"mode": "FreeHand"}); + } + + } + + // clear in either case + ps.start = null; + ps.end = null; + + }; + + this.dispose = function() { + var c = calendar; + + if (!c.root) { + return; + } + + c.root.removeAttribute("style"); + c.root.removeAttribute("class"); + c.root.dp = null; + c.root.innerHTML = null; + c.root = null; + + c._disposed = true; + + }; + + this._registerDispose = function() { + //var root = document.getElementById(id); + this.root.dispose = this.dispose; + }; + + this.Init = this.init; + + this._loadOptions(options); + }; + + // jQuery plugin + if (typeof jQuery !== 'undefined') { + (function($) { + $.fn.daypilotNavigator = function(options) { + var first = null; + var j = this.each(function() { + if (this.daypilot) { // already initialized + return; + }; + + var daypilot = new DayPilot.Navigator(this.id); + this.daypilot = daypilot; + for (var name in options) { + daypilot[name] = options[name]; + } + daypilot.Init(); + if (!first) { + first = daypilot; + } + }); + if (this.length === 1) { + return first; + } + else { + return j; + } + }; + })(jQuery); + } + + // AngularJS plugin + (function registerAngularModule() { + var app = DayPilot.am(); + + if (!app) { + return; + } + + + app.directive("daypilotNavigator", ['$parse', function($parse) { + return { + "restrict": "E", + "template": "
", + "compile": function compile(element, attrs) { + element.replaceWith(this["template"].replace("{{id}}", attrs["id"])); + + return function link(scope, element, attrs) { + var calendar = new DayPilot.Navigator(element[0]); + calendar._angular.scope = scope; + calendar.init(); + + var oattr = attrs["id"]; + if (oattr) { + scope[oattr] = calendar; + } + + // save DayPilot.Calendar object in the specified variable + var pas = attrs["publishAs"]; + if (pas) { + var getter = $parse(pas); + var setter = getter.assign; + setter(scope, calendar); + } + + // bind event handlers from attributes starting with "on" + for (var name in attrs) { + if (name.indexOf("on") === 0) { // event handler + var apply = DayPilot.Util.shouldApply(name); + + if (apply) { + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + scope["$apply"](function() { + f(scope, {"args": args}); + }); + }; + })(name); + } + else { + (function(name) { + calendar[name] = function(args) { + var f = $parse(attrs[name]); + f(scope, {"args": args}); + }; + })(name); + } + + } + } + + var watch = scope["$watch"]; + var config = attrs["config"] || attrs["daypilotConfig"]; + var events = attrs["events"] || attrs["daypilotEvents"]; + + watch.call(scope, config, function (value, oldVal) { + for (var name in value) { + calendar[name] = value[name]; + } + calendar.update(); + }, true); + + watch.call(scope, events, function(value) { + calendar.events.list = value; + calendar._loadEvents(); + calendar._updateFreeBusy(); + }, true); + + }; + } + }; + }]); + + })(); + + if (typeof Sys !== 'undefined' && Sys.Application && Sys.Application.notifyScriptLoaded) { + Sys.Application.notifyScriptLoaded(); + } + + +})(); diff --git a/views/company_view.xml b/views/company_view.xml index be745af..aee751a 100755 --- a/views/company_view.xml +++ b/views/company_view.xml @@ -9,38 +9,33 @@ - -
-
- -
-
- -
-
-
-
- - -
-
-
+ +
diff --git a/views/dss_ads.xml b/views/dss_ads.xml index faf23b0..764be49 100755 --- a/views/dss_ads.xml +++ b/views/dss_ads.xml @@ -9,7 +9,9 @@
@@ -124,51 +126,54 @@
- +
-
- - - -
-
- - - -
-
- - - -
+ + +
-
- - -
-
- - -
-
- - -
+ + + + + + +
-
-
-
- - - -
-
- - - -
+
+ + + + +
+
+ +

+

+

+

+
+
+
+
+ + + + +
+
+ +

+

+

+

+
@@ -184,6 +189,12 @@ + + + + + + @@ -197,6 +208,7 @@ +
@@ -261,6 +273,17 @@ + + Autom Korrekturabzug-Ablauf prüfen + + + form + code + + action = record._check_date_korrekturfreigabe_ablauf() + + + diff --git a/views/dss_contracts.xml b/views/dss_contracts.xml index 0b554eb..699f314 100755 --- a/views/dss_contracts.xml +++ b/views/dss_contracts.xml @@ -11,7 +11,81 @@ - + + + + + + + + + + + DigitalSignage Status Änderung + ir.actions.act_window + dss.contracts + form + [('projectid', '=', active_id)] + { + 'default_projectid': active_id + 'show_project_update': True + } + + + + + dss_contracts_viewstate_form + dss.contracts + + + + + + + + + + + + + dss_contracts_viewstate_form + dss.contracts + +
+ + + + + +
+
+
+ + + dss_contracts_viewstate_form + dss.contracts + +
+ + + + + +
+
+
+ + + dss_contracts_infofeld_form + dss.contracts + +
+ + + + + +
@@ -37,6 +111,7 @@
+ dss_project_contracts_tree dss.contracts @@ -50,7 +125,7 @@ - + @@ -83,12 +158,12 @@
-
-

-

-
+
+

+

+
@@ -277,73 +352,25 @@




-
-
- - - -
-
-
-
- + + + + - -
-
- - - -
-
-
-
- - - -
-
-
-
- - - -
-
-
-
- + - -
-
- - -
-
- - - -
-
-
-
- - - -
-
- - - -
-
- -
-
+ + + + + + + + +
² - Kunde wird über Kontaktmanager verwaltet .. Bitte Daten dort ändern ...
@@ -424,14 +451,21 @@
-
+
+ + + + + +
+
- +
@@ -498,6 +532,19 @@
+
+
+ + + + +
+
+

+

+
+
@@ -513,13 +560,66 @@
>
- + + + + +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + +
-
+

-
+

+
+
+
+
+
+
+
+
+
+
+
+
@@ -671,15 +788,22 @@
-
-

-
-
-

-
-
-

-
+
+ + +
+
+ + +
+
+ + +
@@ -688,17 +812,7 @@
- Status : -
-
-
-
- Info : -
-
-
-
- Aktion : +
@@ -738,4 +852,27 @@ action = records.setFirstKampagne() + + Einstellung der Ansicht speichern + + + kanban + code + action = records.setFirstKampagne() + + + + + Contract Trigger Check + + code + model.trigger_action_init() + + 5 + minutes + -1 + + + + diff --git a/views/dss_maintains.xml b/views/dss_maintains.xml new file mode 100755 index 0000000..eef1a99 --- /dev/null +++ b/views/dss_maintains.xml @@ -0,0 +1,75 @@ + + + + + dss_maingtains_form + dss.maintaintask + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+
+ + + dss_maintains_tree + dss.maintaintask + + + + + + + + + + + + DigitalSignage Einsätze + ir.actions.act_window + dss.maintaintask + form,tree + + {'search_default_actual_projects': 1} + +

+ Fuege ein System ein ! +

+
+
+ + +
diff --git a/views/dss_projects.xml b/views/dss_projects.xml index 0bb36d7..589e613 100755 --- a/views/dss_projects.xml +++ b/views/dss_projects.xml @@ -16,7 +16,13 @@ - + + + + + + + @@ -46,8 +52,30 @@ + + +
+
+ + + +
+
+
+
+ + + +
+
+ + + +
+
+
- - - -
-
- - - -
-
-
-
- - - -
-
- - - -
-
-
- - + + + + + + + + + + + @@ -210,6 +224,19 @@ + + dss_projects_calendar + dss.projects + + + + + + + + dss_projects_tree dss.projects @@ -242,7 +269,7 @@ DigitalSignage Projekte ir.actions.act_window dss.projects - kanban,form,tree + kanban,form,tree,calendar {'search_default_actual_projects': 1} diff --git a/views/dss_provision.xml b/views/dss_provision.xml new file mode 100755 index 0000000..d42711a --- /dev/null +++ b/views/dss_provision.xml @@ -0,0 +1,96 @@ + + + + dss_provision_tree_search + dss.provision + + + + + + + + + + + + dss_provision_tree + dss.provision + + + + + + + + + + + + + + + + + dss_provision_form + dss.provision + +
+ + + + + + + +
+ +
+
+
+
+ + + dss_provision_add_form + dss.provision + +
+ + + + + + + + + + + + + + +
+
+
+
+
+ + + DigitalSignage Provision + ir.actions.act_window + tree,form + dss.provision + {} + +

+ Neuen Systemtyp erstellen +

+
+
+ + +
diff --git a/views/dss_provisionstypen.xml b/views/dss_provisionstypen.xml new file mode 100755 index 0000000..34a3982 --- /dev/null +++ b/views/dss_provisionstypen.xml @@ -0,0 +1,54 @@ + + + + + dss_provisionstypen_tree + dss.provisionstypen + + + + + + + + + + + + + dss_provisionstypen_form + dss.provisionstypen + +
+ + + + + + + + +
+ +
+
+
+
+ + + DigitalSignage Provisionstypen + ir.actions.act_window + dss.provisionstypen + tree,form + {} + +

+ Neuen Systemtyp erstellen +

+
+
+ + +
diff --git a/views/dss_settings.xml b/views/dss_settings.xml index 58e5a09..add358b 100755 --- a/views/dss_settings.xml +++ b/views/dss_settings.xml @@ -75,6 +75,13 @@
+ +
+ + + +
+
diff --git a/views/dss_systemtypen.xml b/views/dss_systemtypen.xml index 4e2b6b5..fbfe408 100755 --- a/views/dss_systemtypen.xml +++ b/views/dss_systemtypen.xml @@ -23,7 +23,7 @@
- + @@ -34,6 +34,12 @@ + + + + + +