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
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'},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 @@