aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Daemon/CurlAuth.php55
-rw-r--r--Zotlabs/Daemon/README.md43
-rw-r--r--Zotlabs/Lib/SuperCurl.php15
-rw-r--r--Zotlabs/Lib/ThreadItem.php2
-rw-r--r--Zotlabs/Module/Achievements.php2
-rw-r--r--Zotlabs/Module/Block.php2
-rw-r--r--Zotlabs/Module/Blocks.php2
-rw-r--r--Zotlabs/Module/Cal.php2
-rw-r--r--Zotlabs/Module/Channel.php2
-rw-r--r--Zotlabs/Module/Chat.php2
-rw-r--r--Zotlabs/Module/Cloud.php2
-rw-r--r--Zotlabs/Module/Common.php2
-rw-r--r--Zotlabs/Module/Connect.php2
-rw-r--r--Zotlabs/Module/Connedit.php2
-rw-r--r--Zotlabs/Module/Cover_photo.php4
-rw-r--r--Zotlabs/Module/Dav.php2
-rw-r--r--Zotlabs/Module/Dreport.php46
-rw-r--r--Zotlabs/Module/Editblock.php2
-rw-r--r--Zotlabs/Module/Editlayout.php2
-rw-r--r--Zotlabs/Module/Editwebpage.php2
-rw-r--r--Zotlabs/Module/Hcard.php2
-rw-r--r--Zotlabs/Module/Id.php2
-rw-r--r--Zotlabs/Module/Layouts.php2
-rw-r--r--Zotlabs/Module/New_channel.php4
-rw-r--r--Zotlabs/Module/Page.php2
-rw-r--r--Zotlabs/Module/Photo.php30
-rw-r--r--Zotlabs/Module/Photos.php2
-rw-r--r--Zotlabs/Module/Profile.php2
-rw-r--r--Zotlabs/Module/Profile_photo.php7
-rw-r--r--Zotlabs/Module/Profiles.php4
-rw-r--r--Zotlabs/Module/Profperm.php2
-rw-r--r--Zotlabs/Module/Register.php3
-rw-r--r--Zotlabs/Module/Setup.php10
-rw-r--r--Zotlabs/Module/Viewconnections.php7
-rw-r--r--Zotlabs/Module/Webpages.php2
-rw-r--r--Zotlabs/Module/Wiki.php19
-rw-r--r--Zotlabs/Storage/Browser.php4
-rw-r--r--doc/permissions.bb20
-rw-r--r--include/account.php18
-rw-r--r--include/attach.php4
-rw-r--r--include/bbcode.php14
-rw-r--r--include/channel.php41
-rw-r--r--include/conversation.php16
-rw-r--r--include/features.php1
-rw-r--r--include/js_strings.php8
-rw-r--r--include/nav.php6
-rw-r--r--include/network.php19
-rw-r--r--install/schema_postgres.sql6
-rw-r--r--library/cacert.pem560
-rw-r--r--library/certs/cacert.pem531
-rw-r--r--library/certs/lets-encrypt-x3-cross-signed.pem27
-rw-r--r--library/fullcalendar/CHANGELOG.txt20
-rw-r--r--library/fullcalendar/fullcalendar.css3
-rw-r--r--library/fullcalendar/fullcalendar.js283
-rw-r--r--library/fullcalendar/fullcalendar.min.css4
-rw-r--r--library/fullcalendar/fullcalendar.min.js10
-rw-r--r--library/fullcalendar/fullcalendar.print.css2
-rw-r--r--library/fullcalendar/gcal.js2
-rw-r--r--library/fullcalendar/lang-all.js6
-rw-r--r--library/moment/CHANGELOG.md21
-rw-r--r--library/moment/README.md2
-rw-r--r--library/moment/moment.js444
-rw-r--r--library/moment/moment.min.js6
-rw-r--r--vendor/autoload.php2
-rw-r--r--vendor/composer/autoload_files.php4
-rw-r--r--vendor/composer/autoload_namespaces.php1
-rw-r--r--vendor/composer/autoload_real.php14
-rw-r--r--vendor/composer/autoload_static.php21
-rw-r--r--vendor/composer/installed.json304
-rw-r--r--vendor/psr/log/.gitignore1
-rw-r--r--vendor/psr/log/LICENSE19
-rw-r--r--vendor/psr/log/Psr/Log/AbstractLogger.php120
-rw-r--r--vendor/psr/log/Psr/Log/InvalidArgumentException.php7
-rw-r--r--vendor/psr/log/Psr/Log/LogLevel.php18
-rw-r--r--vendor/psr/log/Psr/Log/LoggerAwareInterface.php17
-rw-r--r--vendor/psr/log/Psr/Log/LoggerAwareTrait.php22
-rw-r--r--vendor/psr/log/Psr/Log/LoggerInterface.php114
-rw-r--r--vendor/psr/log/Psr/Log/LoggerTrait.php131
-rw-r--r--vendor/psr/log/Psr/Log/NullLogger.php27
-rw-r--r--vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php116
-rw-r--r--vendor/psr/log/README.md45
-rw-r--r--vendor/sabre/dav/.travis.yml24
-rw-r--r--vendor/sabre/dav/CHANGELOG.md100
-rw-r--r--vendor/sabre/dav/README.md13
-rw-r--r--[-rwxr-xr-x]vendor/sabre/dav/bin/build.php2
-rw-r--r--[-rwxr-xr-x]vendor/sabre/dav/bin/googlecode_upload.py0
-rwxr-xr-xvendor/sabre/dav/bin/migrateto17.php284
-rw-r--r--[-rwxr-xr-x]vendor/sabre/dav/bin/migrateto20.php0
-rw-r--r--[-rwxr-xr-x]vendor/sabre/dav/bin/migrateto21.php4
-rw-r--r--[-rwxr-xr-x]vendor/sabre/dav/bin/migrateto30.php0
-rw-r--r--vendor/sabre/dav/bin/migrateto32.php268
-rwxr-xr-xvendor/sabre/dav/bin/naturalselection2
-rw-r--r--[-rwxr-xr-x]vendor/sabre/dav/bin/sabredav.php0
-rw-r--r--vendor/sabre/dav/examples/addressbookserver.php57
-rw-r--r--vendor/sabre/dav/examples/sql/mysql.addressbook.sql28
-rw-r--r--vendor/sabre/dav/examples/sql/mysql.calendars.sql64
-rw-r--r--vendor/sabre/dav/examples/sql/mysql.locks.sql12
-rw-r--r--vendor/sabre/dav/examples/sql/mysql.principals.sql20
-rw-r--r--vendor/sabre/dav/examples/sql/mysql.users.sql9
-rw-r--r--vendor/sabre/dav/examples/sql/pgsql.addressbook.sql52
-rw-r--r--vendor/sabre/dav/examples/sql/pgsql.calendars.sql93
-rw-r--r--vendor/sabre/dav/examples/sql/pgsql.locks.sql19
-rw-r--r--vendor/sabre/dav/examples/sql/pgsql.principals.sql38
-rw-r--r--vendor/sabre/dav/examples/sql/pgsql.users.sql14
-rw-r--r--vendor/sabre/dav/examples/sql/sqlite.addressbooks.sql28
-rw-r--r--vendor/sabre/dav/examples/sql/sqlite.calendars.sql64
-rw-r--r--vendor/sabre/dav/examples/sql/sqlite.locks.sql12
-rw-r--r--vendor/sabre/dav/examples/sql/sqlite.principals.sql20
-rw-r--r--vendor/sabre/dav/examples/sql/sqlite.users.sql9
-rw-r--r--vendor/sabre/dav/examples/webserver/apache2_htaccess.conf16
-rw-r--r--vendor/sabre/dav/examples/webserver/apache2_vhost.conf29
-rw-r--r--vendor/sabre/dav/examples/webserver/apache2_vhost_cgi.conf21
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php6
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php15
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Backend/PDO.php381
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php225
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php296
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Calendar.php63
-rw-r--r--vendor/sabre/dav/lib/CalDAV/CalendarHome.php64
-rw-r--r--vendor/sabre/dav/lib/CalDAV/CalendarObject.php61
-rw-r--r--vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php22
-rw-r--r--vendor/sabre/dav/lib/CalDAV/IShareableCalendar.php48
-rw-r--r--vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php28
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php76
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Notifications/Node.php76
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Plugin.php113
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php64
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php69
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php107
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php16
-rw-r--r--vendor/sabre/dav/lib/CalDAV/ShareableCalendar.php72
-rw-r--r--vendor/sabre/dav/lib/CalDAV/SharedCalendar.php237
-rw-r--r--vendor/sabre/dav/lib/CalDAV/SharingPlugin.php106
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php67
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php11
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php5
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php209
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php22
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php11
-rw-r--r--vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php63
-rw-r--r--vendor/sabre/dav/lib/CardDAV/AddressBook.php82
-rw-r--r--vendor/sabre/dav/lib/CardDAV/AddressBookHome.php76
-rw-r--r--vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php7
-rw-r--r--vendor/sabre/dav/lib/CardDAV/Backend/PDO.php9
-rw-r--r--vendor/sabre/dav/lib/CardDAV/Card.php53
-rw-r--r--vendor/sabre/dav/lib/CardDAV/Plugin.php122
-rw-r--r--vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php28
-rw-r--r--vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php6
-rw-r--r--vendor/sabre/dav/lib/DAV/Auth/Backend/File.php2
-rw-r--r--vendor/sabre/dav/lib/DAV/Auth/Plugin.php126
-rw-r--r--vendor/sabre/dav/lib/DAV/Browser/Plugin.php13
-rw-r--r--vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.css6
-rw-r--r--vendor/sabre/dav/lib/DAV/Client.php19
-rw-r--r--vendor/sabre/dav/lib/DAV/CorePlugin.php40
-rw-r--r--vendor/sabre/dav/lib/DAV/FS/Directory.php6
-rw-r--r--vendor/sabre/dav/lib/DAV/FSExt/Directory.php10
-rw-r--r--vendor/sabre/dav/lib/DAV/File.php20
-rw-r--r--vendor/sabre/dav/lib/DAV/ICollection.php4
-rw-r--r--vendor/sabre/dav/lib/DAV/IFile.php2
-rw-r--r--vendor/sabre/dav/lib/DAV/INode.php5
-rw-r--r--vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php33
-rw-r--r--vendor/sabre/dav/lib/DAV/Server.php39
-rw-r--r--vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php69
-rw-r--r--vendor/sabre/dav/lib/DAV/Sharing/Plugin.php342
-rw-r--r--vendor/sabre/dav/lib/DAV/Tree.php2
-rw-r--r--vendor/sabre/dav/lib/DAV/Version.php2
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php199
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Property/Href.php17
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php70
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php48
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php143
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php11
-rw-r--r--vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php81
-rw-r--r--vendor/sabre/dav/lib/DAVACL/ACLTrait.php100
-rw-r--r--vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php2
-rw-r--r--vendor/sabre/dav/lib/DAVACL/FS/Collection.php52
-rw-r--r--vendor/sabre/dav/lib/DAVACL/FS/File.php49
-rw-r--r--vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php72
-rw-r--r--vendor/sabre/dav/lib/DAVACL/IACL.php1
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Plugin.php609
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Principal.php71
-rw-r--r--vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php2
-rw-r--r--vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php57
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php20
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php67
-rw-r--r--vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php107
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php634
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php53
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php32
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php30
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php166
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php88
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php518
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php97
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php37
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php40
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php2
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php747
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php32
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php86
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php39
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php38
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php36
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php37
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php35
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php25
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php13
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php5
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php19
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php5
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php37
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php73
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php60
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php239
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php215
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php65
-rw-r--r--vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php291
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php6
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php126
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php92
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php275
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php167
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php29
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php47
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php123
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php6
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php46
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php17
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php40
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php73
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php128
-rw-r--r--vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php253
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php12
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php13
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php11
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php20
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php1
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php13
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php6
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php26
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php23
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php49
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php64
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php44
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php16
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php54
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php4
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php9
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php8
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php18
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php64
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php20
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php26
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php28
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php40
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php27
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php21
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php312
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php16
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php48
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php5
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php44
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php4
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php192
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php29
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php112
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php2
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php63
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php2
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php106
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php70
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php7
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php24
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php157
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php31
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php19
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php30
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php14
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php213
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php3
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php10
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php27
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php145
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php67
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php117
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php43
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php40
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php16
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php159
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php53
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php150
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php286
-rw-r--r--vendor/sabre/dav/tests/Sabre/DAVServerTest.php84
-rw-r--r--vendor/sabre/dav/tests/Sabre/TestUtil.php31
-rw-r--r--vendor/sabre/dav/tests/bootstrap.php18
-rw-r--r--vendor/sabre/dav/tests/phpunit.xml47
-rw-r--r--[-rwxr-xr-x]vendor/sabre/vobject/bin/bench.php0
-rw-r--r--[-rwxr-xr-x]vendor/sabre/vobject/bin/fetch_windows_zones.php0
-rw-r--r--[-rwxr-xr-x]vendor/sabre/vobject/bin/generateicalendardata.php0
-rw-r--r--[-rwxr-xr-x]vendor/sabre/vobject/bin/mergeduplicates.php0
-rw-r--r--vendor/sabre/xml/.travis.yml9
-rw-r--r--vendor/sabre/xml/CHANGELOG.md11
-rw-r--r--vendor/sabre/xml/lib/Deserializer/functions.php7
-rw-r--r--vendor/sabre/xml/lib/Reader.php20
-rw-r--r--vendor/sabre/xml/lib/Service.php8
-rw-r--r--view/css/mod_cal.css4
-rw-r--r--view/css/mod_events.css4
-rw-r--r--view/css/widgets.css1
-rw-r--r--view/js/main.js5
-rw-r--r--view/theme/redbasic/css/style.css17
-rw-r--r--view/tpl/dreport.tpl21
-rwxr-xr-xview/tpl/event_head.tpl8
-rwxr-xr-xview/tpl/jot-header.tpl2
-rwxr-xr-xview/tpl/register.tpl3
319 files changed, 10673 insertions, 8242 deletions
diff --git a/Zotlabs/Daemon/CurlAuth.php b/Zotlabs/Daemon/CurlAuth.php
new file mode 100644
index 000000000..be12bc779
--- /dev/null
+++ b/Zotlabs/Daemon/CurlAuth.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Zotlabs\Daemon;
+
+// generate a curl compatible cookie file with an authenticated session for the given channel_id.
+// If this file is then used with curl and the destination url is sent through zid() or manually
+// manipulated to add a zid, it should allow curl to provide zot magic-auth across domains.
+
+// Handles expiration of stale cookies currently by deleting them and rewriting the file.
+
+class CurlAuth {
+
+ static public function run($argc,$argv) {
+
+ if($argc != 2)
+ killme();
+
+ \App::$session->start();
+
+ $_SESSION['authenticated'] = 1;
+ $_SESSION['uid'] = $argv[1];
+
+ $x = session_id();
+
+ $f = 'store/[data]/cookie_' . $argv[1];
+ $c = 'store/[data]/cookien_' . $argv[1];
+
+ $e = file_exists($f);
+
+ $output = '';
+
+ if($e) {
+ $lines = file($f);
+ if($lines) {
+ foreach($lines as $line) {
+ if(strlen($line) > 0 && $line[0] != '#' && substr_count($line, "\t") == 6) {
+ $tokens = explode("\t", $line);
+ $tokens = array_map('trim', $tokens);
+ if($tokens[4] > time()) {
+ $output .= $line . "\n";
+ }
+ }
+ else
+ $output .= $line;
+ }
+ }
+ }
+ $t = time() + (24 * 3600);
+ file_put_contents($f, $output . 'HttpOnly_' . \App::get_hostname() . "\tFALSE\t/\tTRUE\t$t\tPHPSESSID\t" . $x, (($e) ? FILE_APPEND : 0));
+
+ file_put_contents($c,$x);
+
+ killme();
+ }
+} \ No newline at end of file
diff --git a/Zotlabs/Daemon/README.md b/Zotlabs/Daemon/README.md
new file mode 100644
index 000000000..cb5b00a56
--- /dev/null
+++ b/Zotlabs/Daemon/README.md
@@ -0,0 +1,43 @@
+Daemon (background) Processes
+=============================
+
+
+This directory provides background tasks which are executed by a
+command-line process and detached from normal web processing.
+
+Background tasks are invoked by calling
+
+
+ Zotlabs\Daemon\Master::Summon([ $cmd, $arg1, $argn... ]);
+
+The Master class loads the desired command file and passes the arguments.
+
+
+To create a background task 'Foo' use the following template.
+
+ <?php
+
+ namespace Zotlabs\Daemon;
+
+ class Foo {
+
+ static public function run($argc,$argv) {
+ // do something
+ }
+ }
+
+
+The Master class "summons" the command by creating an executable script
+from the provided arguments, then it invokes "Release" to execute the script
+detached from web processing. This process calls the static::run() function
+with any command line arguments using the traditional argc, argv format.
+
+Please note: These are *real* $argc, $argv variables passed from the command
+line, and not the parsed argc() and argv() functions/variables which were
+obtained from parsing path components of the request URL by web processes.
+
+Background processes do not emit displayable output except through logs. They
+should also not make any assumptions about their HTML and web environment
+(as they do not have a web environment), particularly with respect to global
+variables such as $_SERVER, $_REQUEST, $_GET, $_POST, $_COOKIES, and $_SESSION.
+
diff --git a/Zotlabs/Lib/SuperCurl.php b/Zotlabs/Lib/SuperCurl.php
index 40ca1addb..1c8583ff5 100644
--- a/Zotlabs/Lib/SuperCurl.php
+++ b/Zotlabs/Lib/SuperCurl.php
@@ -26,6 +26,7 @@ class SuperCurl {
private $request_method = 'GET';
private $upload = false;
+ private $cookies = false;
private function set_data($s) {
@@ -62,6 +63,11 @@ class SuperCurl {
case 'http_auth':
$this->auth = $v;
break;
+ case 'magicauth':
+ // currently experimental
+ $this->magicauth = $v;
+ \Zotlabs\Daemon\Master::Summon([ 'CurlAuth', $v ]);
+ break;
case 'custom':
$this->request_method = $v;
break;
@@ -90,8 +96,17 @@ class SuperCurl {
function exec() {
$opts = $this->curlopts;
+ $url = $this->url;
if($this->auth)
$opts['http_auth'] = $this->auth;
+ if($this->magicauth) {
+ $opts['cookiejar'] = 'store/[data]/cookie_' . $this->magicauth;
+ $opts['cookiefile'] = 'store/[data]/cookie_' . $this->magicauth;
+ $opts['cookie'] = 'PHPSESSID=' . trim(file_get_contents('store/[data]/cookien_' . $this->magicauth));
+ $c = channelx_by_n($this->magicauth);
+ if($c)
+ $url = zid($this->url,$c['channel_address'] . '@' . \App::get_hostname());
+ }
if($this->custom)
$opts['custom'] = $this->custom;
if($this->headers)
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index f724ac95d..6625b7b52 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -418,7 +418,7 @@ class ThreadItem {
if(($nb_children > $visible_comments) || ($thread_level > 1)) {
$result['children'][0]['comment_firstcollapsed'] = true;
$result['children'][0]['num_comments'] = $comment_count_txt;
- $result['children'][0]['hide_text'] = t('[+] show all');
+ $result['children'][0]['hide_text'] = sprintf( t('%s show all'), '<i class="fa fa-chevron-down"></i>');
if($thread_level > 1) {
$result['children'][$nb_children - 1]['comment_lastcollapsed'] = true;
}
diff --git a/Zotlabs/Module/Achievements.php b/Zotlabs/Module/Achievements.php
index 8ddefb3e5..1529448d3 100644
--- a/Zotlabs/Module/Achievements.php
+++ b/Zotlabs/Module/Achievements.php
@@ -18,7 +18,7 @@ class Achievements extends \Zotlabs\Web\Controller {
$profile = 0;
$profile = argv(1);
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
$r = q("select channel_id from channel where channel_address = '%s'",
dbesc($which)
diff --git a/Zotlabs/Module/Block.php b/Zotlabs/Module/Block.php
index 45e61e4ea..e671730f6 100644
--- a/Zotlabs/Module/Block.php
+++ b/Zotlabs/Module/Block.php
@@ -12,7 +12,7 @@ class Block extends \Zotlabs\Web\Controller {
$which = argv(1);
$profile = 0;
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
if(\App::$profile['profile_uid'])
head_set_icon(\App::$profile['thumb']);
diff --git a/Zotlabs/Module/Blocks.php b/Zotlabs/Module/Blocks.php
index 475cfa6b3..e6a97794d 100644
--- a/Zotlabs/Module/Blocks.php
+++ b/Zotlabs/Module/Blocks.php
@@ -22,7 +22,7 @@ class Blocks extends \Zotlabs\Web\Controller {
else
return;
- profile_load($a,$which);
+ profile_load($which);
}
diff --git a/Zotlabs/Module/Cal.php b/Zotlabs/Module/Cal.php
index 1da42684d..fd4169e68 100644
--- a/Zotlabs/Module/Cal.php
+++ b/Zotlabs/Module/Cal.php
@@ -20,7 +20,7 @@ class Cal extends \Zotlabs\Web\Controller {
if(argc() > 1) {
$nick = argv(1);
- profile_load($a,$nick);
+ profile_load($nick);
$channelx = channelx_by_nick($nick);
diff --git a/Zotlabs/Module/Channel.php b/Zotlabs/Module/Channel.php
index 29bfcbc3c..d09388901 100644
--- a/Zotlabs/Module/Channel.php
+++ b/Zotlabs/Module/Channel.php
@@ -48,7 +48,7 @@ class Channel extends \Zotlabs\Web\Controller {
// Run profile_load() here to make sure the theme is set before
// we start loading content
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
}
diff --git a/Zotlabs/Module/Chat.php b/Zotlabs/Module/Chat.php
index 026e8369a..ff55a9319 100644
--- a/Zotlabs/Module/Chat.php
+++ b/Zotlabs/Module/Chat.php
@@ -39,7 +39,7 @@ class Chat extends \Zotlabs\Web\Controller {
// Run profile_load() here to make sure the theme is set before
// we start loading content
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
}
diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php
index b691475ce..833b1b493 100644
--- a/Zotlabs/Module/Cloud.php
+++ b/Zotlabs/Module/Cloud.php
@@ -37,7 +37,7 @@ class Cloud extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
if ($which)
- profile_load($a, $which, $profile);
+ profile_load( $which, $profile);
$auth = new \Zotlabs\Storage\BasicAuth();
diff --git a/Zotlabs/Module/Common.php b/Zotlabs/Module/Common.php
index 1c428d256..2f3c57267 100644
--- a/Zotlabs/Module/Common.php
+++ b/Zotlabs/Module/Common.php
@@ -21,7 +21,7 @@ class Common extends \Zotlabs\Web\Controller {
);
if($x)
- profile_load($a,$x[0]['channel_address'],0);
+ profile_load($x[0]['channel_address'],0);
}
diff --git a/Zotlabs/Module/Connect.php b/Zotlabs/Module/Connect.php
index f68e0baac..962c05cce 100644
--- a/Zotlabs/Module/Connect.php
+++ b/Zotlabs/Module/Connect.php
@@ -26,7 +26,7 @@ class Connect extends \Zotlabs\Web\Controller {
if($r)
\App::$data['channel'] = $r[0];
- profile_load($a,$which,'');
+ profile_load($which,'');
}
function post() {
diff --git a/Zotlabs/Module/Connedit.php b/Zotlabs/Module/Connedit.php
index feed9cb1a..7db4950b1 100644
--- a/Zotlabs/Module/Connedit.php
+++ b/Zotlabs/Module/Connedit.php
@@ -433,7 +433,7 @@ class Connedit extends \Zotlabs\Web\Controller {
else {
// if you are on a different network we'll force a refresh of the connection basic info
- Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
+ \Zotlabs\Daemon\Master::Summon(array('Notifier','permission_update',$contact_id));
}
goaway(z_root() . '/connedit/' . $contact_id);
}
diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php
index 5633976c8..886958b37 100644
--- a/Zotlabs/Module/Cover_photo.php
+++ b/Zotlabs/Module/Cover_photo.php
@@ -29,7 +29,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
}
$channel = \App::get_channel();
- profile_load($a,$channel['channel_address']);
+ profile_load($channel['channel_address']);
}
@@ -50,7 +50,7 @@ class Cover_photo extends \Zotlabs\Web\Controller {
check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
- if((x($_POST,'cropfinal')) && ($_POST['cropfinal'] == 1)) {
+ if((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) {
// phase 2 - we have finished cropping
diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php
index 2fddabe19..6528e0271 100644
--- a/Zotlabs/Module/Dav.php
+++ b/Zotlabs/Module/Dav.php
@@ -58,7 +58,7 @@ class Dav extends \Zotlabs\Web\Controller {
\App::$page['htmlhead'] .= '<link rel="alternate" type="application/atom+xml" href="' . z_root() . '/feed/' . $which . '" />' . "\r\n";
if ($which)
- profile_load($a, $which, $profile);
+ profile_load( $which, $profile);
diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php
index e8709c952..17ed6515e 100644
--- a/Zotlabs/Module/Dreport.php
+++ b/Zotlabs/Module/Dreport.php
@@ -16,7 +16,24 @@ class Dreport extends \Zotlabs\Web\Controller {
$channel = \App::get_channel();
$mid = ((argc() > 1) ? argv(1) : '');
-
+
+ if($mid === 'push') {
+ $table = 'push';
+ $mid = ((argc() > 2) ? argv(2) : '');
+ if($mid) {
+ $i = q("select id from item where mid = '%s' and author_xchan = '%s' and uid = %d",
+ dbesc($mid),
+ dbesc($channel['channel_hash']),
+ intval($channel['channel_id'])
+ );
+ if($i) {
+ \Zotlabs\Daemon\Master::Summon([ 'Notifier', 'edit_post', $i[0]['id'] ]);
+ }
+ }
+ sleep(3);
+ goaway(z_root() . '/dreport/' . urlencode($mid));
+ }
+
if($mid === 'mail') {
$table = 'mail';
$mid = ((argc() > 2) ? argv(2) : '');
@@ -59,11 +76,7 @@ class Dreport extends \Zotlabs\Web\Controller {
notice( t('no results') . EOL);
return;
}
-
- $o .= '<div class="generic-content-wrapper-styled">';
- $o .= '<h2>' . sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...' . '</h2>';
- $o .= '<table>';
-
+
for($x = 0; $x < count($r); $x++ ) {
$r[$x]['name'] = escape_tags(substr($r[$x]['dreport_recip'],strpos($r[$x]['dreport_recip'],' ')));
@@ -119,13 +132,24 @@ class Dreport extends \Zotlabs\Web\Controller {
}
usort($r,'self::dreport_gravity_sort');
-
-
+
+ $entries = array();
foreach($r as $rr) {
- $o .= '<tr><td width="40%">' . $rr['name'] . '</td><td width="20%">' . escape_tags($rr['dreport_result']) . '</td><td width="20%">' . escape_tags($rr['dreport_time']) . '</td></tr>';
+ $entries[] = [
+ 'name' => $rr['name'],
+ 'result' => escape_tags($rr['dreport_result']),
+ 'time' => escape_tags(datetime_convert('UTC',date_default_timezone_get(),$rr['dreport_time']))
+ ];
}
- $o .= '</table>';
- $o .= '</div>';
+
+ $o = replace_macros(get_markup_template('dreport.tpl'), array(
+ '$title' => sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...',
+ '$table' => $table,
+ '$mid' => urlencode($mid),
+ '$push' => t('Redeliver'),
+ '$entries' => $entries
+ ));
+
return $o;
diff --git a/Zotlabs/Module/Editblock.php b/Zotlabs/Module/Editblock.php
index 1d6ef7a0a..6a9fa5f2d 100644
--- a/Zotlabs/Module/Editblock.php
+++ b/Zotlabs/Module/Editblock.php
@@ -21,7 +21,7 @@ class Editblock extends \Zotlabs\Web\Controller {
else
return;
- profile_load($a,$which);
+ profile_load($which);
}
diff --git a/Zotlabs/Module/Editlayout.php b/Zotlabs/Module/Editlayout.php
index fe794b5fd..26732dc77 100644
--- a/Zotlabs/Module/Editlayout.php
+++ b/Zotlabs/Module/Editlayout.php
@@ -21,7 +21,7 @@ class Editlayout extends \Zotlabs\Web\Controller {
else
return;
- profile_load($a,$which);
+ profile_load($which);
}
diff --git a/Zotlabs/Module/Editwebpage.php b/Zotlabs/Module/Editwebpage.php
index 6d67c08e7..5cd409e1e 100644
--- a/Zotlabs/Module/Editwebpage.php
+++ b/Zotlabs/Module/Editwebpage.php
@@ -23,7 +23,7 @@ class Editwebpage extends \Zotlabs\Web\Controller {
else
return;
- profile_load($a,$which);
+ profile_load($which);
}
diff --git a/Zotlabs/Module/Hcard.php b/Zotlabs/Module/Hcard.php
index 2636e676b..93c8d3ece 100644
--- a/Zotlabs/Module/Hcard.php
+++ b/Zotlabs/Module/Hcard.php
@@ -40,7 +40,7 @@ class Hcard extends \Zotlabs\Web\Controller {
}
}
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
}
diff --git a/Zotlabs/Module/Id.php b/Zotlabs/Module/Id.php
index 6a94b57f5..e053bf99c 100644
--- a/Zotlabs/Module/Id.php
+++ b/Zotlabs/Module/Id.php
@@ -57,7 +57,7 @@ class Id extends \Zotlabs\Web\Controller {
$profile = '';
$channel = \App::get_channel();
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
$op = new MysqlProvider;
$op->server();
diff --git a/Zotlabs/Module/Layouts.php b/Zotlabs/Module/Layouts.php
index a0b1c31cc..c07f65ce1 100644
--- a/Zotlabs/Module/Layouts.php
+++ b/Zotlabs/Module/Layouts.php
@@ -21,7 +21,7 @@ class Layouts extends \Zotlabs\Web\Controller {
else
return;
- profile_load($a,$which);
+ profile_load($which);
}
diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php
index 30d7c83c6..1dcf84fb0 100644
--- a/Zotlabs/Module/New_channel.php
+++ b/Zotlabs/Module/New_channel.php
@@ -62,7 +62,7 @@ class New_channel extends \Zotlabs\Web\Controller {
}
- function post() {
+ function post() {
$arr = $_POST;
@@ -96,7 +96,7 @@ class New_channel extends \Zotlabs\Web\Controller {
}
- function get() {
+ function get() {
$acc = \App::get_account();
diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php
index deb23da68..6ef285dd0 100644
--- a/Zotlabs/Module/Page.php
+++ b/Zotlabs/Module/Page.php
@@ -13,7 +13,7 @@ class Page extends \Zotlabs\Web\Controller {
$which = argv(1);
$profile = 0;
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
diff --git a/Zotlabs/Module/Photo.php b/Zotlabs/Module/Photo.php
index 5148c4a94..66aaec49f 100644
--- a/Zotlabs/Module/Photo.php
+++ b/Zotlabs/Module/Photo.php
@@ -2,6 +2,7 @@
namespace Zotlabs\Module;
require_once('include/security.php');
+require_once('include/attach.php');
require_once('include/photo/photo_driver.php');
@@ -10,6 +11,8 @@ class Photo extends \Zotlabs\Web\Controller {
function init() {
$prvcachecontrol = false;
+ $streaming = null;
+ $channel = null;
switch(argc()) {
case 4:
@@ -131,6 +134,8 @@ class Photo extends \Zotlabs\Web\Controller {
$sql_extra = permissions_sql($r[0]['uid']);
+ $channel = channelx_by_n($r[0]['uid']);
+
// Now we'll see if we can access the photo
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND imgscale = %d $sql_extra LIMIT 1",
@@ -141,8 +146,9 @@ class Photo extends \Zotlabs\Web\Controller {
if($r && $allowed) {
$data = dbunescbin($r[0]['content']);
$mimetype = $r[0]['mimetype'];
- if(intval($r[0]['os_storage']))
- $data = file_get_contents($data);
+ if(intval($r[0]['os_storage'])) {
+ $streaming = $data;
+ }
}
else {
@@ -242,7 +248,25 @@ class Photo extends \Zotlabs\Web\Controller {
header("Cache-Control: max-age=" . $cache);
}
- echo $data;
+
+ // If it's a file resource, stream it.
+
+ if($streaming && $channel) {
+ if(strpos($streaming,'store') !== false)
+ $istream = fopen($streaming,'rb');
+ else
+ $istream = fopen('store/' . $channel['channel_address'] . '/' . $streaming,'rb');
+ $ostream = fopen('php://output','wb');
+ if($istream && $ostream) {
+ pipe_streams($istream,$ostream);
+ fclose($istream);
+ fclose($ostream);
+ }
+ }
+ else {
+ echo $data;
+ }
+
killme();
// NOTREACHED
}
diff --git a/Zotlabs/Module/Photos.php b/Zotlabs/Module/Photos.php
index 1bdc23897..1633e08ef 100644
--- a/Zotlabs/Module/Photos.php
+++ b/Zotlabs/Module/Photos.php
@@ -27,7 +27,7 @@ class Photos extends \Zotlabs\Web\Controller {
if(argc() > 1) {
$nick = argv(1);
- profile_load($a,$nick);
+ profile_load($nick);
$channelx = channelx_by_nick($nick);
diff --git a/Zotlabs/Module/Profile.php b/Zotlabs/Module/Profile.php
index 8bf358bc8..9e868db92 100644
--- a/Zotlabs/Module/Profile.php
+++ b/Zotlabs/Module/Profile.php
@@ -48,7 +48,7 @@ class Profile extends \Zotlabs\Web\Controller {
}
}
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
}
diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php
index 72c92e721..9359b80f8 100644
--- a/Zotlabs/Module/Profile_photo.php
+++ b/Zotlabs/Module/Profile_photo.php
@@ -34,7 +34,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
}
$channel = \App::get_channel();
- profile_load($a,$channel['channel_address']);
+ profile_load($channel['channel_address']);
}
@@ -53,7 +53,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
- if((array_key_exists('postfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
+ if((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
// phase 2 - we have finished cropping
@@ -90,12 +90,11 @@ class Profile_photo extends \Zotlabs\Web\Controller {
$srcY = $_POST['ystart'];
$srcW = $_POST['xfinal'] - $srcX;
$srcH = $_POST['yfinal'] - $srcY;
-
+
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
dbesc($image_id),
dbesc(local_channel()),
intval($scale));
-
if($r) {
$base_image = $r[0];
diff --git a/Zotlabs/Module/Profiles.php b/Zotlabs/Module/Profiles.php
index 06e5cfd7b..899c79b15 100644
--- a/Zotlabs/Module/Profiles.php
+++ b/Zotlabs/Module/Profiles.php
@@ -193,7 +193,7 @@ class Profiles extends \Zotlabs\Web\Controller {
$chan = \App::get_channel();
- profile_load($a,$chan['channel_address'],$r[0]['id']);
+ profile_load($chan['channel_address'],$r[0]['id']);
}
}
@@ -584,7 +584,7 @@ class Profiles extends \Zotlabs\Web\Controller {
if($is_default) {
// reload the info for the sidebar widget - why does this not work?
- profile_load($a,$channel['channel_address']);
+ profile_load($channel['channel_address']);
\Zotlabs\Daemon\Master::Summon(array('Directory',local_channel()));
}
}
diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php
index 79ce7a7ed..b1da147c1 100644
--- a/Zotlabs/Module/Profperm.php
+++ b/Zotlabs/Module/Profperm.php
@@ -17,7 +17,7 @@ class Profperm extends \Zotlabs\Web\Controller {
$profile = \App::$argv[1];
- profile_load($a,$which,$profile);
+ profile_load($which,$profile);
}
diff --git a/Zotlabs/Module/Register.php b/Zotlabs/Module/Register.php
index 7cd1ee501..6afa4a94c 100644
--- a/Zotlabs/Module/Register.php
+++ b/Zotlabs/Module/Register.php
@@ -259,7 +259,8 @@ class Register extends \Zotlabs\Web\Controller {
'$email' => $email,
'$pass1' => $password,
'$pass2' => $password2,
- '$submit' => ((UNO || $auto_create || $registration_is) ? t('Register') : t('Proceed to create your first channel'))
+ '$submit' => t('Register'),
+ '$verify_note' => t('This site may require email verification after submitting this form. If you are returned to a login page, please check your email for instructions.')
));
return $o;
diff --git a/Zotlabs/Module/Setup.php b/Zotlabs/Module/Setup.php
index c4878e217..c5d0ccc21 100644
--- a/Zotlabs/Module/Setup.php
+++ b/Zotlabs/Module/Setup.php
@@ -596,7 +596,7 @@ class Setup extends \Zotlabs\Web\Controller {
if(! is_writable('store')) {
$status = false;
- $help = t('Red uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
+ $help = t('This software uses the store directory to save uploaded files. The web server needs to have write access to the store directory under the Red top level folder') . EOL;
$help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
}
@@ -639,6 +639,9 @@ class Setup extends \Zotlabs\Web\Controller {
$help .= t('If your certificate is not recognized, members of other sites (who may themselves have valid certificates) will get a warning message on their own site complaining about security issues.') . EOL;
$help .= t('This can cause usability issues elsewhere (not just on your own site) so we must insist on this requirement.') .EOL;
$help .= t('Providers are available that issue free certificates which are browser-valid.'). EOL;
+
+ $help .= t('If you are confident that the certificate is valid and signed by a trusted authority, check to see if you have failed to install an intermediate cert. These are not normally required by browsers, but are required for server-to-server communications.') . EOL;
+
$this->check_add($checks, t('SSL certificate validation'), false, true, $help);
}
@@ -695,6 +698,7 @@ class Setup extends \Zotlabs\Web\Controller {
// install the standard theme
set_config('system', 'allowed_themes', 'redbasic');
+
// Set a lenient list of ciphers if using openssl. Other ssl engines
// (e.g. NSS used in RedHat) require different syntax, so hopefully
// the default curl cipher list will work for most sites. If not,
@@ -704,7 +708,9 @@ class Setup extends \Zotlabs\Web\Controller {
// z_fetch_url() is also used to import shared links and other content
// so in theory most any cipher could show up and we should do our best
// to make the content available rather than tell folks that there's a
- // weird SSL error which they can't do anything about.
+ // weird SSL error which they can't do anything about. This does not affect
+ // the SSL server, but is only a client negotiation to find something workable.
+ // Hence it will not make your system susceptible to POODL or other nasties.
$x = curl_version();
if(stristr($x['ssl_version'],'openssl'))
diff --git a/Zotlabs/Module/Viewconnections.php b/Zotlabs/Module/Viewconnections.php
index ea478f92a..4364d482a 100644
--- a/Zotlabs/Module/Viewconnections.php
+++ b/Zotlabs/Module/Viewconnections.php
@@ -10,8 +10,11 @@ class Viewconnections extends \Zotlabs\Web\Controller {
if(observer_prohibited()) {
return;
}
- if(argc() > 1)
- profile_load($a,argv(1));
+
+ if(argc() > 1) {
+ profile_load(argv(1));
+ }
+
}
function get() {
diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php
index fc292be6f..bb8d9c6ed 100644
--- a/Zotlabs/Module/Webpages.php
+++ b/Zotlabs/Module/Webpages.php
@@ -23,7 +23,7 @@ class Webpages extends \Zotlabs\Web\Controller {
else
return;
- profile_load($a,$which);
+ profile_load($which);
}
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php
index f30884bfb..6252f7a1a 100644
--- a/Zotlabs/Module/Wiki.php
+++ b/Zotlabs/Module/Wiki.php
@@ -20,11 +20,23 @@ class Wiki extends \Zotlabs\Web\Controller {
notice(t('You must be logged in to see this page.') . EOL);
goaway('/login');
}
+ profile_load($nick);
+
}
function get() {
+
+ if(observer_prohibited(true)) {
+ return login();
+ }
+
+ $tab = 'wiki';
+
+
require_once('include/wiki.php');
require_once('include/acl_selectors.php');
+ require_once('include/conversation.php');
+
// TODO: Combine the interface configuration into a unified object
// Something like $interface = array('new_page_button' => false, 'new_wiki_button' => false, ...)
$wiki_owner = false;
@@ -123,7 +135,7 @@ class Wiki extends \Zotlabs\Web\Controller {
notice('Error retrieving page content' . EOL);
goaway('/'.argv(0).'/'.argv(1).'/'.$wikiUrlName);
}
- $content = ($p['content'] !== '' ? $p['content'] : '"# New page\n"');
+ $content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"');
// Render the Markdown-formatted page content in HTML
require_once('library/markdown.php');
$html = wiki_generate_toc(purify_html(Markdown(json_decode($content))));
@@ -150,6 +162,11 @@ class Wiki extends \Zotlabs\Web\Controller {
)
);
+ $is_owner = ((local_channel()) && (local_channel() == \App::$profile['profile_uid']) ? true : false);
+
+ $o .= profile_tabs($a, $is_owner, \App::$profile['channel_address']);
+
+
$o .= replace_macros(get_markup_template('wiki.tpl'),array(
'$wikiheaderName' => $wikiheaderName,
'$wikiheaderPage' => $wikiheaderPage,
diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php
index f875cbf33..713d75108 100644
--- a/Zotlabs/Storage/Browser.php
+++ b/Zotlabs/Storage/Browser.php
@@ -219,7 +219,7 @@ class Browser extends DAV\Browser\Plugin {
$output = '';
if ($this->enablePost) {
- $this->server->emit('onHTMLActionsPanel', array($parent, &$output));
+ $this->server->emit('onHTMLActionsPanel', array($parent, &$output, $path));
}
$html .= replace_macros(get_markup_template('cloud.tpl'), array(
@@ -266,7 +266,7 @@ class Browser extends DAV\Browser\Plugin {
* @param \Sabre\DAV\INode $node
* @param string &$output
*/
- public function htmlActionsPanel(DAV\INode $node, &$output) {
+ public function htmlActionsPanel(DAV\INode $node, &$output, $path) {
if (! $node instanceof DAV\ICollection)
return;
diff --git a/doc/permissions.bb b/doc/permissions.bb
index ceb3fec17..cc831dd61 100644
--- a/doc/permissions.bb
+++ b/doc/permissions.bb
@@ -1,16 +1,20 @@
[h1]Permissions[/h1]
-Permissions in the $Projectname are more complete than you may be used to. This allows us to define more fine graded relationships than the black and white &quot;this person is my friend, so they can do everything&quot; or &quot;this person is not my friend, so they can't do anything&quot; permissions you may find elsewhere.
+Permissions in $Projectname are more complete than you may be used to. This allows us to define more fine graded relationships than the black and white &quot;this person is my friend, so they can do everything&quot; or &quot;this person is not my friend, so they can't do anything&quot; permissions you may find elsewhere.
+[b]Permission Roles[/b]
-[b]Default Permissions[/b]
+When you create a channel we allow you to select different 'roles' for that channel. These create an entire family of permissions and privacy settings that are appropriate for that role. Typical roles are "Social - mostly public", "Social - mostly private", "Forum - public" and many others. These bring a level of simplicity to managing permissions. Just choose a role and appropriate permissions are automatically applied. You can also choose 'Custom/Expert mode' and change any individual permission setting in any way you desire.
-On your settings page, you will find a list of default permissions. These permissions are automatically applied to everybody unless you specify otherwise. The scope of these permissions varies from &quot;Only me&quot; to &quot;Everybody&quot; - though some scopes may not be available for some permissions. For example, you can't allow &quot;anybody on the internet&quot; to send you private messages, because we'd have no way to identify the sender, therefore no way to reply to them.
-We highly recommend that you use the "typical social network" settings when you create your first channel, as it allows others to communicate with you and help you out if you have difficulty. You will find that these settings allow you as much privacy as you desire - when you desire it; but also allow you to communicate in public if you choose to. You are free to use much more private settings once you have learned your way around.
+[b]Default Permission Limits[/b]
+
+There are a large number of individual permissions. These control everything from the ability to view your stream to the ability to chat with you. Every permission has a limit. The scope of these permissions varies from &quot;Only me&quot; to &quot;Everybody on the internet&quot; - though some scopes may not be available for some permissions. The limit applies to any published thing you create which has no privacy or access control. For example if you publish a photo and didn't select a specific audience with permission to view it, we apply the limit. These limits apply to everything within that permission rule, so you cannot apply a limit to one photo. The limit applies to all your photos. If all your photos are visible to everybody on the internet and you reduce the limit only to friends, [b]all[/b] of your photos will now be visible only to friends.
-Be aware that altering the scope of who can see your "public" items is a more or less [b]permanent[/b] change. Your public items have no identified permissions attached to them - they are public. If you restrict who can see these items, there is no way of making any single item public ever again - without allowing access to every public item you ever created. You are certainly free to do this, but beware of the consequences.
+[b]Access Control[/b]
+
+Access Control is the preferred method of managing privacy in [i]most[/i] cases, rather than using permission limits. This creates lists of either connections or privacy groups (or both) and uses the access list to decide if a permission is allowed. An access list is attached to everything you publish. Unlike permission limits, if you change the access control list on a single photo, it doesn't affect any of your other photos. You can use privacy groups and a "default access control list" to create and automate the management of access control lists to provide any level of privacy you desire on anything you publish.
-A more useful privacy setup is to leave "public" items visible to anybody on the internet; but force everything you create to be restricted. This can be done on your Channel Settings page by selecting the role "Social - restricted". This ensures a Default Privacy Group for all new contacts, and sets your Default Post Permissions to restrict all your posts to that group. We use the Default Post Permissions for everything you create - posts, photos, events, webpages, and everything else. However you can then edit the permissions when you create any individual thing and remove your default privacy group to make just that item visible to anybody.
+We highly recommend that you use the "typical social network" settings when you create your first channel, as it allows others to communicate with you and help you out if you have difficulty. You will find that these settings allow you as much privacy as you desire - when you desire it; but also allow you to communicate in public if you choose to. You are free to use much more private settings once you have learned your way around.
[dl terms="l"]
@@ -22,11 +26,11 @@ A more useful privacy setup is to leave "public" items visible to anybody on the
[*= Anybody in your address book ] Anybody you do not know will have this permission denied, but anybody you accept as a contact will have this permission approved. This is the way most legacy platforms handle permissions.
- [*= Anybody On This Hub ] Anybody using the same hub as you will have permission approved. Anybody who registered at a different hub will have this permission denied.
+ [*= Anybody On This Hub ] Anybody with a channel on the same hub/website as you will have permission approved. Anybody who is registered at a different hub will have this permission denied.
[*= Anybody in this network ] Anybody in the $Projectname will have this permission approved. Even complete strangers. However, anybody not logged in/authenticated will have this permission denied.
- [*= Anybody authenticated ] This is similar to "anybody in this network" except that it can include anybody who can authenticate by any means - and therefore may include visitors from other networks.
+ [*= Anybody authenticated ] This is similar to "anybody in this network" except that it can include anybody who can authenticate by any means - and therefore [i]may[/i] include visitors from other networks.
[*= Anybody on the internet ] Completely public. This permission will be approved for anybody at all.
[/dl]
diff --git a/include/account.php b/include/account.php
index caf12878e..c02a74928 100644
--- a/include/account.php
+++ b/include/account.php
@@ -499,11 +499,27 @@ function account_approve($hash) {
intval($register[0]['uid'])
);
+ // get a fresh copy after we've modified it.
+
+ $account = q("SELECT * FROM account WHERE account_id = %d LIMIT 1",
+ intval($register[0]['uid'])
+ );
+
+ if(! $account)
+ return $ret;
+
+
+
if(get_config('system','auto_channel_create') || UNO)
auto_channel_create($register[0]['uid']);
+ else {
+ $_SESSION['login_return_url'] = 'new_channel';
+ authenticate_success($account[0],true,true,false,true);
+ }
+
- info( t('Account verified. Please login.') . EOL );
+ // info( t('Account verified. Please login.') . EOL );
return true;
}
diff --git a/include/attach.php b/include/attach.php
index 4961d7f91..b3ddfee88 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -1468,7 +1468,7 @@ function find_filename_by_hash($channel_id, $attachHash) {
function pipe_streams($in, $out) {
$size = 0;
while (!feof($in))
- $size += fwrite($out, fread($in, 8192));
+ $size += fwrite($out, fread($in, 16384));
return $size;
}
@@ -1909,4 +1909,4 @@ function get_attach_binname($s) {
$p = substr($p,strpos($p,'/')+1);
}
return $p;
-} \ No newline at end of file
+}
diff --git a/include/bbcode.php b/include/bbcode.php
index 0bf326506..7f7be4300 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -498,6 +498,18 @@ function bb_highlight($match) {
return $match[0];
}
+function bb_fixtable_lf($match) {
+
+ // remove extraneous whitespace between table element tags since newlines will all
+ // be converted to '<br />' and turn your neatly crafted tables into a whole lot of
+ // empty space.
+
+ $x = preg_replace("/\]\s+\[/",'][',$match[1]);
+ return '[table]' . $x . '[/table]';
+
+}
+
+
// BBcode 2 HTML was written by WAY2WEB.net
// extended to work with Mistpark/Friendica/Redmatrix/Hubzilla - Mike Macgirvin
@@ -579,7 +591,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace_callback("/\[code=(.*?)\](.*?)\[\/code\]/ism", 'bb_highlight', $Text);
}
-
+ $Text = preg_replace_callback("/\[table\](.*?)\[\/table\]/ism",'bb_fixtable_lf',$Text);
// Convert new line chars to html <br /> tags
diff --git a/include/channel.php b/include/channel.php
index a7624f060..95506ed78 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -747,6 +747,44 @@ function identity_export_year($channel_id,$year,$month = 0) {
return $ret;
}
+// export items within an arbitrary date range. Date/time is in UTC.
+
+function channel_export_items($channel_id,$start,$finish) {
+
+ if(! $start)
+ return array();
+ else
+ $start = datetime_convert('UTC','UTC',$start);
+
+ $finish = datetime_convert('UTC','UTC',(($finish) ? $finish : 'now'));
+ if($finish < $start)
+ return array();
+
+ $ret = array();
+
+ $ch = channelx_by_n($channel_id);
+ if($ch) {
+ $ret['relocate'] = [ 'channel_address' => $ch['channel_address'], 'url' => z_root()];
+ }
+
+ $r = q("select * from item where ( item_wall = 1 or item_type != %d ) and item_deleted = 0 and uid = %d and created >= '%s' and created < '%s' and resource_type = '' order by created",
+ intval(ITEM_TYPE_POST),
+ intval($channel_id),
+ dbesc($start),
+ dbesc($finish)
+ );
+
+ if($r) {
+ $ret['item'] = array();
+ xchan_query($r);
+ $r = fetch_post_tags($r,true);
+ foreach($r as $rr)
+ $ret['item'][] = encode_item($rr,true);
+ }
+
+ return $ret;
+}
+
/**
* @brief Loads a profile into the App structure.
@@ -761,11 +799,10 @@ function identity_export_year($channel_id,$year,$month = 0) {
*
* The channel default theme is also selected for use, unless over-riden elsewhere.
*
- * @param[in,out] App &$a
* @param string $nickname
* @param string $profile
*/
-function profile_load(&$a, $nickname, $profile = '') {
+function profile_load($nickname, $profile = '') {
// logger('profile_load: ' . $nickname . (($profile) ? ' profile: ' . $profile : ''));
diff --git a/include/conversation.php b/include/conversation.php
index d2d4ffca0..957dbf8e9 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -1703,13 +1703,19 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
'title' => t('Manage Webpages'),
'id' => 'webpages-tab',
);
- } else {
- /**
- * @FIXME we probably need a listing of events that were created by
- * this channel and are visible to the observer
- */
+ }
+
+ if(feature_enabled($uid,'wiki') && (! UNO)) {
+ $tabs[] = array(
+ 'label' => t('Wiki'),
+ 'url' => z_root() . '/wiki/' . $nickname,
+ 'sel' => ((argv(0) == 'wiki') ? 'active' : ''),
+ 'title' => t('Wiki'),
+ 'id' => 'wiki-tab',
+ );
}
+
$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
call_hooks('profile_tabs', $arr);
diff --git a/include/features.php b/include/features.php
index 6d38bcfb4..2d71aa9be 100644
--- a/include/features.php
+++ b/include/features.php
@@ -52,6 +52,7 @@ function get_features($filtered = true) {
array('advanced_profiles', t('Advanced Profiles'), t('Additional profile sections and selections'),false,get_config('feature_lock','advanced_profiles')),
array('profile_export', t('Profile Import/Export'), t('Save and load profile details across sites/channels'),false,get_config('feature_lock','profile_export')),
array('webpages', t('Web Pages'), t('Provide managed web pages on your channel'),false,get_config('feature_lock','webpages')),
+ array('wiki', t('Wiki'), t('Provide a wiki for your channel'),((UNO) ? false : true),get_config('feature_lock','wiki')),
array('hide_rating', t('Hide Rating'), t('Hide the rating buttons on your channel and profile pages. Note: People can still rate you somewhere else.'),false,get_config('feature_lock','hide_rating')),
array('private_notes', t('Private Notes'), t('Enables a tool to store notes and reminders (note: not encrypted)'),false,get_config('feature_lock','private_notes')),
array('nav_channel_select', t('Navigation Channel Select'), t('Change channels directly from within the navigation dropdown menu'),false,get_config('feature_lock','nav_channel_select')),
diff --git a/include/js_strings.php b/include/js_strings.php
index b1817f373..1b4668061 100644
--- a/include/js_strings.php
+++ b/include/js_strings.php
@@ -4,10 +4,10 @@ function js_strings() {
return replace_macros(get_markup_template('js_strings.tpl'), array(
'$delitem' => t('Delete this item?'),
'$comment' => t('Comment'),
- '$showmore' => t('[+] show all'),
- '$showfewer' => t('[-] show less'),
- '$divgrowmore' => t('[+] expand'),
- '$divgrowless' => t('[-] collapse'),
+ '$showmore' => sprintf( t('%s show all'), '<i class=\'fa fa-chevron-down\'></i>'),
+ '$showfewer' => sprintf( t('%s show less'), '<i class=\'fa fa-chevron-up\'></i>'),
+ '$divgrowmore' => sprintf( t('%s expand'), '<i class=\'fa fa-chevron-down\'></i>'),
+ '$divgrowless' => sprintf( t('%s collapse'),'<i class=\'fa fa-chevron-up\'></i>'),
'$pwshort' => t("Password too short"),
'$pwnomatch' => t("Passwords do not match"),
'$everybody' => t('everybody'),
diff --git a/include/nav.php b/include/nav.php
index 70faec598..6a79b6530 100644
--- a/include/nav.php
+++ b/include/nav.php
@@ -104,6 +104,8 @@ EOT;
if(feature_enabled($channel['channel_id'],'webpages') && (! UNO))
$nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages'),'webpages_nav_btn');
+ if(feature_enabled($channel['channel_id'],'wiki') && (! UNO))
+ $nav['usermenu'][] = Array('wiki/' . $channel['channel_address'],t('Wiki'),"",t('Your wiki'),'wiki_nav_btn');
}
else {
if(! get_account_id()) {
@@ -126,7 +128,7 @@ EOT;
$nav['lock'] = array('logout','','lock',
sprintf( t('%s - click to logout'), $observer['xchan_addr']));
}
- else {
+ elseif(! $_SESSION['authenticated']) {
$nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn');
}
@@ -143,7 +145,7 @@ EOT;
if((App::$module != 'home') && (! (local_channel())))
$nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn');
- if((App::$config['system']['register_policy'] == REGISTER_OPEN) && (! local_channel()) && (! remote_channel()))
+ if((App::$config['system']['register_policy'] == REGISTER_OPEN) && (! $_SESSION['authenticated']))
$nav['register'] = array('register',t('Register'), "", t('Create an account'),'register_nav_btn');
if(! get_config('system','hide_help')) {
diff --git a/include/network.php b/include/network.php
index 91dac936e..47863b680 100644
--- a/include/network.php
+++ b/include/network.php
@@ -101,6 +101,9 @@ function z_fetch_url($url, $binary = false, $redirects = 0, $opts = array()) {
if(x($opts,'cookiefile'))
@curl_setopt($ch, CURLOPT_COOKIEFILE, $opts['cookiefile']);
+ if(x($opts,'cookie'))
+ @curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']);
+
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,
((x($opts,'novalidate') && intval($opts['novalidate'])) ? false : true));
@@ -258,6 +261,10 @@ function z_post_url($url,$params, $redirects = 0, $opts = array()) {
if(x($opts,'cookiefile'))
@curl_setopt($ch, CURLOPT_COOKIEFILE, $opts['cookiefile']);
+
+ if(x($opts,'cookie'))
+ @curl_setopt($ch, CURLOPT_COOKIE, $opts['cookie']);
+
@curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,
((x($opts,'novalidate') && intval($opts['novalidate'])) ? false : true));
@@ -1336,8 +1343,20 @@ function discover_by_webbie($webbie) {
$fullname = $vcard['fn'];
if($vcard['photo'] && (strpos($vcard['photo'],'http') !== 0))
$vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
+ if(($vcard['key']) && (! $pubkey))
+ $pubkey = $vcard['key'];
if(! $avatar)
$avatar = $vcard['photo'];
+ if($diaspora) {
+ if(($vcard['guid']) && (! $diaspora_guid))
+ $diaspora_guid = $vcard['guid'];
+ if(($vcard['url']) && (! $diaspora_base))
+ $diaspora_base = $vcard['url'];
+
+
+
+
+ }
}
}
diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql
index 64cf37f7e..378308233 100644
--- a/install/schema_postgres.sql
+++ b/install/schema_postgres.sql
@@ -827,15 +827,15 @@ CREATE TABLE "obj" (
"obj_id" serial NOT NULL,
"obj_page" char(64) NOT NULL DEFAULT '',
"obj_verb" text NOT NULL DEFAULT '',
- "obj_type" bigint NOT NULL DEFAULT '0',
+ "obj_type" bigint NOT NULL DEFAULT 0,
"obj_obj" text NOT NULL DEFAULT '',
- "obj_channel" bigint NOT NULL DEFAULT '0',
+ "obj_channel" bigint NOT NULL DEFAULT 0,
"obj_term" char(255) NOT NULL DEFAULT '',
"obj_url" char(255) NOT NULL DEFAULT '',
"obj_imgurl" char(255) NOT NULL DEFAULT '',
"obj_created" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
"obj_edited" timestamp NOT NULL DEFAULT '0001-01-01 00:00:00',
- "obj_quantity" int(11) NOT NULL DEFAUL '0'.
+ "obj_quantity" bigint NOT NULL DEFAULT 0,
"allow_cid" text NOT NULL,
"allow_gid" text NOT NULL,
"deny_cid" text NOT NULL,
diff --git a/library/cacert.pem b/library/cacert.pem
index ef43898ab..29dbfa286 100644
--- a/library/cacert.pem
+++ b/library/cacert.pem
@@ -1,7 +1,7 @@
##
## Bundle of CA Root Certificates
##
-## Certificate data from Mozilla as of: Wed Sep 2 18:30:34 2015
+## Certificate data from Mozilla as of: Wed Apr 20 03:12:05 2016
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,30 +14,10 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.25.
-## SHA1: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c
+## SHA1: 5df367cda83086392e1acdf22bfef00c48d5eba6
##
-Equifax Secure CA
-=================
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
-ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
-MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
-B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
-nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
-fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
-8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
-A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
-CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
-A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
-spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
-Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
-zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
-BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
-70+sB3c4
------END CERTIFICATE-----
-
GlobalSign Root CA
==================
-----BEGIN CERTIFICATE-----
@@ -105,30 +85,6 @@ xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
-Verisign Class 4 Public Primary Certification Authority - G3
-============================================================
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
-cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
-tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
-8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
-Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
-Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
-j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
-mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
-fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
-RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
-UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
------END CERTIFICATE-----
-
Entrust.net Premium 2048 Secure Server CA
=========================================
-----BEGIN CERTIFICATE-----
@@ -673,53 +629,6 @@ EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
llpwrN9M
-----END CERTIFICATE-----
-Staat der Nederlanden Root CA
-=============================
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE
-ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g
-Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w
-HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh
-bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt
-vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P
-jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca
-C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth
-vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6
-22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV
-HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v
-dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN
-BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR
-EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw
-MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
-nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
-iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
-
-UTN DATACorp SGC Root CA
-========================
------BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ
-BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa
-MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w
-HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy
-dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys
-raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo
-wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA
-9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv
-33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud
-DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9
-BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD
-LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
-DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
-Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0
-I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx
-EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP
-DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
------END CERTIFICATE-----
-
UTN USERFirst Hardware Root CA
==============================
-----BEGIN CERTIFICATE-----
@@ -800,41 +709,6 @@ IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
-----END CERTIFICATE-----
-NetLock Notary (Class A) Root
-=============================
------BEGIN CERTIFICATE-----
-MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI
-EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
-dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j
-ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX
-DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH
-EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD
-VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz
-cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM
-D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ
-z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC
-/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7
-tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6
-4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG
-A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC
-Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv
-bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
-IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn
-LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0
-ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz
-IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh
-IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu
-b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh
-bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg
-Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp
-bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5
-ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP
-ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB
-CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr
-KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
-8CgHrTwXZoi1/baI
------END CERTIFICATE-----
-
XRamp Global CA Root
====================
-----BEGIN CERTIFICATE-----
@@ -1142,54 +1016,6 @@ vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
oKfN5XozNmr6mis=
-----END CERTIFICATE-----
-TURKTRUST Certificate Services Provider Root 1
-==============================================
------BEGIN CERTIFICATE-----
-MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP
-MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0
-acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx
-MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg
-U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB
-TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC
-aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX
-yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i
-Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ
-8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4
-W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME
-BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46
-sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE
-q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
-B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY
-nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H
------END CERTIFICATE-----
-
-TURKTRUST Certificate Services Provider Root 2
-==============================================
------BEGIN CERTIFICATE-----
-MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
-MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
-QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN
-MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr
-dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G
-A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
-acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe
-LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI
-x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g
-QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr
-5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB
-AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G
-A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt
-Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
-Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+
-hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P
-9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5
-UrbnBEI=
------END CERTIFICATE-----
-
SwissSign Gold CA - G2
======================
-----BEGIN CERTIFICATE-----
@@ -1589,56 +1415,6 @@ PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
-----END CERTIFICATE-----
-TC TrustCenter Class 2 CA II
-============================
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
-IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw
-MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
-c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE
-AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw
-IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2
-xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ
-Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u
-SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB
-7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
-Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
-cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
-SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G
-dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ
-KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj
-TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP
-JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
-vQ==
------END CERTIFICATE-----
-
-TC TrustCenter Universal CA I
-=============================
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
-IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN
-MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg
-VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw
-JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC
-qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv
-xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw
-ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O
-gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j
-BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG
-1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy
-vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3
-ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
-ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a
-7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
------END CERTIFICATE-----
-
Deutsche Telekom Root CA 2
==========================
-----BEGIN CERTIFICATE-----
@@ -1661,28 +1437,6 @@ dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
Cm26OWMohpLzGITY+9HPBVZkVw==
-----END CERTIFICATE-----
-ComSign Secured CA
-==================
------BEGIN CERTIFICATE-----
-MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE
-AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w
-NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD
-QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs
-49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH
-7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB
-kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1
-9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw
-AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t
-U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA
-j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC
-AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a
-BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp
-FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP
-51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
-OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
------END CERTIFICATE-----
-
Cybertrust Global Root
======================
-----BEGIN CERTIFICATE-----
@@ -1784,26 +1538,6 @@ fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w
wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
-----END CERTIFICATE-----
-Buypass Class 3 CA 1
-====================
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
-QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1
-MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
-c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx
-ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0
-n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia
-AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c
-1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P
-AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7
-pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA
-EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5
-htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj
-el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
------END CERTIFICATE-----
-
EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1
==========================================================================
-----BEGIN CERTIFICATE-----
@@ -2085,30 +1819,6 @@ IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
66+KAQ==
-----END CERTIFICATE-----
-CA Disig
-========
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK
-QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw
-MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz
-bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm
-GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD
-Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo
-hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt
-ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w
-gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P
-AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz
-aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff
-ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa
-BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t
-WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3
-mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
-CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K
-ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA
-4Z7CRneC9VkGjCFMhwnN5ag=
------END CERTIFICATE-----
-
Juur-SK
=======
-----BEGIN CERTIFICATE-----
@@ -2635,29 +2345,6 @@ iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt
+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
-----END CERTIFICATE-----
-A-Trust-nQual-03
-================
------BEGIN CERTIFICATE-----
-MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE
-Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
-a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R
-dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw
-RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0
-ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1
-c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA
-zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n
-yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE
-SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4
-iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V
-cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV
-eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40
-ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr
-sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd
-JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
-mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6
-ahq97BvIxYSazQ==
------END CERTIFICATE-----
-
TWCA Root Certification Authority
=================================
-----BEGIN CERTIFICATE-----
@@ -3986,6 +3673,196 @@ PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
-----END CERTIFICATE-----
+
+TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5
+=========================================================
+-----BEGIN CERTIFICATE-----
+MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN
+BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
+bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg
+RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw
+ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w
+SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE
+n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp
+ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537
+jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m
+ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP
+9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV
+4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH
+HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo
+BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
+URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl
+lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8
+B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU=
+-----END CERTIFICATE-----
+
+TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6
+=========================================================
+-----BEGIN CERTIFICATE-----
+MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G
+A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
+acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
+bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5
+MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL
+BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf
+aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm
+aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a
+2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED
+wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb
+HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV
++DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT
+9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R
+fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy
+o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW
+hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1
+O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw==
+-----END CERTIFICATE-----
+
+Certinomis - Root CA
+====================
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
+Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg
+LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx
+EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD
+ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos
+P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo
+d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap
+z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00
+8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x
+RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE
+6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t
+FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV
+PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH
+i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj
+YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I
+6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
+AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV
+WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw
+Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX
+lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ
+y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9
+Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng
+DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi
+I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM
+cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr
+hkIGuUE=
+-----END CERTIFICATE-----
+
+OISTE WISeKey Global Root GB CA
+===============================
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
+EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
+MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
+b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
+scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
+rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
+9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
+Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
+GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
+hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
+dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
+VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
+HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+
+Certification Authority of WoSign G2
+====================================
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx
+CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai
+XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du
+W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9
+5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK
+v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI
+hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY
+P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3
+TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu
++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+
+7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg=
+-----END CERTIFICATE-----
+
+CA WoSign ECC Root
+==================
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD
+TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v
+dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK
+ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU
+t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw
+QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R
+MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0
+Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu
+a/GRspBl9JrmkO5K
+-----END CERTIFICATE-----
+
+SZAFIR ROOT CA2
+===============
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
+A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
+BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
+BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
+VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
+qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
+DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
+2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
+ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
+ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
+AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
+O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
+oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
+4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+
+Certum Trusted Network CA 2
+===========================
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
+BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
+bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
+ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
+TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
+IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
+7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
+CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
+Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
+uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
+GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
+9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
+Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
+hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
+BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
+hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
+Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
+L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
+clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
+pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
+w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
+J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
+ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
+is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
+zAYspsbiDrW5viSP
+-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB
hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
@@ -4078,33 +3955,30 @@ Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----
-
-Lets Encrypt
-============
-----BEGIN CERTIFICATE-----
-MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa
-MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
-ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB
-BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg
-PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG
-dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1
-gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4
-4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy
-BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j
-b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv
-ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ
-MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH
-AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw
-MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM
-LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3
-pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd
-v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd
-ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW
-ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk
-6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj
-f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk=
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----
diff --git a/library/certs/cacert.pem b/library/certs/cacert.pem
index e4da7fc15..c15368bdc 100644
--- a/library/certs/cacert.pem
+++ b/library/certs/cacert.pem
@@ -1,7 +1,7 @@
##
## Bundle of CA Root Certificates
##
-## Certificate data from Mozilla as of: Wed Sep 2 18:30:34 2015
+## Certificate data from Mozilla as of: Wed Apr 20 03:12:05 2016
##
## This is a bundle of X.509 certificates of public Certificate Authorities
## (CA). These were automatically extracted from Mozilla's root certificates
@@ -14,30 +14,10 @@
## Just configure this file as the SSLCACertificateFile.
##
## Conversion done with mk-ca-bundle.pl version 1.25.
-## SHA1: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c
+## SHA1: 5df367cda83086392e1acdf22bfef00c48d5eba6
##
-Equifax Secure CA
-=================
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE
-ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
-MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT
-B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB
-nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR
-fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW
-8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG
-A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE
-CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG
-A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS
-spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB
-Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961
-zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB
-BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95
-70+sB3c4
------END CERTIFICATE-----
-
GlobalSign Root CA
==================
-----BEGIN CERTIFICATE-----
@@ -105,30 +85,6 @@ xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----
-Verisign Class 4 Public Primary Certification Authority - G3
-============================================================
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
-UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
-cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
-dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
-cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
-tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
-8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
-Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
-Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
-j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
-mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
-fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
-RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
-UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
------END CERTIFICATE-----
-
Entrust.net Premium 2048 Secure Server CA
=========================================
-----BEGIN CERTIFICATE-----
@@ -673,53 +629,6 @@ EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
llpwrN9M
-----END CERTIFICATE-----
-Staat der Nederlanden Root CA
-=============================
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE
-ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g
-Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w
-HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh
-bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt
-vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P
-jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca
-C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth
-vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6
-22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV
-HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v
-dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN
-BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR
-EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw
-MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y
-nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
-iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
-
-UTN DATACorp SGC Root CA
-========================
------BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE
-BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
-IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ
-BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa
-MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w
-HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy
-dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys
-raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo
-wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA
-9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv
-33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud
-DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9
-BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD
-LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3
-DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
-Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0
-I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx
-EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP
-DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI
------END CERTIFICATE-----
-
UTN USERFirst Hardware Root CA
==============================
-----BEGIN CERTIFICATE-----
@@ -800,41 +709,6 @@ IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
-----END CERTIFICATE-----
-NetLock Notary (Class A) Root
-=============================
------BEGIN CERTIFICATE-----
-MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI
-EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6
-dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j
-ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX
-DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH
-EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD
-VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz
-cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM
-D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ
-z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC
-/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7
-tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6
-4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG
-A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC
-Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv
-bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
-IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn
-LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0
-ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz
-IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh
-IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu
-b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh
-bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg
-Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp
-bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5
-ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP
-ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB
-CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr
-KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM
-8CgHrTwXZoi1/baI
------END CERTIFICATE-----
-
XRamp Global CA Root
====================
-----BEGIN CERTIFICATE-----
@@ -1142,54 +1016,6 @@ vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
oKfN5XozNmr6mis=
-----END CERTIFICATE-----
-TURKTRUST Certificate Services Provider Root 1
-==============================================
------BEGIN CERTIFICATE-----
-MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP
-MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0
-acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx
-MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg
-U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB
-TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC
-aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX
-yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i
-Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ
-8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4
-W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME
-BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46
-sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE
-q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
-B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY
-nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H
------END CERTIFICATE-----
-
-TURKTRUST Certificate Services Provider Root 2
-==============================================
------BEGIN CERTIFICATE-----
-MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
-MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
-QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN
-MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr
-dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G
-A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
-acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe
-LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI
-x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g
-QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr
-5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB
-AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G
-A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt
-Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
-Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+
-hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P
-9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5
-UrbnBEI=
------END CERTIFICATE-----
-
SwissSign Gold CA - G2
======================
-----BEGIN CERTIFICATE-----
@@ -1589,56 +1415,6 @@ PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
-----END CERTIFICATE-----
-TC TrustCenter Class 2 CA II
-============================
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy
-IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw
-MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1
-c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE
-AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw
-IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2
-xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ
-Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u
-SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB
-/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB
-7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90
-Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU
-cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i
-SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G
-dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ
-KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj
-TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP
-JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk
-vQ==
------END CERTIFICATE-----
-
-TC TrustCenter Universal CA I
-=============================
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC
-REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy
-IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN
-MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg
-VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw
-JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC
-qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv
-xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw
-ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O
-gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j
-BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG
-1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy
-vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3
-ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
-ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a
-7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
------END CERTIFICATE-----
-
Deutsche Telekom Root CA 2
==========================
-----BEGIN CERTIFICATE-----
@@ -1661,28 +1437,6 @@ dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
Cm26OWMohpLzGITY+9HPBVZkVw==
-----END CERTIFICATE-----
-ComSign Secured CA
-==================
------BEGIN CERTIFICATE-----
-MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE
-AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w
-NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD
-QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs
-49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH
-7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB
-kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1
-9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw
-AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t
-U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA
-j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC
-AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a
-BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp
-FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP
-51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
-OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
------END CERTIFICATE-----
-
Cybertrust Global Root
======================
-----BEGIN CERTIFICATE-----
@@ -1784,26 +1538,6 @@ fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w
wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
-----END CERTIFICATE-----
-Buypass Class 3 CA 1
-====================
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
-QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1
-MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh
-c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx
-ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0
-n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia
-AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c
-1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC
-MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P
-AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7
-pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA
-EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5
-htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj
-el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
------END CERTIFICATE-----
-
EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1
==========================================================================
-----BEGIN CERTIFICATE-----
@@ -2085,30 +1819,6 @@ IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
66+KAQ==
-----END CERTIFICATE-----
-CA Disig
-========
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK
-QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw
-MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz
-bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm
-GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD
-Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo
-hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt
-ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w
-gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P
-AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz
-aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff
-ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa
-BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t
-WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3
-mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
-CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K
-ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA
-4Z7CRneC9VkGjCFMhwnN5ag=
------END CERTIFICATE-----
-
Juur-SK
=======
-----BEGIN CERTIFICATE-----
@@ -2635,29 +2345,6 @@ iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt
+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
-----END CERTIFICATE-----
-A-Trust-nQual-03
-================
------BEGIN CERTIFICATE-----
-MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE
-Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy
-a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R
-dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw
-RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0
-ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1
-c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA
-zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n
-yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE
-SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4
-iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V
-cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV
-eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40
-ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr
-sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd
-JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
-mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6
-ahq97BvIxYSazQ==
------END CERTIFICATE-----
-
TWCA Root Certification Authority
=================================
-----BEGIN CERTIFICATE-----
@@ -3987,32 +3674,192 @@ kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
-----END CERTIFICATE-----
-Lets Encrypt
-============
+TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5
+=========================================================
+-----BEGIN CERTIFICATE-----
+MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN
+BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
+bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg
+RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw
+ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w
+SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE
+n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp
+ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537
+jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m
+ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP
+9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV
+4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH
+HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo
+BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
+URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl
+lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8
+B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU=
+-----END CERTIFICATE-----
+
+TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6
+=========================================================
+-----BEGIN CERTIFICATE-----
+MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQGEwJUUjEPMA0G
+A1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls
+acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
+bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5
+MDQxMFoXDTIzMTIxNjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBL
+BgNVBAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSf
+aSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlm
+aWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCdsGjW6L0UlqMACprx9MfMkU1xeHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a
+2uqsxgbPJQ1BgfbBOCK9+bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EED
+wnS3/faAz1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0pu5Fb
+HH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6plVxiSvgNZ1GpryHV
++DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMBAAGjQjBAMB0GA1UdDgQWBBTdVRcT
+9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
+9w0BAQsFAAOCAQEAb1gNl0OqFlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3R
+fdCaqaXKGDsCQC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy
+o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKIDgI6tflEATseW
+hvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm9ocJV612ph1jmv3XZch4gyt1
+O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsGtAuYSyher4hYyw==
+-----END CERTIFICATE-----
+
+Certinomis - Root CA
+====================
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
+Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg
+LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx
+EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD
+ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos
+P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo
+d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap
+z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00
+8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x
+RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE
+6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t
+FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV
+PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH
+i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj
+YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I
+6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
+AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV
+WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw
+Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX
+lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ
+y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9
+Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng
+DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi
+I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM
+cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr
+hkIGuUE=
+-----END CERTIFICATE-----
+
+OISTE WISeKey Global Root GB CA
+===============================
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
+EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
+MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
+b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
+scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
+rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
+9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
+Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
+GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
+hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
+dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
+VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
+HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+
+Certification Authority of WoSign G2
+====================================
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx
+CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai
+XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du
+W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9
+5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK
+v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI
+hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY
+P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3
+TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu
++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+
+7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg=
+-----END CERTIFICATE-----
+
+CA WoSign ECC Root
+==================
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD
+TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v
+dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK
+ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU
+t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw
+QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R
+MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0
+Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu
+a/GRspBl9JrmkO5K
+-----END CERTIFICATE-----
+
+SZAFIR ROOT CA2
+===============
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
+A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
+BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
+BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
+VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
+qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
+DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
+2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
+ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
+ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
+AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
+O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
+oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
+4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+
+Certum Trusted Network CA 2
+===========================
-----BEGIN CERTIFICATE-----
-MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa
-MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
-ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB
-BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg
-PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG
-dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1
-gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4
-4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud
-EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy
-BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j
-b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv
-ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ
-MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH
-AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw
-MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM
-LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3
-pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd
-v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd
-ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW
-ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk
-6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj
-f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk=
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
+BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
+bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
+ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
+TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
+IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
+7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
+CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
+Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
+uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
+GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
+9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
+Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
+hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
+BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
+hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
+Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
+L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
+clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
+pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
+w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
+J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
+ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
+is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
+zAYspsbiDrW5viSP
-----END CERTIFICATE-----
diff --git a/library/certs/lets-encrypt-x3-cross-signed.pem b/library/certs/lets-encrypt-x3-cross-signed.pem
new file mode 100644
index 000000000..0002462ce
--- /dev/null
+++ b/library/certs/lets-encrypt-x3-cross-signed.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
+-----END CERTIFICATE-----
diff --git a/library/fullcalendar/CHANGELOG.txt b/library/fullcalendar/CHANGELOG.txt
index 32559a8ad..f488738b8 100644
--- a/library/fullcalendar/CHANGELOG.txt
+++ b/library/fullcalendar/CHANGELOG.txt
@@ -1,4 +1,24 @@
+v2.8.0 (2016-06-19)
+-------------------
+
+- getEventSources method (#3103, #2433)
+- getEventSourceById method (#3223)
+- refetchEventSources method (#3103, #1328, #254)
+- removeEventSources method (#3165, #948)
+- prevent flicker when refetchEvents is called (#3123, #2558)
+- fix for removing event sources that share same URL (#3209)
+- jQuery 3 support (#3197, #3124)
+- Travis CI integration (#3218)
+- EditorConfig for promoting consistent code style (#141)
+- use en dash when formatting ranges (#3077)
+- height:auto always shows scrollbars in month view on FF (#3202)
+- new languages:
+ - Basque (#2992)
+ - Galician (#194)
+ - Luxembourgish (#2979)
+
+
v2.7.3 (2016-06-02)
-------------------
diff --git a/library/fullcalendar/fullcalendar.css b/library/fullcalendar/fullcalendar.css
index 81e9c1ee2..166bd09d3 100644
--- a/library/fullcalendar/fullcalendar.css
+++ b/library/fullcalendar/fullcalendar.css
@@ -1,5 +1,5 @@
/*!
- * FullCalendar v2.7.3 Stylesheet
+ * FullCalendar v2.8.0 Stylesheet
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
@@ -367,6 +367,7 @@ hr.fc-divider {
.fc table {
width: 100%;
+ box-sizing: border-box; /* fix scrollbar issue in firefox */
table-layout: fixed;
border-collapse: collapse;
border-spacing: 0;
diff --git a/library/fullcalendar/fullcalendar.js b/library/fullcalendar/fullcalendar.js
index cbe67697d..2460eb5e7 100644
--- a/library/fullcalendar/fullcalendar.js
+++ b/library/fullcalendar/fullcalendar.js
@@ -1,5 +1,5 @@
/*!
- * FullCalendar v2.7.3
+ * FullCalendar v2.8.0
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
@@ -19,7 +19,7 @@
;;
var FC = $.fullCalendar = {
- version: "2.7.3",
+ version: "2.8.0",
internalApiVersion: 4
};
var fcViews = FC.views = {};
@@ -1054,6 +1054,20 @@ function debounce(func, wait, immediate) {
};
}
+
+// HACK around jQuery's now A+ promises: execute callback synchronously if already resolved.
+// thenFunc shouldn't accept args.
+// similar to whenResources in Scheduler plugin.
+function syncThen(promise, thenFunc) {
+ // not a promise, or an already-resolved promise?
+ if (!promise || !promise.then || promise.state() === 'resolved') {
+ return $.when(thenFunc()); // resolve immediately
+ }
+ else if (thenFunc) {
+ return promise.then(thenFunc);
+ }
+}
+
;;
var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
@@ -3960,7 +3974,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
fillSegTag: 'div', // subclasses can override
- // Builds the HTML needed for one fill segment. Generic enought o work with different types.
+ // Builds the HTML needed for one fill segment. Generic enough to work with different types.
fillSegHtml: function(type, seg) {
// custom hooks per-type
@@ -8106,15 +8120,14 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
this.calendar.freezeContentHeight();
- return this.clear().then(function() { // clear the content first (async)
+ return syncThen(this.clear(), function() { // clear the content first
return (
_this.displaying =
- $.when(_this.displayView(date)) // displayView might return a promise
- .then(function() {
- _this.forceScroll(_this.computeInitialScroll(scrollState));
- _this.calendar.unfreezeContentHeight();
- _this.triggerRender();
- })
+ syncThen(_this.displayView(date), function() { // displayView might return a promise
+ _this.forceScroll(_this.computeInitialScroll(scrollState));
+ _this.calendar.unfreezeContentHeight();
+ _this.triggerRender();
+ })
);
});
},
@@ -8128,7 +8141,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
var displaying = this.displaying;
if (displaying) { // previously displayed, or in the process of being displayed?
- return displaying.then(function() { // wait for the display to finish
+ return syncThen(displaying, function() { // wait for the display to finish
_this.displaying = null;
_this.clearEvents();
return _this.clearView(); // might return a promise. chain it
@@ -9321,6 +9334,7 @@ function Calendar_constructor(element, overrides) {
t.render = render;
t.destroy = destroy;
t.refetchEvents = refetchEvents;
+ t.refetchEventSources = refetchEventSources;
t.reportEvents = reportEvents;
t.reportEventChange = reportEventChange;
t.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method
@@ -9511,6 +9525,7 @@ function Calendar_constructor(element, overrides) {
EventManager.call(t, options);
var isFetchNeeded = t.isFetchNeeded;
var fetchEvents = t.fetchEvents;
+ var fetchEventSources = t.fetchEventSources;
@@ -9750,11 +9765,16 @@ function Calendar_constructor(element, overrides) {
function refetchEvents() { // can be called as an API method
- destroyEvents(); // so that events are cleared before user starts waiting for AJAX
fetchAndRenderEvents();
}
+ // TODO: move this into EventManager?
+ function refetchEventSources(matchInputs) {
+ fetchEventSources(t.getEventSourcesByMatchArray(matchInputs));
+ }
+
+
function renderEvents() { // destroys old events if previously rendered
if (elementVisible()) {
freezeContentHeight();
@@ -9762,13 +9782,6 @@ function Calendar_constructor(element, overrides) {
unfreezeContentHeight();
}
}
-
-
- function destroyEvents() {
- freezeContentHeight();
- currentView.clearEvents();
- unfreezeContentHeight();
- }
function getAndRenderEvents() {
@@ -9979,7 +9992,7 @@ function Calendar_constructor(element, overrides) {
Calendar.defaults = {
- titleRangeSeparator: ' \u2014 ', // emphasized dash
+ titleRangeSeparator: ' \u2013 ', // en dash
monthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option
defaultTimedEventDuration: '02:00:00',
@@ -10528,14 +10541,14 @@ function Header(calendar, options) {
function disableButton(buttonName) {
el.find('.fc-' + buttonName + '-button')
- .attr('disabled', 'disabled')
+ .prop('disabled', true)
.addClass(tm + '-state-disabled');
}
function enableButton(buttonName) {
el.find('.fc-' + buttonName + '-button')
- .removeAttr('disabled')
+ .prop('disabled', false)
.removeClass(tm + '-state-disabled');
}
@@ -10566,8 +10579,14 @@ function EventManager(options) { // assumed to be a calendar
// exports
t.isFetchNeeded = isFetchNeeded;
t.fetchEvents = fetchEvents;
+ t.fetchEventSources = fetchEventSources;
+ t.getEventSources = getEventSources;
+ t.getEventSourceById = getEventSourceById;
+ t.getEventSourcesByMatchArray = getEventSourcesByMatchArray;
+ t.getEventSourcesByMatch = getEventSourcesByMatch;
t.addEventSource = addEventSource;
t.removeEventSource = removeEventSource;
+ t.removeEventSources = removeEventSources;
t.updateEvent = updateEvent;
t.renderEvent = renderEvent;
t.removeEvents = removeEvents;
@@ -10585,8 +10604,7 @@ function EventManager(options) { // assumed to be a calendar
var stickySource = { events: [] };
var sources = [ stickySource ];
var rangeStart, rangeEnd;
- var currentFetchID = 0;
- var pendingSourceCnt = 0;
+ var pendingSourceCnt = 0; // outstanding fetch requests, max one per source
var cache = []; // holds events that have already been expanded
@@ -10616,23 +10634,58 @@ function EventManager(options) { // assumed to be a calendar
function fetchEvents(start, end) {
rangeStart = start;
rangeEnd = end;
- cache = [];
- var fetchID = ++currentFetchID;
- var len = sources.length;
- pendingSourceCnt = len;
- for (var i=0; i<len; i++) {
- fetchEventSource(sources[i], fetchID);
+ fetchEventSources(sources, 'reset');
+ }
+
+
+ // expects an array of event source objects (the originals, not copies)
+ // `specialFetchType` is an optimization parameter that affects purging of the event cache.
+ function fetchEventSources(specificSources, specialFetchType) {
+ var i, source;
+
+ if (specialFetchType === 'reset') {
+ cache = [];
+ }
+ else if (specialFetchType !== 'add') {
+ cache = excludeEventsBySources(cache, specificSources);
+ }
+
+ for (i = 0; i < specificSources.length; i++) {
+ source = specificSources[i];
+
+ // already-pending sources have already been accounted for in pendingSourceCnt
+ if (source._status !== 'pending') {
+ pendingSourceCnt++;
+ }
+
+ source._fetchId = (source._fetchId || 0) + 1;
+ source._status = 'pending';
+ }
+
+ for (i = 0; i < specificSources.length; i++) {
+ source = specificSources[i];
+
+ tryFetchEventSource(source, source._fetchId);
}
}
-
-
- function fetchEventSource(source, fetchID) {
+
+
+ // fetches an event source and processes its result ONLY if it is still the current fetch.
+ // caller is responsible for incrementing pendingSourceCnt first.
+ function tryFetchEventSource(source, fetchId) {
_fetchEventSource(source, function(eventInputs) {
var isArraySource = $.isArray(source.events);
var i, eventInput;
var abstractEvent;
- if (fetchID == currentFetchID) {
+ if (
+ // is this the source's most recent fetch?
+ // if not, rely on an upcoming fetch of this source to decrement pendingSourceCnt
+ fetchId === source._fetchId &&
+ // event source no longer valid?
+ source._status !== 'rejected'
+ ) {
+ source._status = 'resolved';
if (eventInputs) {
for (i = 0; i < eventInputs.length; i++) {
@@ -10654,13 +10707,29 @@ function EventManager(options) { // assumed to be a calendar
}
}
- pendingSourceCnt--;
- if (!pendingSourceCnt) {
- reportEvents(cache);
- }
+ decrementPendingSourceCnt();
}
});
}
+
+
+ function rejectEventSource(source) {
+ var wasPending = source._status === 'pending';
+
+ source._status = 'rejected';
+
+ if (wasPending) {
+ decrementPendingSourceCnt();
+ }
+ }
+
+
+ function decrementPendingSourceCnt() {
+ pendingSourceCnt--;
+ if (!pendingSourceCnt) {
+ reportEvents(cache);
+ }
+ }
function _fetchEventSource(source, callback) {
@@ -10776,14 +10845,13 @@ function EventManager(options) { // assumed to be a calendar
/* Sources
-----------------------------------------------------------------------------*/
-
+
function addEventSource(sourceInput) {
var source = buildEventSource(sourceInput);
if (source) {
sources.push(source);
- pendingSourceCnt++;
- fetchEventSource(source, currentFetchID); // will eventually call reportEvents
+ fetchEventSources([ source ], 'add'); // will eventually call reportEvents
}
}
@@ -10833,19 +10901,120 @@ function EventManager(options) { // assumed to be a calendar
}
- function removeEventSource(source) {
- sources = $.grep(sources, function(src) {
- return !isSourcesEqual(src, source);
- });
- // remove all client events from that source
- cache = $.grep(cache, function(e) {
- return !isSourcesEqual(e.source, source);
- });
+ function removeEventSource(matchInput) {
+ removeSpecificEventSources(
+ getEventSourcesByMatch(matchInput)
+ );
+ }
+
+
+ // if called with no arguments, removes all.
+ function removeEventSources(matchInputs) {
+ if (matchInputs == null) {
+ removeSpecificEventSources(sources, true); // isAll=true
+ }
+ else {
+ removeSpecificEventSources(
+ getEventSourcesByMatchArray(matchInputs)
+ );
+ }
+ }
+
+
+ function removeSpecificEventSources(targetSources, isAll) {
+ var i;
+
+ // cancel pending requests
+ for (i = 0; i < targetSources.length; i++) {
+ rejectEventSource(targetSources[i]);
+ }
+
+ if (isAll) { // an optimization
+ sources = [];
+ cache = [];
+ }
+ else {
+ // remove from persisted source list
+ sources = $.grep(sources, function(source) {
+ for (i = 0; i < targetSources.length; i++) {
+ if (source === targetSources[i]) {
+ return false; // exclude
+ }
+ }
+ return true; // include
+ });
+
+ cache = excludeEventsBySources(cache, targetSources);
+ }
+
reportEvents(cache);
}
- function isSourcesEqual(source1, source2) {
+ function getEventSources() {
+ return sources.slice(1); // returns a shallow copy of sources with stickySource removed
+ }
+
+
+ function getEventSourceById(id) {
+ return $.grep(sources, function(source) {
+ return source.id && source.id === id;
+ })[0];
+ }
+
+
+ // like getEventSourcesByMatch, but accepts multple match criteria (like multiple IDs)
+ function getEventSourcesByMatchArray(matchInputs) {
+
+ // coerce into an array
+ if (!matchInputs) {
+ matchInputs = [];
+ }
+ else if (!$.isArray(matchInputs)) {
+ matchInputs = [ matchInputs ];
+ }
+
+ var matchingSources = [];
+ var i;
+
+ // resolve raw inputs to real event source objects
+ for (i = 0; i < matchInputs.length; i++) {
+ matchingSources.push.apply( // append
+ matchingSources,
+ getEventSourcesByMatch(matchInputs[i])
+ );
+ }
+
+ return matchingSources;
+ }
+
+
+ // matchInput can either by a real event source object, an ID, or the function/URL for the source.
+ // returns an array of matching source objects.
+ function getEventSourcesByMatch(matchInput) {
+ var i, source;
+
+ // given an proper event source object
+ for (i = 0; i < sources.length; i++) {
+ source = sources[i];
+ if (source === matchInput) {
+ return [ source ];
+ }
+ }
+
+ // an ID match
+ source = getEventSourceById(matchInput);
+ if (source) {
+ return [ source ];
+ }
+
+ return $.grep(sources, function(source) {
+ return isSourcesEquivalent(matchInput, source);
+ });
+ }
+
+
+ function isSourcesEquivalent(source1, source2) {
return source1 && source2 && getSourcePrimitive(source1) == getSourcePrimitive(source2);
}
@@ -10858,6 +11027,20 @@ function EventManager(options) { // assumed to be a calendar
) ||
source; // the given argument *is* the primitive
}
+
+
+ // util
+ // returns a filtered array without events that are part of any of the given sources
+ function excludeEventsBySources(specificEvents, specificSources) {
+ return $.grep(specificEvents, function(event) {
+ for (var i = 0; i < specificSources.length; i++) {
+ if (event.source === specificSources[i]) {
+ return false; // exclude
+ }
+ }
+ return true; // keep
+ });
+ }
diff --git a/library/fullcalendar/fullcalendar.min.css b/library/fullcalendar/fullcalendar.min.css
index 3a251eb19..9f395b445 100644
--- a/library/fullcalendar/fullcalendar.min.css
+++ b/library/fullcalendar/fullcalendar.min.css
@@ -1,5 +1,5 @@
/*!
- * FullCalendar v2.7.3 Stylesheet
+ * FullCalendar v2.8.0 Stylesheet
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
- */.fc-bgevent,.fc-highlight{opacity:.3;filter:alpha(opacity=30)}.fc-icon,body .fc{font-size:1em}.fc-button-group,.fc-icon{display:inline-block}.fc-bg,.fc-row .fc-bgevent-skeleton,.fc-row .fc-highlight-skeleton{bottom:0}.fc-icon,.fc-unselectable{-khtml-user-select:none;-webkit-touch-callout:none}.fc .fc-axis,.fc button,.fc-time-grid-event .fc-time,.fc-time-grid-event.fc-short .fc-content{white-space:nowrap}.fc{direction:ltr;text-align:left}.fc-rtl{text-align:right}.fc th,.fc-basic-view .fc-week-number,.fc-icon,.fc-toolbar{text-align:center}.fc-unthemed .fc-content,.fc-unthemed .fc-divider,.fc-unthemed .fc-popover,.fc-unthemed .fc-row,.fc-unthemed tbody,.fc-unthemed td,.fc-unthemed th,.fc-unthemed thead{border-color:#ddd}.fc-unthemed .fc-popover{background-color:#fff}.fc-unthemed .fc-divider,.fc-unthemed .fc-popover .fc-header{background:#eee}.fc-unthemed .fc-popover .fc-header .fc-close{color:#666}.fc-unthemed .fc-today{background:#fcf8e3}.fc-highlight{background:#bce8f1}.fc-bgevent{background:#8fdf82}.fc-nonbusiness{background:#d7d7d7}.fc-icon{height:1em;line-height:1em;overflow:hidden;font-family:"Courier New",Courier,monospace;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fc-icon:after{position:relative}.fc-icon-left-single-arrow:after{content:"\02039";font-weight:700;font-size:200%;top:-7%}.fc-icon-right-single-arrow:after{content:"\0203A";font-weight:700;font-size:200%;top:-7%}.fc-icon-left-double-arrow:after{content:"\000AB";font-size:160%;top:-7%}.fc-icon-right-double-arrow:after{content:"\000BB";font-size:160%;top:-7%}.fc-icon-left-triangle:after{content:"\25C4";font-size:125%;top:3%}.fc-icon-right-triangle:after{content:"\25BA";font-size:125%;top:3%}.fc-icon-down-triangle:after{content:"\25BC";font-size:125%;top:2%}.fc-icon-x:after{content:"\000D7";font-size:200%;top:6%}.fc button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;height:2.1em;padding:0 .6em;font-size:1em;cursor:pointer}.fc button::-moz-focus-inner{margin:0;padding:0}.fc-state-default{border:1px solid;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.fc-state-default.fc-corner-left{border-top-left-radius:4px;border-bottom-left-radius:4px}.fc-state-default.fc-corner-right{border-top-right-radius:4px;border-bottom-right-radius:4px}.fc button .fc-icon{position:relative;top:-.05em;margin:0 .2em;vertical-align:middle}.fc-state-active,.fc-state-disabled,.fc-state-down,.fc-state-hover{color:#333;background-color:#e6e6e6}.fc-state-hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.fc-state-active,.fc-state-down{background-color:#ccc;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.fc-state-disabled{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);box-shadow:none}.fc-event.fc-draggable,.fc-event[href],.fc-popover .fc-header .fc-close{cursor:pointer}.fc .fc-button-group>*{float:left;margin:0 0 0 -1px}.fc .fc-button-group>:first-child{margin-left:0}.fc-popover{position:absolute;box-shadow:0 2px 6px rgba(0,0,0,.15)}.fc-popover .fc-header{padding:2px 4px}.fc-popover .fc-header .fc-title{margin:0 2px}.fc-ltr .fc-popover .fc-header .fc-title,.fc-rtl .fc-popover .fc-header .fc-close{float:left}.fc-ltr .fc-popover .fc-header .fc-close,.fc-rtl .fc-popover .fc-header .fc-title{float:right}.fc-unthemed .fc-popover{border-width:1px;border-style:solid}.fc-unthemed .fc-popover .fc-header .fc-close{font-size:.9em;margin-top:2px}.fc-popover>.ui-widget-header+.ui-widget-content{border-top:0}.fc-divider{border-style:solid;border-width:1px}hr.fc-divider{height:0;margin:0;padding:0 0 2px;border-width:1px 0}.fc-bg table,.fc-row .fc-bgevent-skeleton table,.fc-row .fc-highlight-skeleton table{height:100%}.fc-clear{clear:both}.fc-bg,.fc-bgevent-skeleton,.fc-helper-skeleton,.fc-highlight-skeleton{position:absolute;top:0;left:0;right:0}.fc table{width:100%;table-layout:fixed;border-collapse:collapse;border-spacing:0;font-size:1em}.fc td,.fc th{border-style:solid;border-width:1px;padding:0;vertical-align:top}.fc td.fc-today{border-style:double}.fc .fc-row{border-style:solid;border-width:0}.fc-row table{border-left:0 hidden transparent;border-right:0 hidden transparent;border-bottom:0 hidden transparent}.fc-row:first-child table{border-top:0 hidden transparent}.fc-row{position:relative}.fc-row .fc-bg{z-index:1}.fc-row .fc-bgevent-skeleton td,.fc-row .fc-highlight-skeleton td{border-color:transparent}.fc-row .fc-bgevent-skeleton{z-index:2}.fc-row .fc-highlight-skeleton{z-index:3}.fc-row .fc-content-skeleton{position:relative;z-index:4;padding-bottom:2px}.fc-row .fc-helper-skeleton{z-index:5}.fc-row .fc-content-skeleton td,.fc-row .fc-helper-skeleton td{background:0 0;border-color:transparent;border-bottom:0}.fc-row .fc-content-skeleton tbody td,.fc-row .fc-helper-skeleton tbody td{border-top:0}.fc-scroller{-webkit-overflow-scrolling:touch}.fc-row.fc-rigid,.fc-time-grid-event{overflow:hidden}.fc-scroller>.fc-day-grid,.fc-scroller>.fc-time-grid{position:relative;width:100%}.fc-event{position:relative;display:block;font-size:.85em;line-height:1.3;border-radius:3px;border:1px solid #3a87ad;background-color:#3a87ad;font-weight:400}.fc-event,.fc-event:hover,.ui-widget .fc-event{color:#fff;text-decoration:none}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc-event .fc-bg{z-index:1;background:#fff;opacity:.25;filter:alpha(opacity=25)}.fc-event .fc-content{position:relative;z-index:2}.fc-event .fc-resizer{position:absolute;z-index:4;display:none}.fc-event.fc-allow-mouse-resize .fc-resizer,.fc-event.fc-selected .fc-resizer{display:block}.fc-event.fc-selected .fc-resizer:before{content:"";position:absolute;z-index:9999;top:50%;left:50%;width:40px;height:40px;margin-left:-20px;margin-top:-20px}.fc-event.fc-selected{z-index:9999!important;box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event.fc-selected.fc-dragging{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-h-event.fc-selected:before{content:"";position:absolute;z-index:3;top:-10px;bottom:-10px;left:0;right:0}.fc-ltr .fc-h-event.fc-not-start,.fc-rtl .fc-h-event.fc-not-end{margin-left:0;border-left-width:0;padding-left:1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-ltr .fc-h-event.fc-not-end,.fc-rtl .fc-h-event.fc-not-start{margin-right:0;border-right-width:0;padding-right:1px;border-top-right-radius:0;border-bottom-right-radius:0}.fc-ltr .fc-h-event .fc-start-resizer,.fc-rtl .fc-h-event .fc-end-resizer{cursor:w-resize;left:-1px}.fc-ltr .fc-h-event .fc-end-resizer,.fc-rtl .fc-h-event .fc-start-resizer{cursor:e-resize;right:-1px}.fc-h-event.fc-allow-mouse-resize .fc-resizer{width:7px;top:-1px;bottom:-1px}.fc-h-event.fc-selected .fc-resizer{border-radius:4px;border-width:1px;width:6px;height:6px;border-style:solid;border-color:inherit;background:#fff;top:50%;margin-top:-4px}.fc-ltr .fc-h-event.fc-selected .fc-start-resizer,.fc-rtl .fc-h-event.fc-selected .fc-end-resizer{margin-left:-4px}.fc-ltr .fc-h-event.fc-selected .fc-end-resizer,.fc-rtl .fc-h-event.fc-selected .fc-start-resizer{margin-right:-4px}.fc-day-grid-event{margin:1px 2px 0;padding:0 1px}.fc-day-grid-event.fc-selected:after{content:"";position:absolute;z-index:1;top:-1px;right:-1px;bottom:-1px;left:-1px;background:#000;opacity:.25;filter:alpha(opacity=25)}.fc-day-grid-event .fc-content{white-space:nowrap;overflow:hidden}.fc-day-grid-event .fc-time{font-weight:700}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer{margin-left:-2px}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer{margin-right:-2px}a.fc-more{margin:1px 3px;font-size:.85em;cursor:pointer;text-decoration:none}a.fc-more:hover{text-decoration:underline}.fc-limited{display:none}.fc-day-grid .fc-row{z-index:1}.fc-more-popover{z-index:2;width:220px}.fc-more-popover .fc-event-container{padding:10px}.fc-now-indicator{position:absolute;border:0 solid red}.fc-unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fc-toolbar{margin-bottom:1em}.fc-toolbar .fc-left{float:left}.fc-toolbar .fc-right{float:right}.fc-toolbar .fc-center{display:inline-block}.fc .fc-toolbar>*>*{float:left;margin-left:.75em}.fc .fc-toolbar>*>:first-child{margin-left:0}.fc-toolbar h2{margin:0}.fc-toolbar button{position:relative}.fc-toolbar .fc-state-hover,.fc-toolbar .ui-state-hover{z-index:2}.fc-toolbar .fc-state-down{z-index:3}.fc-toolbar .fc-state-active,.fc-toolbar .ui-state-active{z-index:4}.fc-toolbar button:focus{z-index:5}.fc-view-container *,.fc-view-container :after,.fc-view-container :before{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.fc-view,.fc-view>table{position:relative;z-index:1}.fc-basicDay-view .fc-content-skeleton,.fc-basicWeek-view .fc-content-skeleton{padding-top:1px;padding-bottom:1em}.fc-basic-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-basic-view .fc-day-number,.fc-basic-view .fc-week-number{padding:0 2px}.fc-basic-view td.fc-day-number,.fc-basic-view td.fc-week-number span{padding-top:2px;padding-bottom:2px}.fc-basic-view .fc-week-number span{display:inline-block;min-width:1.25em}.fc-ltr .fc-basic-view .fc-day-number{text-align:right}.fc-rtl .fc-basic-view .fc-day-number{text-align:left}.fc-day-number.fc-other-month{opacity:.3;filter:alpha(opacity=30)}.fc-agenda-view .fc-day-grid{position:relative;z-index:2}.fc-agenda-view .fc-day-grid .fc-row{min-height:3em}.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton{padding-top:1px;padding-bottom:1em}.fc .fc-axis{vertical-align:middle;padding:0 4px}.fc-ltr .fc-axis{text-align:right}.fc-rtl .fc-axis{text-align:left}.ui-widget td.fc-axis{font-weight:400}.fc-time-grid,.fc-time-grid-container{position:relative;z-index:1}.fc-time-grid{min-height:100%}.fc-time-grid table{border:0 hidden transparent}.fc-time-grid>.fc-bg{z-index:1}.fc-time-grid .fc-slats,.fc-time-grid>hr{position:relative;z-index:2}.fc-time-grid .fc-content-col{position:relative}.fc-time-grid .fc-content-skeleton{position:absolute;z-index:3;top:0;left:0;right:0}.fc-time-grid .fc-business-container{position:relative;z-index:1}.fc-time-grid .fc-bgevent-container{position:relative;z-index:2}.fc-time-grid .fc-highlight-container{z-index:3;position:relative}.fc-time-grid .fc-event-container{position:relative;z-index:4}.fc-time-grid .fc-now-indicator-line{z-index:5}.fc-time-grid .fc-helper-container{position:relative;z-index:6}.fc-time-grid .fc-slats td{height:1.5em;border-bottom:0}.fc-time-grid .fc-slats .fc-minor td{border-top-style:dotted}.fc-time-grid .fc-slats .ui-widget-content{background:0 0}.fc-time-grid .fc-highlight{position:absolute;left:0;right:0}.fc-ltr .fc-time-grid .fc-event-container{margin:0 2.5% 0 2px}.fc-rtl .fc-time-grid .fc-event-container{margin:0 2px 0 2.5%}.fc-time-grid .fc-bgevent,.fc-time-grid .fc-event{position:absolute;z-index:1}.fc-time-grid .fc-bgevent{left:0;right:0}.fc-v-event.fc-not-start{border-top-width:0;padding-top:1px;border-top-left-radius:0;border-top-right-radius:0}.fc-v-event.fc-not-end{border-bottom-width:0;padding-bottom:1px;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-time-grid-event.fc-selected{overflow:visible}.fc-time-grid-event.fc-selected .fc-bg{display:none}.fc-time-grid-event .fc-content{overflow:hidden}.fc-time-grid-event .fc-time,.fc-time-grid-event .fc-title{padding:0 1px}.fc-time-grid-event .fc-time{font-size:.85em}.fc-time-grid-event.fc-short .fc-time,.fc-time-grid-event.fc-short .fc-title{display:inline-block;vertical-align:top}.fc-time-grid-event.fc-short .fc-time span{display:none}.fc-time-grid-event.fc-short .fc-time:before{content:attr(data-start)}.fc-time-grid-event.fc-short .fc-time:after{content:"\000A0-\000A0"}.fc-time-grid-event.fc-short .fc-title{font-size:.85em;padding:0}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer{left:0;right:0;bottom:0;height:8px;overflow:hidden;line-height:8px;font-size:11px;font-family:monospace;text-align:center;cursor:s-resize}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after{content:"="}.fc-time-grid-event.fc-selected .fc-resizer{border-radius:5px;border-width:1px;width:8px;height:8px;border-style:solid;border-color:inherit;background:#fff;left:50%;margin-left:-5px;bottom:-5px}.fc-time-grid .fc-now-indicator-line{border-top-width:1px;left:0;right:0}.fc-time-grid .fc-now-indicator-arrow{margin-top:-5px}.fc-ltr .fc-time-grid .fc-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-rtl .fc-time-grid .fc-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent} \ No newline at end of file
+ */.fc-bgevent,.fc-highlight{opacity:.3;filter:alpha(opacity=30)}.fc-icon,body .fc{font-size:1em}.fc-button-group,.fc-icon{display:inline-block}.fc-bg,.fc-row .fc-bgevent-skeleton,.fc-row .fc-highlight-skeleton{bottom:0}.fc-icon,.fc-unselectable{-khtml-user-select:none;-webkit-touch-callout:none}.fc .fc-axis,.fc button,.fc-time-grid-event .fc-time,.fc-time-grid-event.fc-short .fc-content{white-space:nowrap}.fc{direction:ltr;text-align:left}.fc-rtl{text-align:right}.fc th,.fc-basic-view .fc-week-number,.fc-icon,.fc-toolbar{text-align:center}.fc-unthemed .fc-content,.fc-unthemed .fc-divider,.fc-unthemed .fc-popover,.fc-unthemed .fc-row,.fc-unthemed tbody,.fc-unthemed td,.fc-unthemed th,.fc-unthemed thead{border-color:#ddd}.fc-unthemed .fc-popover{background-color:#fff}.fc-unthemed .fc-divider,.fc-unthemed .fc-popover .fc-header{background:#eee}.fc-unthemed .fc-popover .fc-header .fc-close{color:#666}.fc-unthemed .fc-today{background:#fcf8e3}.fc-highlight{background:#bce8f1}.fc-bgevent{background:#8fdf82}.fc-nonbusiness{background:#d7d7d7}.fc-icon{height:1em;line-height:1em;overflow:hidden;font-family:"Courier New",Courier,monospace;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fc-icon:after{position:relative}.fc-icon-left-single-arrow:after{content:"\02039";font-weight:700;font-size:200%;top:-7%}.fc-icon-right-single-arrow:after{content:"\0203A";font-weight:700;font-size:200%;top:-7%}.fc-icon-left-double-arrow:after{content:"\000AB";font-size:160%;top:-7%}.fc-icon-right-double-arrow:after{content:"\000BB";font-size:160%;top:-7%}.fc-icon-left-triangle:after{content:"\25C4";font-size:125%;top:3%}.fc-icon-right-triangle:after{content:"\25BA";font-size:125%;top:3%}.fc-icon-down-triangle:after{content:"\25BC";font-size:125%;top:2%}.fc-icon-x:after{content:"\000D7";font-size:200%;top:6%}.fc button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;height:2.1em;padding:0 .6em;font-size:1em;cursor:pointer}.fc button::-moz-focus-inner{margin:0;padding:0}.fc-state-default{border:1px solid;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.fc-state-default.fc-corner-left{border-top-left-radius:4px;border-bottom-left-radius:4px}.fc-state-default.fc-corner-right{border-top-right-radius:4px;border-bottom-right-radius:4px}.fc button .fc-icon{position:relative;top:-.05em;margin:0 .2em;vertical-align:middle}.fc-state-active,.fc-state-disabled,.fc-state-down,.fc-state-hover{color:#333;background-color:#e6e6e6}.fc-state-hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.fc-state-active,.fc-state-down{background-color:#ccc;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.fc-state-disabled{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);box-shadow:none}.fc-event.fc-draggable,.fc-event[href],.fc-popover .fc-header .fc-close{cursor:pointer}.fc .fc-button-group>*{float:left;margin:0 0 0 -1px}.fc .fc-button-group>:first-child{margin-left:0}.fc-popover{position:absolute;box-shadow:0 2px 6px rgba(0,0,0,.15)}.fc-popover .fc-header{padding:2px 4px}.fc-popover .fc-header .fc-title{margin:0 2px}.fc-ltr .fc-popover .fc-header .fc-title,.fc-rtl .fc-popover .fc-header .fc-close{float:left}.fc-ltr .fc-popover .fc-header .fc-close,.fc-rtl .fc-popover .fc-header .fc-title{float:right}.fc-unthemed .fc-popover{border-width:1px;border-style:solid}.fc-unthemed .fc-popover .fc-header .fc-close{font-size:.9em;margin-top:2px}.fc-popover>.ui-widget-header+.ui-widget-content{border-top:0}.fc-divider{border-style:solid;border-width:1px}hr.fc-divider{height:0;margin:0;padding:0 0 2px;border-width:1px 0}.fc-bg table,.fc-row .fc-bgevent-skeleton table,.fc-row .fc-highlight-skeleton table{height:100%}.fc-clear{clear:both}.fc-bg,.fc-bgevent-skeleton,.fc-helper-skeleton,.fc-highlight-skeleton{position:absolute;top:0;left:0;right:0}.fc table{width:100%;box-sizing:border-box;table-layout:fixed;border-collapse:collapse;border-spacing:0;font-size:1em}.fc td,.fc th{border-style:solid;border-width:1px;padding:0;vertical-align:top}.fc td.fc-today{border-style:double}.fc .fc-row{border-style:solid;border-width:0}.fc-row table{border-left:0 hidden transparent;border-right:0 hidden transparent;border-bottom:0 hidden transparent}.fc-row:first-child table{border-top:0 hidden transparent}.fc-row{position:relative}.fc-row .fc-bg{z-index:1}.fc-row .fc-bgevent-skeleton td,.fc-row .fc-highlight-skeleton td{border-color:transparent}.fc-row .fc-bgevent-skeleton{z-index:2}.fc-row .fc-highlight-skeleton{z-index:3}.fc-row .fc-content-skeleton{position:relative;z-index:4;padding-bottom:2px}.fc-row .fc-helper-skeleton{z-index:5}.fc-row .fc-content-skeleton td,.fc-row .fc-helper-skeleton td{background:0 0;border-color:transparent;border-bottom:0}.fc-row .fc-content-skeleton tbody td,.fc-row .fc-helper-skeleton tbody td{border-top:0}.fc-scroller{-webkit-overflow-scrolling:touch}.fc-row.fc-rigid,.fc-time-grid-event{overflow:hidden}.fc-scroller>.fc-day-grid,.fc-scroller>.fc-time-grid{position:relative;width:100%}.fc-event{position:relative;display:block;font-size:.85em;line-height:1.3;border-radius:3px;border:1px solid #3a87ad;background-color:#3a87ad;font-weight:400}.fc-event,.fc-event:hover,.ui-widget .fc-event{color:#fff;text-decoration:none}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc-event .fc-bg{z-index:1;background:#fff;opacity:.25;filter:alpha(opacity=25)}.fc-event .fc-content{position:relative;z-index:2}.fc-event .fc-resizer{position:absolute;z-index:4;display:none}.fc-event.fc-allow-mouse-resize .fc-resizer,.fc-event.fc-selected .fc-resizer{display:block}.fc-event.fc-selected .fc-resizer:before{content:"";position:absolute;z-index:9999;top:50%;left:50%;width:40px;height:40px;margin-left:-20px;margin-top:-20px}.fc-event.fc-selected{z-index:9999!important;box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event.fc-selected.fc-dragging{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-h-event.fc-selected:before{content:"";position:absolute;z-index:3;top:-10px;bottom:-10px;left:0;right:0}.fc-ltr .fc-h-event.fc-not-start,.fc-rtl .fc-h-event.fc-not-end{margin-left:0;border-left-width:0;padding-left:1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-ltr .fc-h-event.fc-not-end,.fc-rtl .fc-h-event.fc-not-start{margin-right:0;border-right-width:0;padding-right:1px;border-top-right-radius:0;border-bottom-right-radius:0}.fc-ltr .fc-h-event .fc-start-resizer,.fc-rtl .fc-h-event .fc-end-resizer{cursor:w-resize;left:-1px}.fc-ltr .fc-h-event .fc-end-resizer,.fc-rtl .fc-h-event .fc-start-resizer{cursor:e-resize;right:-1px}.fc-h-event.fc-allow-mouse-resize .fc-resizer{width:7px;top:-1px;bottom:-1px}.fc-h-event.fc-selected .fc-resizer{border-radius:4px;border-width:1px;width:6px;height:6px;border-style:solid;border-color:inherit;background:#fff;top:50%;margin-top:-4px}.fc-ltr .fc-h-event.fc-selected .fc-start-resizer,.fc-rtl .fc-h-event.fc-selected .fc-end-resizer{margin-left:-4px}.fc-ltr .fc-h-event.fc-selected .fc-end-resizer,.fc-rtl .fc-h-event.fc-selected .fc-start-resizer{margin-right:-4px}.fc-day-grid-event{margin:1px 2px 0;padding:0 1px}.fc-day-grid-event.fc-selected:after{content:"";position:absolute;z-index:1;top:-1px;right:-1px;bottom:-1px;left:-1px;background:#000;opacity:.25;filter:alpha(opacity=25)}.fc-day-grid-event .fc-content{white-space:nowrap;overflow:hidden}.fc-day-grid-event .fc-time{font-weight:700}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer{margin-left:-2px}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer{margin-right:-2px}a.fc-more{margin:1px 3px;font-size:.85em;cursor:pointer;text-decoration:none}a.fc-more:hover{text-decoration:underline}.fc-limited{display:none}.fc-day-grid .fc-row{z-index:1}.fc-more-popover{z-index:2;width:220px}.fc-more-popover .fc-event-container{padding:10px}.fc-now-indicator{position:absolute;border:0 solid red}.fc-unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fc-toolbar{margin-bottom:1em}.fc-toolbar .fc-left{float:left}.fc-toolbar .fc-right{float:right}.fc-toolbar .fc-center{display:inline-block}.fc .fc-toolbar>*>*{float:left;margin-left:.75em}.fc .fc-toolbar>*>:first-child{margin-left:0}.fc-toolbar h2{margin:0}.fc-toolbar button{position:relative}.fc-toolbar .fc-state-hover,.fc-toolbar .ui-state-hover{z-index:2}.fc-toolbar .fc-state-down{z-index:3}.fc-toolbar .fc-state-active,.fc-toolbar .ui-state-active{z-index:4}.fc-toolbar button:focus{z-index:5}.fc-view-container *,.fc-view-container :after,.fc-view-container :before{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.fc-view,.fc-view>table{position:relative;z-index:1}.fc-basicDay-view .fc-content-skeleton,.fc-basicWeek-view .fc-content-skeleton{padding-top:1px;padding-bottom:1em}.fc-basic-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-basic-view .fc-day-number,.fc-basic-view .fc-week-number{padding:0 2px}.fc-basic-view td.fc-day-number,.fc-basic-view td.fc-week-number span{padding-top:2px;padding-bottom:2px}.fc-basic-view .fc-week-number span{display:inline-block;min-width:1.25em}.fc-ltr .fc-basic-view .fc-day-number{text-align:right}.fc-rtl .fc-basic-view .fc-day-number{text-align:left}.fc-day-number.fc-other-month{opacity:.3;filter:alpha(opacity=30)}.fc-agenda-view .fc-day-grid{position:relative;z-index:2}.fc-agenda-view .fc-day-grid .fc-row{min-height:3em}.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton{padding-top:1px;padding-bottom:1em}.fc .fc-axis{vertical-align:middle;padding:0 4px}.fc-ltr .fc-axis{text-align:right}.fc-rtl .fc-axis{text-align:left}.ui-widget td.fc-axis{font-weight:400}.fc-time-grid,.fc-time-grid-container{position:relative;z-index:1}.fc-time-grid{min-height:100%}.fc-time-grid table{border:0 hidden transparent}.fc-time-grid>.fc-bg{z-index:1}.fc-time-grid .fc-slats,.fc-time-grid>hr{position:relative;z-index:2}.fc-time-grid .fc-content-col{position:relative}.fc-time-grid .fc-content-skeleton{position:absolute;z-index:3;top:0;left:0;right:0}.fc-time-grid .fc-business-container{position:relative;z-index:1}.fc-time-grid .fc-bgevent-container{position:relative;z-index:2}.fc-time-grid .fc-highlight-container{z-index:3;position:relative}.fc-time-grid .fc-event-container{position:relative;z-index:4}.fc-time-grid .fc-now-indicator-line{z-index:5}.fc-time-grid .fc-helper-container{position:relative;z-index:6}.fc-time-grid .fc-slats td{height:1.5em;border-bottom:0}.fc-time-grid .fc-slats .fc-minor td{border-top-style:dotted}.fc-time-grid .fc-slats .ui-widget-content{background:0 0}.fc-time-grid .fc-highlight{position:absolute;left:0;right:0}.fc-ltr .fc-time-grid .fc-event-container{margin:0 2.5% 0 2px}.fc-rtl .fc-time-grid .fc-event-container{margin:0 2px 0 2.5%}.fc-time-grid .fc-bgevent,.fc-time-grid .fc-event{position:absolute;z-index:1}.fc-time-grid .fc-bgevent{left:0;right:0}.fc-v-event.fc-not-start{border-top-width:0;padding-top:1px;border-top-left-radius:0;border-top-right-radius:0}.fc-v-event.fc-not-end{border-bottom-width:0;padding-bottom:1px;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-time-grid-event.fc-selected{overflow:visible}.fc-time-grid-event.fc-selected .fc-bg{display:none}.fc-time-grid-event .fc-content{overflow:hidden}.fc-time-grid-event .fc-time,.fc-time-grid-event .fc-title{padding:0 1px}.fc-time-grid-event .fc-time{font-size:.85em}.fc-time-grid-event.fc-short .fc-time,.fc-time-grid-event.fc-short .fc-title{display:inline-block;vertical-align:top}.fc-time-grid-event.fc-short .fc-time span{display:none}.fc-time-grid-event.fc-short .fc-time:before{content:attr(data-start)}.fc-time-grid-event.fc-short .fc-time:after{content:"\000A0-\000A0"}.fc-time-grid-event.fc-short .fc-title{font-size:.85em;padding:0}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer{left:0;right:0;bottom:0;height:8px;overflow:hidden;line-height:8px;font-size:11px;font-family:monospace;text-align:center;cursor:s-resize}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after{content:"="}.fc-time-grid-event.fc-selected .fc-resizer{border-radius:5px;border-width:1px;width:8px;height:8px;border-style:solid;border-color:inherit;background:#fff;left:50%;margin-left:-5px;bottom:-5px}.fc-time-grid .fc-now-indicator-line{border-top-width:1px;left:0;right:0}.fc-time-grid .fc-now-indicator-arrow{margin-top:-5px}.fc-ltr .fc-time-grid .fc-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-rtl .fc-time-grid .fc-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent} \ No newline at end of file
diff --git a/library/fullcalendar/fullcalendar.min.js b/library/fullcalendar/fullcalendar.min.js
index f27380229..d05408974 100644
--- a/library/fullcalendar/fullcalendar.min.js
+++ b/library/fullcalendar/fullcalendar.min.js
@@ -1,9 +1,9 @@
/*!
- * FullCalendar v2.7.3
+ * FullCalendar v2.8.0
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
-!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){function c(a){return W(a,Xa)}function d(b){var c,d={views:b.views||{}};return a.each(b,function(b,e){"views"!=b&&(a.isPlainObject(e)&&!/(time|duration|interval)$/i.test(b)&&-1==a.inArray(b,Xa)?(c=null,a.each(e,function(a,e){/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(a)?(d.views[a]||(d.views[a]={}),d.views[a][b]=e):(c||(c={}),c[a]=e)}),c&&(d[b]=c)):d[b]=e)}),d}function e(a,b){b.left&&a.css({"border-left-width":1,"margin-left":b.left-1}),b.right&&a.css({"border-right-width":1,"margin-right":b.right-1})}function f(a){a.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})}function g(){a("body").addClass("fc-not-allowed")}function h(){a("body").removeClass("fc-not-allowed")}function i(b,c,d){var e=Math.floor(c/b.length),f=Math.floor(c-e*(b.length-1)),g=[],h=[],i=[],k=0;j(b),b.each(function(c,d){var j=c===b.length-1?f:e,l=a(d).outerHeight(!0);j>l?(g.push(d),h.push(l),i.push(a(d).height())):k+=l}),d&&(c-=k,e=Math.floor(c/g.length),f=Math.floor(c-e*(g.length-1))),a(g).each(function(b,c){var d=b===g.length-1?f:e,j=h[b],k=i[b],l=d-(j-k);d>j&&a(c).height(l)})}function j(a){a.height("")}function k(b){var c=0;return b.find("> span").each(function(b,d){var e=a(d).outerWidth();e>c&&(c=e)}),c++,b.width(c),c}function l(a,b){var c,d=a.add(b);return d.css({position:"relative",left:-1}),c=a.outerHeight()-b.outerHeight(),d.css({position:"",left:""}),c}function m(b){var c=b.css("position"),d=b.parents().filter(function(){var b=a(this);return/(auto|scroll)/.test(b.css("overflow")+b.css("overflow-y")+b.css("overflow-x"))}).eq(0);return"fixed"!==c&&d.length?d:a(b[0].ownerDocument||document)}function n(a,b){var c=a.offset(),d=c.left-(b?b.left:0),e=c.top-(b?b.top:0);return{left:d,right:d+a.outerWidth(),top:e,bottom:e+a.outerHeight()}}function o(a,b){var c=a.offset(),d=q(a),e=c.left+t(a,"border-left-width")+d.left-(b?b.left:0),f=c.top+t(a,"border-top-width")+d.top-(b?b.top:0);return{left:e,right:e+a[0].clientWidth,top:f,bottom:f+a[0].clientHeight}}function p(a,b){var c=a.offset(),d=c.left+t(a,"border-left-width")+t(a,"padding-left")-(b?b.left:0),e=c.top+t(a,"border-top-width")+t(a,"padding-top")-(b?b.top:0);return{left:d,right:d+a.width(),top:e,bottom:e+a.height()}}function q(a){var b=a.innerWidth()-a[0].clientWidth,c={left:0,right:0,top:0,bottom:a.innerHeight()-a[0].clientHeight};return r()&&"rtl"==a.css("direction")?c.left=b:c.right=b,c}function r(){return null===Ya&&(Ya=s()),Ya}function s(){var b=a("<div><div/></div>").css({position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}).appendTo("body"),c=b.children(),d=c.offset().left>b.offset().left;return b.remove(),d}function t(a,b){return parseFloat(a.css(b))||0}function u(a){return 1==a.which&&!a.ctrlKey}function v(a){if(void 0!==a.pageX)return a.pageX;var b=a.originalEvent.touches;return b?b[0].pageX:void 0}function w(a){if(void 0!==a.pageY)return a.pageY;var b=a.originalEvent.touches;return b?b[0].pageY:void 0}function x(a){return/^touch/.test(a.type)}function y(a){a.addClass("fc-unselectable").on("selectstart",z)}function z(a){a.preventDefault()}function A(a){return window.addEventListener?(window.addEventListener("scroll",a,!0),!0):!1}function B(a){return window.removeEventListener?(window.removeEventListener("scroll",a,!0),!0):!1}function C(a,b){var c={left:Math.max(a.left,b.left),right:Math.min(a.right,b.right),top:Math.max(a.top,b.top),bottom:Math.min(a.bottom,b.bottom)};return c.left<c.right&&c.top<c.bottom?c:!1}function D(a,b){return{left:Math.min(Math.max(a.left,b.left),b.right),top:Math.min(Math.max(a.top,b.top),b.bottom)}}function E(a){return{left:(a.left+a.right)/2,top:(a.top+a.bottom)/2}}function F(a,b){return{left:a.left-b.left,top:a.top-b.top}}function G(b){var c,d,e=[],f=[];for("string"==typeof b?f=b.split(/\s*,\s*/):"function"==typeof b?f=[b]:a.isArray(b)&&(f=b),c=0;c<f.length;c++)d=f[c],"string"==typeof d?e.push("-"==d.charAt(0)?{field:d.substring(1),order:-1}:{field:d,order:1}):"function"==typeof d&&e.push({func:d});return e}function H(a,b,c){var d,e;for(d=0;d<c.length;d++)if(e=I(a,b,c[d]))return e;return 0}function I(a,b,c){return c.func?c.func(a,b):J(a[c.field],b[c.field])*(c.order||1)}function J(b,c){return b||c?null==c?-1:null==b?1:"string"===a.type(b)||"string"===a.type(c)?String(b).localeCompare(String(c)):b-c:0}function K(a,b){var c,d,e,f,g=a.start,h=a.end,i=b.start,j=b.end;return h>i&&j>g?(g>=i?(c=g.clone(),e=!0):(c=i.clone(),e=!1),j>=h?(d=h.clone(),f=!0):(d=j.clone(),f=!1),{start:c,end:d,isStart:e,isEnd:f}):void 0}function L(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days"),ms:a.time()-c.time()})}function M(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days")})}function N(a,c,d){return b.duration(Math.round(a.diff(c,d,!0)),d)}function O(a,b){var c,d,e;for(c=0;c<$a.length&&(d=$a[c],e=P(d,a,b),!(e>=1&&ha(e)));c++);return d}function P(a,c,d){return null!=d?d.diff(c,a,!0):b.isDuration(c)?c.as(a):c.end.diff(c.start,a,!0)}function Q(a,b,c){var d;return T(c)?(b-a)/c:(d=c.asMonths(),Math.abs(d)>=1&&ha(d)?b.diff(a,"months",!0)/d:b.diff(a,"days",!0)/c.asDays())}function R(a,b){var c,d;return T(a)||T(b)?a/b:(c=a.asMonths(),d=b.asMonths(),Math.abs(c)>=1&&ha(c)&&Math.abs(d)>=1&&ha(d)?c/d:a.asDays()/b.asDays())}function S(a,c){var d;return T(a)?b.duration(a*c):(d=a.asMonths(),Math.abs(d)>=1&&ha(d)?b.duration({months:d*c}):b.duration({days:a.asDays()*c}))}function T(a){return Boolean(a.hours()||a.minutes()||a.seconds()||a.milliseconds())}function U(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function V(a){return/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(a)}function W(a,b){var c,d,e,f,g,h,i={};if(b)for(c=0;c<b.length;c++){for(d=b[c],e=[],f=a.length-1;f>=0;f--)if(g=a[f][d],"object"==typeof g)e.unshift(g);else if(void 0!==g){i[d]=g;break}e.length&&(i[d]=W(e))}for(c=a.length-1;c>=0;c--){h=a[c];for(d in h)d in i||(i[d]=h[d])}return i}function X(a){var b=function(){};return b.prototype=a,new b}function Y(a,b){for(var c in a)$(a,c)&&(b[c]=a[c])}function Z(a,b){var c,d,e=["constructor","toString","valueOf"];for(c=0;c<e.length;c++)d=e[c],a[d]!==Object.prototype[d]&&(b[d]=a[d])}function $(a,b){return cb.call(a,b)}function _(b){return/undefined|null|boolean|number|string/.test(a.type(b))}function aa(b,c,d){if(a.isFunction(b)&&(b=[b]),b){var e,f;for(e=0;e<b.length;e++)f=b[e].apply(c,d)||f;return f}}function ba(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]}function ca(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#039;").replace(/"/g,"&quot;").replace(/\n/g,"<br />")}function da(a){return a.replace(/&.*?;/g,"")}function ea(b){var c=[];return a.each(b,function(a,b){null!=b&&c.push(a+":"+b)}),c.join(";")}function fa(a){return a.charAt(0).toUpperCase()+a.slice(1)}function ga(a,b){return a-b}function ha(a){return a%1===0}function ia(a,b){var c=a[b];return function(){return c.apply(a,arguments)}}function ja(a,b,c){var d,e,f,g,h,i=function(){var j=+new Date-g;b>j?d=setTimeout(i,b-j):(d=null,c||(h=a.apply(f,e),f=e=null))};return function(){f=this,e=arguments,g=+new Date;var j=c&&!d;return d||(d=setTimeout(i,b)),j&&(h=a.apply(f,e),f=e=null),h}}function ka(c,d,e){var f,g,h,i,j=c[0],k=1==c.length&&"string"==typeof j;return b.isMoment(j)?(i=b.apply(null,c),ma(j,i)):U(j)||void 0===j?i=b.apply(null,c):(f=!1,g=!1,k?db.test(j)?(j+="-01",c=[j],f=!0,g=!0):(h=eb.exec(j))&&(f=!h[5],g=!0):a.isArray(j)&&(g=!0),i=d||f?b.utc.apply(b,c):b.apply(null,c),f?(i._ambigTime=!0,i._ambigZone=!0):e&&(g?i._ambigZone=!0:k&&(i.utcOffset?i.utcOffset(j):i.zone(j)))),i._fullCalendar=!0,i}function la(a,c){var d,e,f=!1,g=!1,h=a.length,i=[];for(d=0;h>d;d++)e=a[d],b.isMoment(e)||(e=Va.moment.parseZone(e)),f=f||e._ambigTime,g=g||e._ambigZone,i.push(e);for(d=0;h>d;d++)e=i[d],c||!f||e._ambigTime?g&&!e._ambigZone&&(i[d]=e.clone().stripZone()):i[d]=e.clone().stripTime();return i}function ma(a,b){a._ambigTime?b._ambigTime=!0:b._ambigTime&&(b._ambigTime=!1),a._ambigZone?b._ambigZone=!0:b._ambigZone&&(b._ambigZone=!1)}function na(a,b){a.year(b[0]||0).month(b[1]||0).date(b[2]||0).hours(b[3]||0).minutes(b[4]||0).seconds(b[5]||0).milliseconds(b[6]||0)}function oa(a,b){return gb.format.call(a,b)}function pa(a,b){return qa(a,va(b))}function qa(a,b){var c,d="";for(c=0;c<b.length;c++)d+=ra(a,b[c]);return d}function ra(a,b){var c,d;return"string"==typeof b?b:(c=b.token)?hb[c]?hb[c](a):oa(a,c):b.maybe&&(d=qa(a,b.maybe),d.match(/[1-9]/))?d:""}function sa(a,b,c,d,e){var f;return a=Va.moment.parseZone(a),b=Va.moment.parseZone(b),f=(a.localeData||a.lang).call(a),c=f.longDateFormat(c)||c,d=d||" - ",ta(a,b,va(c),d,e)}function ta(a,b,c,d,e){var f,g,h,i,j=a.clone().stripZone(),k=b.clone().stripZone(),l="",m="",n="",o="",p="";for(g=0;g<c.length&&(f=ua(a,b,j,k,c[g]),f!==!1);g++)l+=f;for(h=c.length-1;h>g&&(f=ua(a,b,j,k,c[h]),f!==!1);h--)m=f+m;for(i=g;h>=i;i++)n+=ra(a,c[i]),o+=ra(b,c[i]);return(n||o)&&(p=e?o+d+n:n+d+o),l+p+m}function ua(a,b,c,d,e){var f,g;return"string"==typeof e?e:(f=e.token)&&(g=ib[f.charAt(0)],g&&c.isSame(d,g))?oa(a,f):!1}function va(a){return a in jb?jb[a]:jb[a]=wa(a)}function wa(a){for(var b,c=[],d=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;b=d.exec(a);)b[1]?c.push(b[1]):b[2]?c.push({maybe:wa(b[2])}):b[3]?c.push({token:b[3]}):b[5]&&c.push(b[5]);return c}function xa(){}function ya(a,b){var c;return $(b,"constructor")&&(c=b.constructor),"function"!=typeof c&&(c=b.constructor=function(){a.apply(this,arguments)}),c.prototype=X(a.prototype),Y(b,c.prototype),Z(b,c.prototype),Y(a,c),c}function za(a,b){Y(b,a.prototype)}function Aa(a,b){return a||b?a&&b?a.component===b.component&&Ba(a,b)&&Ba(b,a):!1:!0}function Ba(a,b){for(var c in a)if(!/^(component|left|right|top|bottom)$/.test(c)&&a[c]!==b[c])return!1;return!0}function Ca(a){var b=Ea(a);return"background"===b||"inverse-background"===b}function Da(a){return"inverse-background"===Ea(a)}function Ea(a){return ba((a.source||{}).rendering,a.rendering)}function Fa(a){var b,c,d={};for(b=0;b<a.length;b++)c=a[b],(d[c._id]||(d[c._id]=[])).push(c);return d}function Ga(a,b){return a.start-b.start}function Ha(c){var d,e,f,g,h=Va.dataAttrPrefix;return h&&(h+="-"),d=c.data(h+"event")||null,d&&(d="object"==typeof d?a.extend({},d):{},e=d.start,null==e&&(e=d.time),f=d.duration,g=d.stick,delete d.start,delete d.time,delete d.duration,delete d.stick),null==e&&(e=c.data(h+"start")),null==e&&(e=c.data(h+"time")),null==f&&(f=c.data(h+"duration")),null==g&&(g=c.data(h+"stick")),e=null!=e?b.duration(e):null,f=null!=f?b.duration(f):null,g=Boolean(g),{eventProps:d,startTime:e,duration:f,stick:g}}function Ia(a,b){var c,d;for(c=0;c<b.length;c++)if(d=b[c],d.leftCol<=a.rightCol&&d.rightCol>=a.leftCol)return!0;return!1}function Ja(a,b){return a.leftCol-b.leftCol}function Ka(a){var b,c,d,e=[];for(b=0;b<a.length;b++){for(c=a[b],d=0;d<e.length&&Na(c,e[d]).length;d++);c.level=d,(e[d]||(e[d]=[])).push(c)}return e}function La(a){var b,c,d,e,f;for(b=0;b<a.length;b++)for(c=a[b],d=0;d<c.length;d++)for(e=c[d],e.forwardSegs=[],f=b+1;f<a.length;f++)Na(e,a[f],e.forwardSegs)}function Ma(a){var b,c,d=a.forwardSegs,e=0;if(void 0===a.forwardPressure){for(b=0;b<d.length;b++)c=d[b],Ma(c),e=Math.max(e,1+c.forwardPressure);a.forwardPressure=e}}function Na(a,b,c){c=c||[];for(var d=0;d<b.length;d++)Oa(a,b[d])&&c.push(b[d]);return c}function Oa(a,b){return a.bottom>b.top&&a.top<b.bottom}function Pa(c,d){function e(){T?h()&&(k(),i()):f()}function f(){U=O.theme?"ui":"fc",c.addClass("fc"),O.isRTL?c.addClass("fc-rtl"):c.addClass("fc-ltr"),O.theme?c.addClass("ui-widget"):c.addClass("fc-unthemed"),T=a("<div class='fc-view-container'/>").prependTo(c),R=N.header=new Sa(N,O),S=R.render(),S&&c.prepend(S),i(O.defaultView),O.handleWindowResize&&(Y=ja(m,O.windowResizeDelay),a(window).resize(Y))}function g(){V&&V.removeElement(),R.removeElement(),T.remove(),c.removeClass("fc fc-ltr fc-rtl fc-unthemed ui-widget"),Y&&a(window).unbind("resize",Y)}function h(){return c.is(":visible")}function i(b){ca++,V&&b&&V.type!==b&&(R.deactivateButton(V.type),H(),V.removeElement(),V=N.view=null),!V&&b&&(V=N.view=ba[b]||(ba[b]=N.instantiateView(b)),V.setElement(a("<div class='fc-view fc-"+b+"-view' />").appendTo(T)),R.activateButton(b)),V&&(Z=V.massageCurrentDate(Z),V.displaying&&Z.isWithin(V.intervalStart,V.intervalEnd)||h()&&(V.display(Z),I(),u(),v(),q())),I(),ca--}function j(a){return h()?(a&&l(),ca++,V.updateSize(!0),ca--,!0):void 0}function k(){h()&&l()}function l(){W="number"==typeof O.contentHeight?O.contentHeight:"number"==typeof O.height?O.height-(S?S.outerHeight(!0):0):Math.round(T.width()/Math.max(O.aspectRatio,.5))}function m(a){!ca&&a.target===window&&V.start&&j(!0)&&V.trigger("windowResize",aa)}function n(){p(),r()}function o(){h()&&(H(),V.displayEvents(da),I())}function p(){H(),V.clearEvents(),I()}function q(){!O.lazyFetching||$(V.start,V.end)?r():o()}function r(){_(V.start,V.end)}function s(a){da=a,o()}function t(){o()}function u(){R.updateTitle(V.title)}function v(){var a=N.getNow();a.isWithin(V.intervalStart,V.intervalEnd)?R.disableButton("today"):R.enableButton("today")}function w(a,b){V.select(N.buildSelectSpan.apply(N,arguments))}function x(){V&&V.unselect()}function y(){Z=V.computePrevDate(Z),i()}function z(){Z=V.computeNextDate(Z),i()}function A(){Z.add(-1,"years"),i()}function B(){Z.add(1,"years"),i()}function C(){Z=N.getNow(),i()}function D(a){Z=N.moment(a).stripZone(),i()}function E(a){Z.add(b.duration(a)),i()}function F(a,b){var c;b=b||"day",c=N.getViewSpec(b)||N.getUnitViewSpec(b),Z=a.clone(),i(c?c.type:null)}function G(){return N.applyTimezone(Z)}function H(){T.css({width:"100%",height:T.height(),overflow:"hidden"})}function I(){T.css({width:"",height:"",overflow:""})}function J(){return N}function K(){return V}function L(a,b){return void 0===b?O[a]:void("height"!=a&&"contentHeight"!=a&&"aspectRatio"!=a||(O[a]=b,j(!0)))}function M(a,b){var c=Array.prototype.slice.call(arguments,2);return b=b||aa,this.triggerWith(a,b,c),O[a]?O[a].apply(b,c):void 0}var N=this;N.initOptions(d||{});var O=this.options;N.render=e,N.destroy=g,N.refetchEvents=n,N.reportEvents=s,N.reportEventChange=t,N.rerenderEvents=o,N.changeView=i,N.select=w,N.unselect=x,N.prev=y,N.next=z,N.prevYear=A,N.nextYear=B,N.today=C,N.gotoDate=D,N.incrementDate=E,N.zoomTo=F,N.getDate=G,N.getCalendar=J,N.getView=K,N.option=L,N.trigger=M;var P=X(Ra(O.lang));if(O.monthNames&&(P._months=O.monthNames),O.monthNamesShort&&(P._monthsShort=O.monthNamesShort),O.dayNames&&(P._weekdays=O.dayNames),O.dayNamesShort&&(P._weekdaysShort=O.dayNamesShort),null!=O.firstDay){var Q=X(P._week);Q.dow=O.firstDay,P._week=Q}P._fullCalendar_weekCalc=function(a){return"function"==typeof a?a:"local"===a?a:"iso"===a||"ISO"===a?"ISO":void 0}(O.weekNumberCalculation),N.defaultAllDayEventDuration=b.duration(O.defaultAllDayEventDuration),N.defaultTimedEventDuration=b.duration(O.defaultTimedEventDuration),N.moment=function(){var a;return"local"===O.timezone?(a=Va.moment.apply(null,arguments),a.hasTime()&&a.local()):a="UTC"===O.timezone?Va.moment.utc.apply(null,arguments):Va.moment.parseZone.apply(null,arguments),"_locale"in a?a._locale=P:a._lang=P,a},N.getIsAmbigTimezone=function(){return"local"!==O.timezone&&"UTC"!==O.timezone},N.applyTimezone=function(a){if(!a.hasTime())return a.clone();var b,c=N.moment(a.toArray()),d=a.time()-c.time();return d&&(b=c.clone().add(d),a.time()-b.time()===0&&(c=b)),c},N.getNow=function(){var a=O.now;return"function"==typeof a&&(a=a()),N.moment(a).stripZone()},N.getEventEnd=function(a){return a.end?a.end.clone():N.getDefaultEventEnd(a.allDay,a.start)},N.getDefaultEventEnd=function(a,b){var c=b.clone();return a?c.stripTime().add(N.defaultAllDayEventDuration):c.add(N.defaultTimedEventDuration),N.getIsAmbigTimezone()&&c.stripZone(),c},N.humanizeDuration=function(a){return(a.locale||a.lang).call(a,O.lang).humanize()},Ta.call(N,O);var R,S,T,U,V,W,Y,Z,$=N.isFetchNeeded,_=N.fetchEvents,aa=c[0],ba={},ca=0,da=[];Z=null!=O.defaultDate?N.moment(O.defaultDate).stripZone():N.getNow(),N.getSuggestedViewHeight=function(){return void 0===W&&k(),W},N.isHeightAuto=function(){return"auto"===O.contentHeight||"auto"===O.height},N.freezeContentHeight=H,N.unfreezeContentHeight=I,N.initialize()}function Qa(b){a.each(Cb,function(a,c){null==b[a]&&(b[a]=c(b))})}function Ra(a){var c=b.localeData||b.langData;return c.call(b,a)||c.call(b,"en")}function Sa(b,c){function d(){var b=c.header;return n=c.theme?"ui":"fc",b?o=a("<div class='fc-toolbar'/>").append(f("left")).append(f("right")).append(f("center")).append('<div class="fc-clear"/>'):void 0}function e(){o.remove(),o=a()}function f(d){var e=a('<div class="fc-'+d+'"/>'),f=c.header[d];return f&&a.each(f.split(" "),function(d){var f,g=a(),h=!0;a.each(this.split(","),function(d,e){var f,i,j,k,l,m,o,q,r,s;"title"==e?(g=g.add(a("<h2>&nbsp;</h2>")),h=!1):((f=(b.options.customButtons||{})[e])?(j=function(a){f.click&&f.click.call(s[0],a)},k="",l=f.text):(i=b.getViewSpec(e))?(j=function(){b.changeView(e)},p.push(e),k=i.buttonTextOverride,l=i.buttonTextDefault):b[e]&&(j=function(){b[e]()},k=(b.overrides.buttonText||{})[e],l=c.buttonText[e]),j&&(m=f?f.themeIcon:c.themeButtonIcons[e],o=f?f.icon:c.buttonIcons[e],q=k?ca(k):m&&c.theme?"<span class='ui-icon ui-icon-"+m+"'></span>":o&&!c.theme?"<span class='fc-icon fc-icon-"+o+"'></span>":ca(l),r=["fc-"+e+"-button",n+"-button",n+"-state-default"],s=a('<button type="button" class="'+r.join(" ")+'">'+q+"</button>").click(function(a){s.hasClass(n+"-state-disabled")||(j(a),(s.hasClass(n+"-state-active")||s.hasClass(n+"-state-disabled"))&&s.removeClass(n+"-state-hover"))}).mousedown(function(){s.not("."+n+"-state-active").not("."+n+"-state-disabled").addClass(n+"-state-down")}).mouseup(function(){s.removeClass(n+"-state-down")}).hover(function(){s.not("."+n+"-state-active").not("."+n+"-state-disabled").addClass(n+"-state-hover")},function(){s.removeClass(n+"-state-hover").removeClass(n+"-state-down")}),g=g.add(s)))}),h&&g.first().addClass(n+"-corner-left").end().last().addClass(n+"-corner-right").end(),g.length>1?(f=a("<div/>"),h&&f.addClass("fc-button-group"),f.append(g),e.append(f)):e.append(g)}),e}function g(a){o.find("h2").text(a)}function h(a){o.find(".fc-"+a+"-button").addClass(n+"-state-active")}function i(a){o.find(".fc-"+a+"-button").removeClass(n+"-state-active")}function j(a){o.find(".fc-"+a+"-button").attr("disabled","disabled").addClass(n+"-state-disabled")}function k(a){o.find(".fc-"+a+"-button").removeAttr("disabled").removeClass(n+"-state-disabled")}function l(){return p}var m=this;m.render=d,m.removeElement=e,m.updateTitle=g,m.activateButton=h,m.deactivateButton=i,m.disableButton=j,m.enableButton=k,m.getViewsWithButtons=l;var n,o=a(),p=[]}function Ta(c){function d(a,b){return!I||I>a||b>J}function e(a,b){I=a,J=b,S=[];var c=++Q,d=P.length;R=d;for(var e=0;d>e;e++)f(P[e],c)}function f(b,c){g(b,function(d){var e,f,g,h=a.isArray(b.events);if(c==Q){if(d)for(e=0;e<d.length;e++)f=d[e],g=h?f:s(f,b),g&&S.push.apply(S,w(g));R--,R||K(S)}})}function g(b,d){var e,f,h=Va.sourceFetchers;for(e=0;e<h.length;e++){if(f=h[e].call(H,b,I.clone(),J.clone(),c.timezone,d),f===!0)return;if("object"==typeof f)return void g(f,d)}var i=b.events;if(i)a.isFunction(i)?(H.pushLoading(),i.call(H,I.clone(),J.clone(),c.timezone,function(a){d(a),H.popLoading()})):a.isArray(i)?d(i):d();else{var j=b.url;if(j){var k,l=b.success,m=b.error,n=b.complete;k=a.isFunction(b.data)?b.data():b.data;var o=a.extend({},k||{}),p=ba(b.startParam,c.startParam),q=ba(b.endParam,c.endParam),r=ba(b.timezoneParam,c.timezoneParam);p&&(o[p]=I.format()),q&&(o[q]=J.format()),c.timezone&&"local"!=c.timezone&&(o[r]=c.timezone),H.pushLoading(),a.ajax(a.extend({},Db,b,{data:o,success:function(b){b=b||[];var c=aa(l,this,arguments);a.isArray(c)&&(b=c),d(b)},error:function(){aa(m,this,arguments),d()},complete:function(){aa(n,this,arguments),H.popLoading()}}))}else d()}}function h(a){var b=i(a);b&&(P.push(b),R++,f(b,Q))}function i(b){var c,d,e=Va.sourceNormalizers;if(a.isFunction(b)||a.isArray(b)?c={events:b}:"string"==typeof b?c={url:b}:"object"==typeof b&&(c=a.extend({},b)),c){for(c.className?"string"==typeof c.className&&(c.className=c.className.split(/\s+/)):c.className=[],a.isArray(c.events)&&(c.origArray=c.events,c.events=a.map(c.events,function(a){return s(a,c)})),d=0;d<e.length;d++)e[d].call(H,c);return c}}function j(b){P=a.grep(P,function(a){return!k(a,b)}),S=a.grep(S,function(a){return!k(a.source,b)}),K(S)}function k(a,b){return a&&b&&l(a)==l(b)}function l(a){return("object"==typeof a?a.origArray||a.googleCalendarId||a.url||a.events:null)||a}function m(a){a.start=H.moment(a.start),a.end?a.end=H.moment(a.end):a.end=null,x(a,n(a)),K(S)}function n(b){var c={};return a.each(b,function(a,b){o(a)&&void 0!==b&&_(b)&&(c[a]=b)}),c}function o(a){return!/^_|^(id|allDay|start|end)$/.test(a)}function p(a,b){var c,d,e,f=s(a);if(f){for(c=w(f),d=0;d<c.length;d++)e=c[d],e.source||(b&&(O.events.push(e),e.source=O),S.push(e));return K(S),c}return[]}function q(b){var c,d;for(null==b?b=function(){return!0}:a.isFunction(b)||(c=b+"",b=function(a){return a._id==c}),S=a.grep(S,b,!0),d=0;d<P.length;d++)a.isArray(P[d].events)&&(P[d].events=a.grep(P[d].events,b,!0));K(S)}function r(b){return a.isFunction(b)?a.grep(S,b):null!=b?(b+="",a.grep(S,function(a){return a._id==b})):S}function s(d,e){var f,g,h,i={};if(c.eventDataTransform&&(d=c.eventDataTransform(d)),e&&e.eventDataTransform&&(d=e.eventDataTransform(d)),a.extend(i,d),e&&(i.source=e),i._id=d._id||(void 0===d.id?"_fc"+Eb++:d.id+""),d.className?"string"==typeof d.className?i.className=d.className.split(/\s+/):i.className=d.className:i.className=[],f=d.start||d.date,g=d.end,V(f)&&(f=b.duration(f)),V(g)&&(g=b.duration(g)),d.dow||b.isDuration(f)||b.isDuration(g))i.start=f?b.duration(f):null,i.end=g?b.duration(g):null,i._recurring=!0;else{if(f&&(f=H.moment(f),!f.isValid()))return!1;g&&(g=H.moment(g),g.isValid()||(g=null)),h=d.allDay,void 0===h&&(h=ba(e?e.allDayDefault:void 0,c.allDayDefault)),t(f,g,h,i)}return H.normalizeEvent(i),i}function t(a,b,c,d){d.start=a,d.end=b,d.allDay=c,u(d),Ua(d)}function u(a){v(a),a.end&&!a.end.isAfter(a.start)&&(a.end=null),a.end||(c.forceEventDuration?a.end=H.getDefaultEventEnd(a.allDay,a.start):a.end=null)}function v(a){null==a.allDay&&(a.allDay=!(a.start.hasTime()||a.end&&a.end.hasTime())),a.allDay?(a.start.stripTime(),a.end&&a.end.stripTime()):(a.start.hasTime()||(a.start=H.applyTimezone(a.start.time(0))),a.end&&!a.end.hasTime()&&(a.end=H.applyTimezone(a.end.time(0))))}function w(b,c,d){var e,f,g,h,i,j,k,l,m,n=[];if(c=c||I,d=d||J,b)if(b._recurring){if(f=b.dow)for(e={},g=0;g<f.length;g++)e[f[g]]=!0;for(h=c.clone().stripTime();h.isBefore(d);)e&&!e[h.day()]||(i=b.start,j=b.end,k=h.clone(),l=null,i&&(k=k.time(i)),j&&(l=h.clone().time(j)),m=a.extend({},b),t(k,l,!i&&!j,m),n.push(m)),h.add(1,"days")}else n.push(b);return n}function x(b,c,d){function e(a,b){return d?N(a,b,d):c.allDay?M(a,b):L(a,b)}var f,g,h,i,j,k,l={};return c=c||{},c.start||(c.start=b.start.clone()),void 0===c.end&&(c.end=b.end?b.end.clone():null),null==c.allDay&&(c.allDay=b.allDay),u(c),f={start:b._start.clone(),end:b._end?b._end.clone():H.getDefaultEventEnd(b._allDay,b._start),allDay:c.allDay},u(f),g=null!==b._end&&null===c.end,h=e(c.start,f.start),c.end?(i=e(c.end,f.end),j=i.subtract(h)):j=null,a.each(c,function(a,b){o(a)&&void 0!==b&&(l[a]=b)}),k=y(r(b._id),g,c.allDay,h,j,l),{dateDelta:h,durationDelta:j,undo:k}}function y(b,c,d,e,f,g){var h=H.getIsAmbigTimezone(),i=[];return e&&!e.valueOf()&&(e=null),f&&!f.valueOf()&&(f=null),a.each(b,function(b,j){var k,l;k={start:j.start.clone(),end:j.end?j.end.clone():null,allDay:j.allDay},a.each(g,function(a){k[a]=j[a]}),l={start:j._start,end:j._end,allDay:d},u(l),c?l.end=null:f&&!l.end&&(l.end=H.getDefaultEventEnd(l.allDay,l.start)),e&&(l.start.add(e),l.end&&l.end.add(e)),f&&l.end.add(f),h&&!l.allDay&&(e||f)&&(l.start.stripZone(),l.end&&l.end.stripZone()),a.extend(j,g,l),Ua(j),i.push(function(){a.extend(j,k),Ua(j)})}),function(){for(var a=0;a<i.length;a++)i[a]()}}function z(b){var d,e=c.businessHours,f={className:"fc-nonbusiness",start:"09:00",end:"17:00",dow:[1,2,3,4,5],rendering:"inverse-background"},g=H.getView();return e&&(d=a.extend({},f,"object"==typeof e?e:{})),d?(b&&(d.start=null,d.end=null),w(s(d),g.start,g.end)):[]}function A(a,b){var d=b.source||{},e=ba(b.constraint,d.constraint,c.eventConstraint),f=ba(b.overlap,d.overlap,c.eventOverlap);return D(a,e,f,b)}function B(b,c,d){var e,f;return d&&(e=a.extend({},d,c),f=w(s(e))[0]),f?A(b,f):C(b)}function C(a){return D(a,c.selectConstraint,c.selectOverlap)}function D(a,b,c,d){var e,f,g,h,i,j;if(null!=b){for(e=E(b),f=!1,h=0;h<e.length;h++)if(F(e[h],a)){f=!0;break}if(!f)return!1}for(g=H.getPeerEvents(a,d),h=0;h<g.length;h++)if(i=g[h],G(i,a)){if(c===!1)return!1;if("function"==typeof c&&!c(i,d))return!1;if(d){if(j=ba(i.overlap,(i.source||{}).overlap),j===!1)return!1;if("function"==typeof j&&!j(d,i))return!1}}return!0}function E(a){return"businessHours"===a?z():"object"==typeof a?w(s(a)):r(a)}function F(a,b){var c=a.start.clone().stripZone(),d=H.getEventEnd(a).stripZone();return b.start>=c&&b.end<=d}function G(a,b){var c=a.start.clone().stripZone(),d=H.getEventEnd(a).stripZone();return b.start<d&&b.end>c}var H=this;H.isFetchNeeded=d,H.fetchEvents=e,H.addEventSource=h,H.removeEventSource=j,H.updateEvent=m,H.renderEvent=p,H.removeEvents=q,H.clientEvents=r,H.mutateEvent=x,H.normalizeEventDates=u,H.normalizeEventTimes=v;var I,J,K=H.reportEvents,O={events:[]},P=[O],Q=0,R=0,S=[];a.each((c.events?[c.events]:[]).concat(c.eventSources||[]),function(a,b){var c=i(b);c&&P.push(c)}),H.getBusinessHoursEvents=z,H.isEventSpanAllowed=A,H.isExternalSpanAllowed=B,H.isSelectionSpanAllowed=C,H.getEventCache=function(){return S}}function Ua(a){a._allDay=a.allDay,a._start=a.start.clone(),a._end=a.end?a.end.clone():null}var Va=a.fullCalendar={version:"2.7.3",internalApiVersion:4},Wa=Va.views={};a.fn.fullCalendar=function(b){var c=Array.prototype.slice.call(arguments,1),d=this;return this.each(function(e,f){var g,h=a(f),i=h.data("fullCalendar");"string"==typeof b?i&&a.isFunction(i[b])&&(g=i[b].apply(i,c),e||(d=g),"destroy"===b&&h.removeData("fullCalendar")):i||(i=new yb(h,b),h.data("fullCalendar",i),i.render())}),d};var Xa=["header","buttonText","buttonIcons","themeButtonIcons"];Va.intersectRanges=K,Va.applyAll=aa,Va.debounce=ja,Va.isInt=ha,Va.htmlEscape=ca,Va.cssToStr=ea,Va.proxy=ia,Va.capitaliseFirstLetter=fa,Va.getOuterRect=n,Va.getClientRect=o,Va.getContentRect=p,Va.getScrollbarWidths=q;var Ya=null;Va.preventDefault=z,Va.intersectRects=C,Va.parseFieldSpecs=G,Va.compareByFieldSpecs=H,Va.compareByFieldSpec=I,Va.flexibleCompare=J,Va.computeIntervalUnit=O,Va.divideRangeByDuration=Q,Va.divideDurationByDuration=R,Va.multiplyDuration=S,Va.durationHasTime=T;var Za=["sun","mon","tue","wed","thu","fri","sat"],$a=["year","month","week","day","hour","minute","second","millisecond"];Va.log=function(){var a=window.console;return a&&a.log?a.log.apply(a,arguments):void 0},Va.warn=function(){var a=window.console;return a&&a.warn?a.warn.apply(a,arguments):Va.log.apply(Va,arguments)};var _a,ab,bb,cb={}.hasOwnProperty,db=/^\s*\d{4}-\d\d$/,eb=/^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/,fb=b.fn,gb=a.extend({},fb);Va.moment=function(){return ka(arguments)},Va.moment.utc=function(){var a=ka(arguments,!0);return a.hasTime()&&a.utc(),a},Va.moment.parseZone=function(){return ka(arguments,!0,!0)},fb.clone=function(){var a=gb.clone.apply(this,arguments);return ma(this,a),this._fullCalendar&&(a._fullCalendar=!0),a},fb.week=fb.weeks=function(a){var b=(this._locale||this._lang)._fullCalendar_weekCalc;return null==a&&"function"==typeof b?b(this):"ISO"===b?gb.isoWeek.apply(this,arguments):gb.week.apply(this,arguments)},fb.time=function(a){if(!this._fullCalendar)return gb.time.apply(this,arguments);if(null==a)return b.duration({hours:this.hours(),minutes:this.minutes(),seconds:this.seconds(),milliseconds:this.milliseconds()});this._ambigTime=!1,b.isDuration(a)||b.isMoment(a)||(a=b.duration(a));var c=0;return b.isDuration(a)&&(c=24*Math.floor(a.asDays())),this.hours(c+a.hours()).minutes(a.minutes()).seconds(a.seconds()).milliseconds(a.milliseconds())},fb.stripTime=function(){var a;return this._ambigTime||(a=this.toArray(),this.utc(),ab(this,a.slice(0,3)),this._ambigTime=!0,this._ambigZone=!0),this},fb.hasTime=function(){return!this._ambigTime},fb.stripZone=function(){var a,b;return this._ambigZone||(a=this.toArray(),b=this._ambigTime,this.utc(),ab(this,a),this._ambigTime=b||!1,this._ambigZone=!0),this},fb.hasZone=function(){return!this._ambigZone},fb.local=function(){var a=this.toArray(),b=this._ambigZone;return gb.local.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,b&&bb(this,a),this},fb.utc=function(){return gb.utc.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,this},a.each(["zone","utcOffset"],function(a,b){gb[b]&&(fb[b]=function(a){return null!=a&&(this._ambigTime=!1,this._ambigZone=!1),gb[b].apply(this,arguments)})}),fb.format=function(){return this._fullCalendar&&arguments[0]?pa(this,arguments[0]):this._ambigTime?oa(this,"YYYY-MM-DD"):this._ambigZone?oa(this,"YYYY-MM-DD[T]HH:mm:ss"):gb.format.apply(this,arguments)},fb.toISOString=function(){return this._ambigTime?oa(this,"YYYY-MM-DD"):this._ambigZone?oa(this,"YYYY-MM-DD[T]HH:mm:ss"):gb.toISOString.apply(this,arguments)},fb.isWithin=function(a,b){var c=la([this,a,b]);return c[0]>=c[1]&&c[0]<c[2]},fb.isSame=function(a,b){var c;return this._fullCalendar?b?(c=la([this,a],!0),gb.isSame.call(c[0],c[1],b)):(a=Va.moment.parseZone(a),gb.isSame.call(this,a)&&Boolean(this._ambigTime)===Boolean(a._ambigTime)&&Boolean(this._ambigZone)===Boolean(a._ambigZone)):gb.isSame.apply(this,arguments)},a.each(["isBefore","isAfter"],function(a,b){fb[b]=function(a,c){var d;return this._fullCalendar?(d=la([this,a]),gb[b].call(d[0],d[1],c)):gb[b].apply(this,arguments)}}),_a="_d"in b()&&"updateOffset"in b,ab=_a?function(a,c){a._d.setTime(Date.UTC.apply(Date,c)),b.updateOffset(a,!1)}:na,bb=_a?function(a,c){a._d.setTime(+new Date(c[0]||0,c[1]||0,c[2]||0,c[3]||0,c[4]||0,c[5]||0,c[6]||0)),b.updateOffset(a,!1)}:na;var hb={t:function(a){return oa(a,"a").charAt(0)},T:function(a){return oa(a,"A").charAt(0)}};Va.formatRange=sa;var ib={Y:"year",M:"month",D:"day",d:"day",A:"second",a:"second",T:"second",t:"second",H:"second",h:"second",m:"second",s:"second"},jb={};Va.Class=xa,xa.extend=function(){var a,b,c=arguments.length;for(a=0;c>a;a++)b=arguments[a],c-1>a&&za(this,b);return ya(this,b||{})},xa.mixin=function(a){za(this,a)};var kb=Va.EmitterMixin={on:function(b,c){var d=function(a,b){return c.apply(b.context||this,b.args||[])};return c.guid||(c.guid=a.guid++),d.guid=c.guid,a(this).on(b,d),this},off:function(b,c){return a(this).off(b,c),this},trigger:function(b){var c=Array.prototype.slice.call(arguments,1);return a(this).triggerHandler(b,{args:c}),this},triggerWith:function(b,c,d){return a(this).triggerHandler(b,{context:c,args:d}),this}},lb=Va.ListenerMixin=function(){var b=0,c={listenerId:null,listenTo:function(b,c,d){if("object"==typeof c)for(var e in c)c.hasOwnProperty(e)&&this.listenTo(b,e,c[e]);else"string"==typeof c&&b.on(c+"."+this.getListenerNamespace(),a.proxy(d,this))},stopListeningTo:function(a,b){a.off((b||"")+"."+this.getListenerNamespace())},getListenerNamespace:function(){return null==this.listenerId&&(this.listenerId=b++),"_listener"+this.listenerId}};return c}(),mb={isIgnoringMouse:!1,delayUnignoreMouse:null,initMouseIgnoring:function(a){this.delayUnignoreMouse=ja(ia(this,"unignoreMouse"),a||1e3)},tempIgnoreMouse:function(){this.isIgnoringMouse=!0,this.delayUnignoreMouse()},unignoreMouse:function(){this.isIgnoringMouse=!1;
-}},nb=xa.extend(lb,{isHidden:!0,options:null,el:null,margin:10,constructor:function(a){this.options=a||{}},show:function(){this.isHidden&&(this.el||this.render(),this.el.show(),this.position(),this.isHidden=!1,this.trigger("show"))},hide:function(){this.isHidden||(this.el.hide(),this.isHidden=!0,this.trigger("hide"))},render:function(){var b=this,c=this.options;this.el=a('<div class="fc-popover"/>').addClass(c.className||"").css({top:0,left:0}).append(c.content).appendTo(c.parentEl),this.el.on("click",".fc-close",function(){b.hide()}),c.autoHide&&this.listenTo(a(document),"mousedown",this.documentMousedown)},documentMousedown:function(b){this.el&&!a(b.target).closest(this.el).length&&this.hide()},removeElement:function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(a(document),"mousedown")},position:function(){var b,c,d,e,f,g=this.options,h=this.el.offsetParent().offset(),i=this.el.outerWidth(),j=this.el.outerHeight(),k=a(window),l=m(this.el);e=g.top||0,f=void 0!==g.left?g.left:void 0!==g.right?g.right-i:0,l.is(window)||l.is(document)?(l=k,b=0,c=0):(d=l.offset(),b=d.top,c=d.left),b+=k.scrollTop(),c+=k.scrollLeft(),g.viewportConstrain!==!1&&(e=Math.min(e,b+l.outerHeight()-j-this.margin),e=Math.max(e,b+this.margin),f=Math.min(f,c+l.outerWidth()-i-this.margin),f=Math.max(f,c+this.margin)),this.el.css({top:e-h.top,left:f-h.left})},trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1))}}),ob=Va.CoordCache=xa.extend({els:null,forcedOffsetParentEl:null,origin:null,boundingRect:null,isHorizontal:!1,isVertical:!1,lefts:null,rights:null,tops:null,bottoms:null,constructor:function(b){this.els=a(b.els),this.isHorizontal=b.isHorizontal,this.isVertical=b.isVertical,this.forcedOffsetParentEl=b.offsetParent?a(b.offsetParent):null},build:function(){var a=this.forcedOffsetParentEl||this.els.eq(0).offsetParent();this.origin=a.offset(),this.boundingRect=this.queryBoundingRect(),this.isHorizontal&&this.buildElHorizontals(),this.isVertical&&this.buildElVerticals()},clear:function(){this.origin=null,this.boundingRect=null,this.lefts=null,this.rights=null,this.tops=null,this.bottoms=null},ensureBuilt:function(){this.origin||this.build()},queryBoundingRect:function(){var a=m(this.els.eq(0));return a.is(document)?void 0:o(a)},buildElHorizontals:function(){var b=[],c=[];this.els.each(function(d,e){var f=a(e),g=f.offset().left,h=f.outerWidth();b.push(g),c.push(g+h)}),this.lefts=b,this.rights=c},buildElVerticals:function(){var b=[],c=[];this.els.each(function(d,e){var f=a(e),g=f.offset().top,h=f.outerHeight();b.push(g),c.push(g+h)}),this.tops=b,this.bottoms=c},getHorizontalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.lefts,e=this.rights,f=d.length;if(!c||a>=c.left&&a<c.right)for(b=0;f>b;b++)if(a>=d[b]&&a<e[b])return b},getVerticalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.tops,e=this.bottoms,f=d.length;if(!c||a>=c.top&&a<c.bottom)for(b=0;f>b;b++)if(a>=d[b]&&a<e[b])return b},getLeftOffset:function(a){return this.ensureBuilt(),this.lefts[a]},getLeftPosition:function(a){return this.ensureBuilt(),this.lefts[a]-this.origin.left},getRightOffset:function(a){return this.ensureBuilt(),this.rights[a]},getRightPosition:function(a){return this.ensureBuilt(),this.rights[a]-this.origin.left},getWidth:function(a){return this.ensureBuilt(),this.rights[a]-this.lefts[a]},getTopOffset:function(a){return this.ensureBuilt(),this.tops[a]},getTopPosition:function(a){return this.ensureBuilt(),this.tops[a]-this.origin.top},getBottomOffset:function(a){return this.ensureBuilt(),this.bottoms[a]},getBottomPosition:function(a){return this.ensureBuilt(),this.bottoms[a]-this.origin.top},getHeight:function(a){return this.ensureBuilt(),this.bottoms[a]-this.tops[a]}}),pb=Va.DragListener=xa.extend(lb,mb,{options:null,subjectEl:null,subjectHref:null,originX:null,originY:null,scrollEl:null,isInteracting:!1,isDistanceSurpassed:!1,isDelayEnded:!1,isDragging:!1,isTouch:!1,delay:null,delayTimeoutId:null,minDistance:null,handleTouchScrollProxy:null,constructor:function(a){this.options=a||{},this.handleTouchScrollProxy=ia(this,"handleTouchScroll"),this.initMouseIgnoring(500)},startInteraction:function(b,c){var d=x(b);if("mousedown"===b.type){if(this.isIgnoringMouse)return;if(!u(b))return;b.preventDefault()}this.isInteracting||(c=c||{},this.delay=ba(c.delay,this.options.delay,0),this.minDistance=ba(c.distance,this.options.distance,0),this.subjectEl=this.options.subjectEl,this.isInteracting=!0,this.isTouch=d,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,this.originX=v(b),this.originY=w(b),this.scrollEl=m(a(b.target)),this.bindHandlers(),this.initAutoScroll(),this.handleInteractionStart(b),this.startDelay(b),this.minDistance||this.handleDistanceSurpassed(b))},handleInteractionStart:function(a){this.trigger("interactionStart",a)},endInteraction:function(a,b){this.isInteracting&&(this.endDrag(a),this.delayTimeoutId&&(clearTimeout(this.delayTimeoutId),this.delayTimeoutId=null),this.destroyAutoScroll(),this.unbindHandlers(),this.isInteracting=!1,this.handleInteractionEnd(a,b),this.isTouch&&this.tempIgnoreMouse())},handleInteractionEnd:function(a,b){this.trigger("interactionEnd",a,b||!1)},bindHandlers:function(){var b=this,c=1;this.isTouch?(this.listenTo(a(document),{touchmove:this.handleTouchMove,touchend:this.endInteraction,touchcancel:this.endInteraction,touchstart:function(a){c?c--:b.endInteraction(a,!0)}}),!A(this.handleTouchScrollProxy)&&this.scrollEl&&this.listenTo(this.scrollEl,"scroll",this.handleTouchScroll)):this.listenTo(a(document),{mousemove:this.handleMouseMove,mouseup:this.endInteraction}),this.listenTo(a(document),{selectstart:z,contextmenu:z})},unbindHandlers:function(){this.stopListeningTo(a(document)),B(this.handleTouchScrollProxy),this.scrollEl&&this.stopListeningTo(this.scrollEl,"scroll")},startDrag:function(a,b){this.startInteraction(a,b),this.isDragging||(this.isDragging=!0,this.handleDragStart(a))},handleDragStart:function(a){this.trigger("dragStart",a),this.initHrefHack()},handleMove:function(a){var b,c=v(a)-this.originX,d=w(a)-this.originY,e=this.minDistance;this.isDistanceSurpassed||(b=c*c+d*d,b>=e*e&&this.handleDistanceSurpassed(a)),this.isDragging&&this.handleDrag(c,d,a)},handleDrag:function(a,b,c){this.trigger("drag",a,b,c),this.updateAutoScroll(c)},endDrag:function(a){this.isDragging&&(this.isDragging=!1,this.handleDragEnd(a))},handleDragEnd:function(a){this.trigger("dragEnd",a),this.destroyHrefHack()},startDelay:function(a){var b=this;this.delay?this.delayTimeoutId=setTimeout(function(){b.handleDelayEnd(a)},this.delay):this.handleDelayEnd(a)},handleDelayEnd:function(a){this.isDelayEnded=!0,this.isDistanceSurpassed&&this.startDrag(a)},handleDistanceSurpassed:function(a){this.isDistanceSurpassed=!0,this.isDelayEnded&&this.startDrag(a)},handleTouchMove:function(a){this.isDragging&&a.preventDefault(),this.handleMove(a)},handleMouseMove:function(a){this.handleMove(a)},handleTouchScroll:function(a){this.isDragging||this.endInteraction(a,!0)},initHrefHack:function(){var a=this.subjectEl;(this.subjectHref=a?a.attr("href"):null)&&a.removeAttr("href")},destroyHrefHack:function(){var a=this.subjectEl,b=this.subjectHref;setTimeout(function(){b&&a.attr("href",b)},0)},trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1)),this["_"+a]&&this["_"+a].apply(this,Array.prototype.slice.call(arguments,1))}});pb.mixin({isAutoScroll:!1,scrollBounds:null,scrollTopVel:null,scrollLeftVel:null,scrollIntervalId:null,scrollSensitivity:30,scrollSpeed:200,scrollIntervalMs:50,initAutoScroll:function(){var a=this.scrollEl;this.isAutoScroll=this.options.scroll&&a&&!a.is(window)&&!a.is(document),this.isAutoScroll&&this.listenTo(a,"scroll",ja(this.handleDebouncedScroll,100))},destroyAutoScroll:function(){this.endAutoScroll(),this.isAutoScroll&&this.stopListeningTo(this.scrollEl,"scroll")},computeScrollBounds:function(){this.isAutoScroll&&(this.scrollBounds=n(this.scrollEl))},updateAutoScroll:function(a){var b,c,d,e,f=this.scrollSensitivity,g=this.scrollBounds,h=0,i=0;g&&(b=(f-(w(a)-g.top))/f,c=(f-(g.bottom-w(a)))/f,d=(f-(v(a)-g.left))/f,e=(f-(g.right-v(a)))/f,b>=0&&1>=b?h=b*this.scrollSpeed*-1:c>=0&&1>=c&&(h=c*this.scrollSpeed),d>=0&&1>=d?i=d*this.scrollSpeed*-1:e>=0&&1>=e&&(i=e*this.scrollSpeed)),this.setScrollVel(h,i)},setScrollVel:function(a,b){this.scrollTopVel=a,this.scrollLeftVel=b,this.constrainScrollVel(),!this.scrollTopVel&&!this.scrollLeftVel||this.scrollIntervalId||(this.scrollIntervalId=setInterval(ia(this,"scrollIntervalFunc"),this.scrollIntervalMs))},constrainScrollVel:function(){var a=this.scrollEl;this.scrollTopVel<0?a.scrollTop()<=0&&(this.scrollTopVel=0):this.scrollTopVel>0&&a.scrollTop()+a[0].clientHeight>=a[0].scrollHeight&&(this.scrollTopVel=0),this.scrollLeftVel<0?a.scrollLeft()<=0&&(this.scrollLeftVel=0):this.scrollLeftVel>0&&a.scrollLeft()+a[0].clientWidth>=a[0].scrollWidth&&(this.scrollLeftVel=0)},scrollIntervalFunc:function(){var a=this.scrollEl,b=this.scrollIntervalMs/1e3;this.scrollTopVel&&a.scrollTop(a.scrollTop()+this.scrollTopVel*b),this.scrollLeftVel&&a.scrollLeft(a.scrollLeft()+this.scrollLeftVel*b),this.constrainScrollVel(),this.scrollTopVel||this.scrollLeftVel||this.endAutoScroll()},endAutoScroll:function(){this.scrollIntervalId&&(clearInterval(this.scrollIntervalId),this.scrollIntervalId=null,this.handleScrollEnd())},handleDebouncedScroll:function(){this.scrollIntervalId||this.handleScrollEnd()},handleScrollEnd:function(){}});var qb=pb.extend({component:null,origHit:null,hit:null,coordAdjust:null,constructor:function(a,b){pb.call(this,b),this.component=a},handleInteractionStart:function(a){var b,c,d,e=this.subjectEl;this.computeCoords(),a?(c={left:v(a),top:w(a)},d=c,e&&(b=n(e),d=D(d,b)),this.origHit=this.queryHit(d.left,d.top),e&&this.options.subjectCenter&&(this.origHit&&(b=C(this.origHit,b)||b),d=E(b)),this.coordAdjust=F(d,c)):(this.origHit=null,this.coordAdjust=null),pb.prototype.handleInteractionStart.apply(this,arguments)},computeCoords:function(){this.component.prepareHits(),this.computeScrollBounds()},handleDragStart:function(a){var b;pb.prototype.handleDragStart.apply(this,arguments),b=this.queryHit(v(a),w(a)),b&&this.handleHitOver(b)},handleDrag:function(a,b,c){var d;pb.prototype.handleDrag.apply(this,arguments),d=this.queryHit(v(c),w(c)),Aa(d,this.hit)||(this.hit&&this.handleHitOut(),d&&this.handleHitOver(d))},handleDragEnd:function(){this.handleHitDone(),pb.prototype.handleDragEnd.apply(this,arguments)},handleHitOver:function(a){var b=Aa(a,this.origHit);this.hit=a,this.trigger("hitOver",this.hit,b,this.origHit)},handleHitOut:function(){this.hit&&(this.trigger("hitOut",this.hit),this.handleHitDone(),this.hit=null)},handleHitDone:function(){this.hit&&this.trigger("hitDone",this.hit)},handleInteractionEnd:function(){pb.prototype.handleInteractionEnd.apply(this,arguments),this.origHit=null,this.hit=null,this.component.releaseHits()},handleScrollEnd:function(){pb.prototype.handleScrollEnd.apply(this,arguments),this.computeCoords()},queryHit:function(a,b){return this.coordAdjust&&(a+=this.coordAdjust.left,b+=this.coordAdjust.top),this.component.queryHit(a,b)}}),rb=xa.extend(lb,{options:null,sourceEl:null,el:null,parentEl:null,top0:null,left0:null,y0:null,x0:null,topDelta:null,leftDelta:null,isFollowing:!1,isHidden:!1,isAnimating:!1,constructor:function(b,c){this.options=c=c||{},this.sourceEl=b,this.parentEl=c.parentEl?a(c.parentEl):b.parent()},start:function(b){this.isFollowing||(this.isFollowing=!0,this.y0=w(b),this.x0=v(b),this.topDelta=0,this.leftDelta=0,this.isHidden||this.updatePosition(),x(b)?this.listenTo(a(document),"touchmove",this.handleMove):this.listenTo(a(document),"mousemove",this.handleMove))},stop:function(b,c){function d(){this.isAnimating=!1,e.removeElement(),this.top0=this.left0=null,c&&c()}var e=this,f=this.options.revertDuration;this.isFollowing&&!this.isAnimating&&(this.isFollowing=!1,this.stopListeningTo(a(document)),b&&f&&!this.isHidden?(this.isAnimating=!0,this.el.animate({top:this.top0,left:this.left0},{duration:f,complete:d})):d())},getEl:function(){var a=this.el;return a||(this.sourceEl.width(),a=this.el=this.sourceEl.clone().addClass(this.options.additionalClass||"").css({position:"absolute",visibility:"",display:this.isHidden?"none":"",margin:0,right:"auto",bottom:"auto",width:this.sourceEl.width(),height:this.sourceEl.height(),opacity:this.options.opacity||"",zIndex:this.options.zIndex}),a.addClass("fc-unselectable"),a.appendTo(this.parentEl)),a},removeElement:function(){this.el&&(this.el.remove(),this.el=null)},updatePosition:function(){var a,b;this.getEl(),null===this.top0&&(this.sourceEl.width(),a=this.sourceEl.offset(),b=this.el.offsetParent().offset(),this.top0=a.top-b.top,this.left0=a.left-b.left),this.el.css({top:this.top0+this.topDelta,left:this.left0+this.leftDelta})},handleMove:function(a){this.topDelta=w(a)-this.y0,this.leftDelta=v(a)-this.x0,this.isHidden||this.updatePosition()},hide:function(){this.isHidden||(this.isHidden=!0,this.el&&this.el.hide())},show:function(){this.isHidden&&(this.isHidden=!1,this.updatePosition(),this.getEl().show())}}),sb=Va.Grid=xa.extend(lb,mb,{view:null,isRTL:null,start:null,end:null,el:null,elsByFill:null,eventTimeFormat:null,displayEventTime:null,displayEventEnd:null,minResizeDuration:null,largeUnit:null,dayDragListener:null,segDragListener:null,segResizeListener:null,externalDragListener:null,constructor:function(a){this.view=a,this.isRTL=a.opt("isRTL"),this.elsByFill={},this.dayDragListener=this.buildDayDragListener(),this.initMouseIgnoring()},computeEventTimeFormat:function(){return this.view.opt("smallTimeFormat")},computeDisplayEventTime:function(){return!0},computeDisplayEventEnd:function(){return!0},setRange:function(a){this.start=a.start.clone(),this.end=a.end.clone(),this.rangeUpdated(),this.processRangeOptions()},rangeUpdated:function(){},processRangeOptions:function(){var a,b,c=this.view;this.eventTimeFormat=c.opt("eventTimeFormat")||c.opt("timeFormat")||this.computeEventTimeFormat(),a=c.opt("displayEventTime"),null==a&&(a=this.computeDisplayEventTime()),b=c.opt("displayEventEnd"),null==b&&(b=this.computeDisplayEventEnd()),this.displayEventTime=a,this.displayEventEnd=b},spanToSegs:function(a){},diffDates:function(a,b){return this.largeUnit?N(a,b,this.largeUnit):L(a,b)},prepareHits:function(){},releaseHits:function(){},queryHit:function(a,b){},getHitSpan:function(a){},getHitEl:function(a){},setElement:function(a){this.el=a,y(a),this.bindDayHandler("touchstart",this.dayTouchStart),this.bindDayHandler("mousedown",this.dayMousedown),this.bindSegHandlers(),this.bindGlobalHandlers()},bindDayHandler:function(b,c){var d=this;this.el.on(b,function(b){return a(b.target).is(".fc-event-container *, .fc-more")||a(b.target).closest(".fc-popover").length?void 0:c.call(d,b)})},removeElement:function(){this.unbindGlobalHandlers(),this.clearDragListeners(),this.el.remove()},renderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},bindGlobalHandlers:function(){this.listenTo(a(document),{dragstart:this.externalDragStart,sortstart:this.externalDragStart})},unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},dayMousedown:function(a){this.isIgnoringMouse||this.dayDragListener.startInteraction(a,{})},dayTouchStart:function(a){var b=this.view;(b.isSelected||b.selectedEvent)&&this.tempIgnoreMouse(),this.dayDragListener.startInteraction(a,{delay:this.view.opt("longPressDelay")})},buildDayDragListener:function(){var a,b,c=this,d=this.view,e=d.opt("selectable"),f=new qb(this,{scroll:d.opt("dragScroll"),interactionStart:function(){a=f.origHit},dragStart:function(){d.unselect()},hitOver:function(d,f,h){h&&(f||(a=null),e&&(b=c.computeSelection(c.getHitSpan(h),c.getHitSpan(d)),b?c.renderSelection(b):b===!1&&g()))},hitOut:function(){a=null,b=null,c.unrenderSelection(),h()},interactionEnd:function(e,f){f||(a&&!c.isIgnoringMouse&&d.triggerDayClick(c.getHitSpan(a),c.getHitEl(a),e),b&&d.reportSelection(b,e),h())}});return f},clearDragListeners:function(){this.dayDragListener.endInteraction(),this.segDragListener&&this.segDragListener.endInteraction(),this.segResizeListener&&this.segResizeListener.endInteraction(),this.externalDragListener&&this.externalDragListener.endInteraction()},renderEventLocationHelper:function(a,b){var c=this.fabricateHelperEvent(a,b);return this.renderHelper(c,b)},fabricateHelperEvent:function(a,b){var c=b?X(b.event):{};return c.start=a.start.clone(),c.end=a.end?a.end.clone():null,c.allDay=null,this.view.calendar.normalizeEventDates(c),c.className=(c.className||[]).concat("fc-helper"),b||(c.editable=!1),c},renderHelper:function(a,b){},unrenderHelper:function(){},renderSelection:function(a){this.renderHighlight(a)},unrenderSelection:function(){this.unrenderHighlight()},computeSelection:function(a,b){var c=this.computeSelectionSpan(a,b);return c&&!this.view.calendar.isSelectionSpanAllowed(c)?!1:c},computeSelectionSpan:function(a,b){var c=[a.start,a.end,b.start,b.end];return c.sort(ga),{start:c[0].clone(),end:c[3].clone()}},renderHighlight:function(a){this.renderFill("highlight",this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderFill("highlight")},highlightSegClasses:function(){return["fc-highlight"]},renderBusinessHours:function(){},unrenderBusinessHours:function(){},getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},renderFill:function(a,b){},unrenderFill:function(a){var b=this.elsByFill[a];b&&(b.remove(),delete this.elsByFill[a])},renderFillSegEls:function(b,c){var d,e=this,f=this[b+"SegEl"],g="",h=[];if(c.length){for(d=0;d<c.length;d++)g+=this.fillSegHtml(b,c[d]);a(g).each(function(b,d){var g=c[b],i=a(d);f&&(i=f.call(e,g,i)),i&&(i=a(i),i.is(e.fillSegTag)&&(g.el=i,h.push(g)))})}return h},fillSegTag:"div",fillSegHtml:function(a,b){var c=this[a+"SegClasses"],d=this[a+"SegCss"],e=c?c.call(this,b):[],f=ea(d?d.call(this,b):{});return"<"+this.fillSegTag+(e.length?' class="'+e.join(" ")+'"':"")+(f?' style="'+f+'"':"")+" />"},getDayClasses:function(a){var b=this.view,c=b.calendar.getNow(),d=["fc-"+Za[a.day()]];return 1==b.intervalDuration.as("months")&&a.month()!=b.intervalStart.month()&&d.push("fc-other-month"),a.isSame(c,"day")?d.push("fc-today",b.highlightStateClass):c>a?d.push("fc-past"):d.push("fc-future"),d}});sb.mixin({mousedOverSeg:null,isDraggingSeg:!1,isResizingSeg:!1,isDraggingExternal:!1,segs:null,renderEvents:function(a){var b,c=[],d=[];for(b=0;b<a.length;b++)(Ca(a[b])?c:d).push(a[b]);this.segs=[].concat(this.renderBgEvents(c),this.renderFgEvents(d))},renderBgEvents:function(a){var b=this.eventsToSegs(a);return this.renderBgSegs(b)||b},renderFgEvents:function(a){var b=this.eventsToSegs(a);return this.renderFgSegs(b)||b},unrenderEvents:function(){this.handleSegMouseout(),this.clearDragListeners(),this.unrenderFgSegs(),this.unrenderBgSegs(),this.segs=null},getEventSegs:function(){return this.segs||[]},renderFgSegs:function(a){},unrenderFgSegs:function(){},renderFgSegEls:function(b,c){var d,e=this.view,f="",g=[];if(b.length){for(d=0;d<b.length;d++)f+=this.fgSegHtml(b[d],c);a(f).each(function(c,d){var f=b[c],h=e.resolveEventEl(f.event,a(d));h&&(h.data("fc-seg",f),f.el=h,g.push(f))})}return g},fgSegHtml:function(a,b){},renderBgSegs:function(a){return this.renderFill("bgEvent",a)},unrenderBgSegs:function(){this.unrenderFill("bgEvent")},bgEventSegEl:function(a,b){return this.view.resolveEventEl(a.event,b)},bgEventSegClasses:function(a){var b=a.event,c=b.source||{};return["fc-bgevent"].concat(b.className,c.className||[])},bgEventSegCss:function(a){return{"background-color":this.getSegSkinCss(a)["background-color"]}},businessHoursSegClasses:function(a){return["fc-nonbusiness","fc-bgevent"]},bindSegHandlers:function(){this.bindSegHandler("touchstart",this.handleSegTouchStart),this.bindSegHandler("touchend",this.handleSegTouchEnd),this.bindSegHandler("mouseenter",this.handleSegMouseover),this.bindSegHandler("mouseleave",this.handleSegMouseout),this.bindSegHandler("mousedown",this.handleSegMousedown),this.bindSegHandler("click",this.handleSegClick)},bindSegHandler:function(b,c){var d=this;this.el.on(b,".fc-event-container > *",function(b){var e=a(this).data("fc-seg");return!e||d.isDraggingSeg||d.isResizingSeg?void 0:c.call(d,e,b)})},handleSegClick:function(a,b){return this.view.trigger("eventClick",a.el[0],a.event,b)},handleSegMouseover:function(a,b){this.isIgnoringMouse||this.mousedOverSeg||(this.mousedOverSeg=a,a.el.addClass("fc-allow-mouse-resize"),this.view.trigger("eventMouseover",a.el[0],a.event,b))},handleSegMouseout:function(a,b){b=b||{},this.mousedOverSeg&&(a=a||this.mousedOverSeg,this.mousedOverSeg=null,a.el.removeClass("fc-allow-mouse-resize"),this.view.trigger("eventMouseout",a.el[0],a.event,b))},handleSegMousedown:function(a,b){var c=this.startSegResize(a,b,{distance:5});!c&&this.view.isEventDraggable(a.event)&&this.buildSegDragListener(a).startInteraction(b,{distance:5})},handleSegTouchStart:function(a,b){var c,d=this.view,e=a.event,f=d.isEventSelected(e),g=d.isEventDraggable(e),h=d.isEventResizable(e),i=!1;f&&h&&(i=this.startSegResize(a,b)),i||!g&&!h||(c=g?this.buildSegDragListener(a):this.buildSegSelectListener(a),c.startInteraction(b,{delay:f?0:this.view.opt("longPressDelay")})),this.tempIgnoreMouse()},handleSegTouchEnd:function(a,b){this.tempIgnoreMouse()},startSegResize:function(b,c,d){return a(c.target).is(".fc-resizer")?(this.buildSegResizeListener(b,a(c.target).is(".fc-start-resizer")).startInteraction(c,d),!0):!1},buildSegDragListener:function(a){var b,c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event;if(this.segDragListener)return this.segDragListener;var l=this.segDragListener=new qb(f,{scroll:f.opt("dragScroll"),subjectEl:j,subjectCenter:!0,interactionStart:function(d){b=!1,c=new rb(a.el,{additionalClass:"fc-dragging",parentEl:f.el,opacity:l.isTouch?null:f.opt("dragOpacity"),revertDuration:f.opt("dragRevertDuration"),zIndex:2}),c.hide(),c.start(d)},dragStart:function(c){l.isTouch&&!f.isEventSelected(k)&&f.selectEvent(k),b=!0,e.handleSegMouseout(a,c),e.segDragStart(a,c),f.hideEvent(k)},hitOver:function(b,h,j){var m;a.hit&&(j=a.hit),d=e.computeEventDrop(j.component.getHitSpan(j),b.component.getHitSpan(b),k),d&&!i.isEventSpanAllowed(e.eventToSpan(d),k)&&(g(),d=null),d&&(m=f.renderDrag(d,a))?(m.addClass("fc-dragging"),l.isTouch||e.applyDragOpacity(m),c.hide()):c.show(),h&&(d=null)},hitOut:function(){f.unrenderDrag(),c.show(),d=null},hitDone:function(){h()},interactionEnd:function(g){c.stop(!d,function(){b&&(f.unrenderDrag(),f.showEvent(k),e.segDragStop(a,g)),d&&f.reportEventDrop(k,d,this.largeUnit,j,g)}),e.segDragListener=null}});return l},buildSegSelectListener:function(a){var b=this,c=this.view,d=a.event;if(this.segDragListener)return this.segDragListener;var e=this.segDragListener=new pb({dragStart:function(a){e.isTouch&&!c.isEventSelected(d)&&c.selectEvent(d)},interactionEnd:function(a){b.segDragListener=null}});return e},segDragStart:function(a,b){this.isDraggingSeg=!0,this.view.trigger("eventDragStart",a.el[0],a.event,b,{})},segDragStop:function(a,b){this.isDraggingSeg=!1,this.view.trigger("eventDragStop",a.el[0],a.event,b,{})},computeEventDrop:function(a,b,c){var d,e,f=this.view.calendar,g=a.start,h=b.start;return g.hasTime()===h.hasTime()?(d=this.diffDates(h,g),c.allDay&&T(d)?(e={start:c.start.clone(),end:f.getEventEnd(c),allDay:!1},f.normalizeEventTimes(e)):e={start:c.start.clone(),end:c.end?c.end.clone():null,allDay:c.allDay},e.start.add(d),e.end&&e.end.add(d)):e={start:h.clone(),end:null,allDay:!h.hasTime()},e},applyDragOpacity:function(a){var b=this.view.opt("dragOpacity");null!=b&&a.each(function(a,c){c.style.opacity=b})},externalDragStart:function(b,c){var d,e,f=this.view;f.opt("droppable")&&(d=a((c?c.item:null)||b.target),e=f.opt("dropAccept"),(a.isFunction(e)?e.call(d[0],d):d.is(e))&&(this.isDraggingExternal||this.listenToExternalDrag(d,b,c)))},listenToExternalDrag:function(a,b,c){var d,e=this,f=this.view.calendar,i=Ha(a),j=e.externalDragListener=new qb(this,{interactionStart:function(){e.isDraggingExternal=!0},hitOver:function(a){d=e.computeExternalDrop(a.component.getHitSpan(a),i),d&&!f.isExternalSpanAllowed(e.eventToSpan(d),d,i.eventProps)&&(g(),d=null),d&&e.renderDrag(d)},hitOut:function(){d=null},hitDone:function(){h(),e.unrenderDrag()},interactionEnd:function(b){d&&e.view.reportExternalDrop(i,d,a,b,c),e.isDraggingExternal=!1,e.externalDragListener=null}});j.startDrag(b)},computeExternalDrop:function(a,b){var c=this.view.calendar,d={start:c.applyTimezone(a.start),end:null};return b.startTime&&!d.start.hasTime()&&d.start.time(b.startTime),b.duration&&(d.end=d.start.clone().add(b.duration)),d},renderDrag:function(a,b){},unrenderDrag:function(){},buildSegResizeListener:function(a,b){var c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event,l=i.getEventEnd(k),m=this.segResizeListener=new qb(this,{scroll:f.opt("dragScroll"),subjectEl:j,interactionStart:function(){c=!1},dragStart:function(b){c=!0,e.handleSegMouseout(a,b),e.segResizeStart(a,b)},hitOver:function(c,h,j){var m=e.getHitSpan(j),n=e.getHitSpan(c);d=b?e.computeEventStartResize(m,n,k):e.computeEventEndResize(m,n,k),d&&(i.isEventSpanAllowed(e.eventToSpan(d),k)?d.start.isSame(k.start)&&d.end.isSame(l)&&(d=null):(g(),d=null)),d&&(f.hideEvent(k),e.renderEventResize(d,a))},hitOut:function(){d=null},hitDone:function(){e.unrenderEventResize(),f.showEvent(k),h()},interactionEnd:function(b){c&&e.segResizeStop(a,b),d&&f.reportEventResize(k,d,this.largeUnit,j,b),e.segResizeListener=null}});return m},segResizeStart:function(a,b){this.isResizingSeg=!0,this.view.trigger("eventResizeStart",a.el[0],a.event,b,{})},segResizeStop:function(a,b){this.isResizingSeg=!1,this.view.trigger("eventResizeStop",a.el[0],a.event,b,{})},computeEventStartResize:function(a,b,c){return this.computeEventResize("start",a,b,c)},computeEventEndResize:function(a,b,c){return this.computeEventResize("end",a,b,c)},computeEventResize:function(a,b,c,d){var e,f,g=this.view.calendar,h=this.diffDates(c[a],b[a]);return e={start:d.start.clone(),end:g.getEventEnd(d),allDay:d.allDay},e.allDay&&T(h)&&(e.allDay=!1,g.normalizeEventTimes(e)),e[a].add(h),e.start.isBefore(e.end)||(f=this.minResizeDuration||(d.allDay?g.defaultAllDayEventDuration:g.defaultTimedEventDuration),"start"==a?e.start=e.end.clone().subtract(f):e.end=e.start.clone().add(f)),e},renderEventResize:function(a,b){},unrenderEventResize:function(){},getEventTimeText:function(a,b,c){return null==b&&(b=this.eventTimeFormat),null==c&&(c=this.displayEventEnd),this.displayEventTime&&a.start.hasTime()?c&&a.end?this.view.formatRange(a,b):a.start.format(b):""},getSegClasses:function(a,b,c){var d=this.view,e=a.event,f=["fc-event",a.isStart?"fc-start":"fc-not-start",a.isEnd?"fc-end":"fc-not-end"].concat(e.className,e.source?e.source.className:[]);return b&&f.push("fc-draggable"),c&&f.push("fc-resizable"),d.isEventSelected(e)&&f.push("fc-selected"),f},getSegSkinCss:function(a){var b=a.event,c=this.view,d=b.source||{},e=b.color,f=d.color,g=c.opt("eventColor");return{"background-color":b.backgroundColor||e||d.backgroundColor||f||c.opt("eventBackgroundColor")||g,"border-color":b.borderColor||e||d.borderColor||f||c.opt("eventBorderColor")||g,color:b.textColor||d.textColor||c.opt("eventTextColor")}},eventToSegs:function(a){return this.eventsToSegs([a])},eventToSpan:function(a){return this.eventToSpans(a)[0]},eventToSpans:function(a){var b=this.eventToRange(a);return this.eventRangeToSpans(b,a)},eventsToSegs:function(b,c){var d=this,e=Fa(b),f=[];return a.each(e,function(a,b){var e,g=[];for(e=0;e<b.length;e++)g.push(d.eventToRange(b[e]));if(Da(b[0]))for(g=d.invertRanges(g),e=0;e<g.length;e++)f.push.apply(f,d.eventRangeToSegs(g[e],b[0],c));else for(e=0;e<g.length;e++)f.push.apply(f,d.eventRangeToSegs(g[e],b[e],c))}),f},eventToRange:function(a){return{start:a.start.clone().stripZone(),end:(a.end?a.end.clone():this.view.calendar.getDefaultEventEnd(null!=a.allDay?a.allDay:!a.start.hasTime(),a.start)).stripZone()}},eventRangeToSegs:function(a,b,c){var d,e=this.eventRangeToSpans(a,b),f=[];for(d=0;d<e.length;d++)f.push.apply(f,this.eventSpanToSegs(e[d],b,c));return f},eventRangeToSpans:function(b,c){return[a.extend({},b)]},eventSpanToSegs:function(a,b,c){var d,e,f=c?c(a):this.spanToSegs(a);for(d=0;d<f.length;d++)e=f[d],e.event=b,e.eventStartMS=+a.start,e.eventDurationMS=a.end-a.start;return f},invertRanges:function(a){var b,c,d=this.view,e=d.start.clone(),f=d.end.clone(),g=[],h=e;for(a.sort(Ga),b=0;b<a.length;b++)c=a[b],c.start>h&&g.push({start:h,end:c.start}),h=c.end;return f>h&&g.push({start:h,end:f}),g},sortEventSegs:function(a){a.sort(ia(this,"compareEventSegs"))},compareEventSegs:function(a,b){return a.eventStartMS-b.eventStartMS||b.eventDurationMS-a.eventDurationMS||b.event.allDay-a.event.allDay||H(a.event,b.event,this.view.eventOrderSpecs)}}),Va.isBgEvent=Ca,Va.dataAttrPrefix="";var tb=Va.DayTableMixin={breakOnWeeks:!1,dayDates:null,dayIndices:null,daysPerRow:null,rowCnt:null,colCnt:null,colHeadFormat:null,updateDayTable:function(){for(var a,b,c,d=this.view,e=this.start.clone(),f=-1,g=[],h=[];e.isBefore(this.end);)d.isHiddenDay(e)?g.push(f+.5):(f++,g.push(f),h.push(e.clone())),e.add(1,"days");if(this.breakOnWeeks){for(b=h[0].day(),a=1;a<h.length&&h[a].day()!=b;a++);c=Math.ceil(h.length/a)}else c=1,a=h.length;this.dayDates=h,this.dayIndices=g,this.daysPerRow=a,this.rowCnt=c,this.updateDayTableCols()},updateDayTableCols:function(){this.colCnt=this.computeColCnt(),this.colHeadFormat=this.view.opt("columnFormat")||this.computeColHeadFormat()},computeColCnt:function(){return this.daysPerRow},getCellDate:function(a,b){return this.dayDates[this.getCellDayIndex(a,b)].clone()},getCellRange:function(a,b){var c=this.getCellDate(a,b),d=c.clone().add(1,"days");return{start:c,end:d}},getCellDayIndex:function(a,b){return a*this.daysPerRow+this.getColDayIndex(b)},getColDayIndex:function(a){return this.isRTL?this.colCnt-1-a:a},getDateDayIndex:function(a){var b=this.dayIndices,c=a.diff(this.start,"days");return 0>c?b[0]-1:c>=b.length?b[b.length-1]+1:b[c]},computeColHeadFormat:function(){return this.rowCnt>1||this.colCnt>10?"ddd":this.colCnt>1?this.view.opt("dayOfMonthFormat"):"dddd"},sliceRangeByRow:function(a){var b,c,d,e,f,g=this.daysPerRow,h=this.view.computeDayRange(a),i=this.getDateDayIndex(h.start),j=this.getDateDayIndex(h.end.clone().subtract(1,"days")),k=[];for(b=0;b<this.rowCnt;b++)c=b*g,d=c+g-1,e=Math.max(i,c),f=Math.min(j,d),e=Math.ceil(e),f=Math.floor(f),f>=e&&k.push({row:b,firstRowDayIndex:e-c,lastRowDayIndex:f-c,isStart:e===i,isEnd:f===j});return k},sliceRangeByDay:function(a){var b,c,d,e,f,g,h=this.daysPerRow,i=this.view.computeDayRange(a),j=this.getDateDayIndex(i.start),k=this.getDateDayIndex(i.end.clone().subtract(1,"days")),l=[];for(b=0;b<this.rowCnt;b++)for(c=b*h,d=c+h-1,e=c;d>=e;e++)f=Math.max(j,e),g=Math.min(k,e),f=Math.ceil(f),g=Math.floor(g),g>=f&&l.push({row:b,firstRowDayIndex:f-c,lastRowDayIndex:g-c,isStart:f===j,isEnd:g===k});return l},renderHeadHtml:function(){var a=this.view;return'<div class="fc-row '+a.widgetHeaderClass+'"><table><thead>'+this.renderHeadTrHtml()+"</thead></table></div>"},renderHeadIntroHtml:function(){return this.renderIntroHtml()},renderHeadTrHtml:function(){return"<tr>"+(this.isRTL?"":this.renderHeadIntroHtml())+this.renderHeadDateCellsHtml()+(this.isRTL?this.renderHeadIntroHtml():"")+"</tr>"},renderHeadDateCellsHtml:function(){var a,b,c=[];for(a=0;a<this.colCnt;a++)b=this.getCellDate(0,a),c.push(this.renderHeadDateCellHtml(b));return c.join("")},renderHeadDateCellHtml:function(a,b,c){var d=this.view;return'<th class="fc-day-header '+d.widgetHeaderClass+" fc-"+Za[a.day()]+'"'+(1==this.rowCnt?' data-date="'+a.format("YYYY-MM-DD")+'"':"")+(b>1?' colspan="'+b+'"':"")+(c?" "+c:"")+">"+ca(a.format(this.colHeadFormat))+"</th>"},renderBgTrHtml:function(a){return"<tr>"+(this.isRTL?"":this.renderBgIntroHtml(a))+this.renderBgCellsHtml(a)+(this.isRTL?this.renderBgIntroHtml(a):"")+"</tr>";
-},renderBgIntroHtml:function(a){return this.renderIntroHtml()},renderBgCellsHtml:function(a){var b,c,d=[];for(b=0;b<this.colCnt;b++)c=this.getCellDate(a,b),d.push(this.renderBgCellHtml(c));return d.join("")},renderBgCellHtml:function(a,b){var c=this.view,d=this.getDayClasses(a);return d.unshift("fc-day",c.widgetContentClass),'<td class="'+d.join(" ")+'" data-date="'+a.format("YYYY-MM-DD")+'"'+(b?" "+b:"")+"></td>"},renderIntroHtml:function(){},bookendCells:function(a){var b=this.renderIntroHtml();b&&(this.isRTL?a.append(b):a.prepend(b))}},ub=Va.DayGrid=sb.extend(tb,{numbersVisible:!1,bottomCoordPadding:0,rowEls:null,cellEls:null,helperEls:null,rowCoordCache:null,colCoordCache:null,renderDates:function(a){var b,c,d=this.view,e=this.rowCnt,f=this.colCnt,g="";for(b=0;e>b;b++)g+=this.renderDayRowHtml(b,a);for(this.el.html(g),this.rowEls=this.el.find(".fc-row"),this.cellEls=this.el.find(".fc-day"),this.rowCoordCache=new ob({els:this.rowEls,isVertical:!0}),this.colCoordCache=new ob({els:this.cellEls.slice(0,this.colCnt),isHorizontal:!0}),b=0;e>b;b++)for(c=0;f>c;c++)d.trigger("dayRender",null,this.getCellDate(b,c),this.getCellEl(b,c))},unrenderDates:function(){this.removeSegPopover()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(!0),b=this.eventsToSegs(a);this.renderFill("businessHours",b,"bgevent")},renderDayRowHtml:function(a,b){var c=this.view,d=["fc-row","fc-week",c.widgetContentClass];return b&&d.push("fc-rigid"),'<div class="'+d.join(" ")+'"><div class="fc-bg"><table>'+this.renderBgTrHtml(a)+'</table></div><div class="fc-content-skeleton"><table>'+(this.numbersVisible?"<thead>"+this.renderNumberTrHtml(a)+"</thead>":"")+"</table></div></div>"},renderNumberTrHtml:function(a){return"<tr>"+(this.isRTL?"":this.renderNumberIntroHtml(a))+this.renderNumberCellsHtml(a)+(this.isRTL?this.renderNumberIntroHtml(a):"")+"</tr>"},renderNumberIntroHtml:function(a){return this.renderIntroHtml()},renderNumberCellsHtml:function(a){var b,c,d=[];for(b=0;b<this.colCnt;b++)c=this.getCellDate(a,b),d.push(this.renderNumberCellHtml(c));return d.join("")},renderNumberCellHtml:function(a){var b;return this.view.dayNumbersVisible?(b=this.getDayClasses(a),b.unshift("fc-day-number"),'<td class="'+b.join(" ")+'" data-date="'+a.format()+'">'+a.date()+"</td>"):"<td/>"},computeEventTimeFormat:function(){return this.view.opt("extraSmallTimeFormat")},computeDisplayEventEnd:function(){return 1==this.colCnt},rangeUpdated:function(){this.updateDayTable()},spanToSegs:function(a){var b,c,d=this.sliceRangeByRow(a);for(b=0;b<d.length;b++)c=d[b],this.isRTL?(c.leftCol=this.daysPerRow-1-c.lastRowDayIndex,c.rightCol=this.daysPerRow-1-c.firstRowDayIndex):(c.leftCol=c.firstRowDayIndex,c.rightCol=c.lastRowDayIndex);return d},prepareHits:function(){this.colCoordCache.build(),this.rowCoordCache.build(),this.rowCoordCache.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},releaseHits:function(){this.colCoordCache.clear(),this.rowCoordCache.clear()},queryHit:function(a,b){var c=this.colCoordCache.getHorizontalIndex(a),d=this.rowCoordCache.getVerticalIndex(b);return null!=d&&null!=c?this.getCellHit(d,c):void 0},getHitSpan:function(a){return this.getCellRange(a.row,a.col)},getHitEl:function(a){return this.getCellEl(a.row,a.col)},getCellHit:function(a,b){return{row:a,col:b,component:this,left:this.colCoordCache.getLeftOffset(b),right:this.colCoordCache.getRightOffset(b),top:this.rowCoordCache.getTopOffset(a),bottom:this.rowCoordCache.getBottomOffset(a)}},getCellEl:function(a,b){return this.cellEls.eq(a*this.colCnt+b)},renderDrag:function(a,b){return this.renderHighlight(this.eventToSpan(a)),b&&!b.el.closest(this.el).length?this.renderEventLocationHelper(a,b):void 0},unrenderDrag:function(){this.unrenderHighlight(),this.unrenderHelper()},renderEventResize:function(a,b){return this.renderHighlight(this.eventToSpan(a)),this.renderEventLocationHelper(a,b)},unrenderEventResize:function(){this.unrenderHighlight(),this.unrenderHelper()},renderHelper:function(b,c){var d,e=[],f=this.eventToSegs(b);return f=this.renderFgSegEls(f),d=this.renderSegRows(f),this.rowEls.each(function(b,f){var g,h=a(f),i=a('<div class="fc-helper-skeleton"><table/></div>');g=c&&c.row===b?c.el.position().top:h.find(".fc-content-skeleton tbody").position().top,i.css("top",g).find("table").append(d[b].tbodyEl),h.append(i),e.push(i[0])}),this.helperEls=a(e)},unrenderHelper:function(){this.helperEls&&(this.helperEls.remove(),this.helperEls=null)},fillSegTag:"td",renderFill:function(b,c,d){var e,f,g,h=[];for(c=this.renderFillSegEls(b,c),e=0;e<c.length;e++)f=c[e],g=this.renderFillRow(b,f,d),this.rowEls.eq(f.row).append(g),h.push(g[0]);return this.elsByFill[b]=a(h),c},renderFillRow:function(b,c,d){var e,f,g=this.colCnt,h=c.leftCol,i=c.rightCol+1;return d=d||b.toLowerCase(),e=a('<div class="fc-'+d+'-skeleton"><table><tr/></table></div>'),f=e.find("tr"),h>0&&f.append('<td colspan="'+h+'"/>'),f.append(c.el.attr("colspan",i-h)),g>i&&f.append('<td colspan="'+(g-i)+'"/>'),this.bookendCells(f),e}});ub.mixin({rowStructs:null,unrenderEvents:function(){this.removeSegPopover(),sb.prototype.unrenderEvents.apply(this,arguments)},getEventSegs:function(){return sb.prototype.getEventSegs.call(this).concat(this.popoverSegs||[])},renderBgSegs:function(b){var c=a.grep(b,function(a){return a.event.allDay});return sb.prototype.renderBgSegs.call(this,c)},renderFgSegs:function(b){var c;return b=this.renderFgSegEls(b),c=this.rowStructs=this.renderSegRows(b),this.rowEls.each(function(b,d){a(d).find(".fc-content-skeleton > table").append(c[b].tbodyEl)}),b},unrenderFgSegs:function(){for(var a,b=this.rowStructs||[];a=b.pop();)a.tbodyEl.remove();this.rowStructs=null},renderSegRows:function(a){var b,c,d=[];for(b=this.groupSegRows(a),c=0;c<b.length;c++)d.push(this.renderSegRow(c,b[c]));return d},fgSegHtml:function(a,b){var c,d,e=this.view,f=a.event,g=e.isEventDraggable(f),h=!b&&f.allDay&&a.isStart&&e.isEventResizableFromStart(f),i=!b&&f.allDay&&a.isEnd&&e.isEventResizableFromEnd(f),j=this.getSegClasses(a,g,h||i),k=ea(this.getSegSkinCss(a)),l="";return j.unshift("fc-day-grid-event","fc-h-event"),a.isStart&&(c=this.getEventTimeText(f),c&&(l='<span class="fc-time">'+ca(c)+"</span>")),d='<span class="fc-title">'+(ca(f.title||"")||"&nbsp;")+"</span>",'<a class="'+j.join(" ")+'"'+(f.url?' href="'+ca(f.url)+'"':"")+(k?' style="'+k+'"':"")+'><div class="fc-content">'+(this.isRTL?d+" "+l:l+" "+d)+"</div>"+(h?'<div class="fc-resizer fc-start-resizer" />':"")+(i?'<div class="fc-resizer fc-end-resizer" />':"")+"</a>"},renderSegRow:function(b,c){function d(b){for(;b>g;)k=(r[e-1]||[])[g],k?k.attr("rowspan",parseInt(k.attr("rowspan")||1,10)+1):(k=a("<td/>"),h.append(k)),q[e][g]=k,r[e][g]=k,g++}var e,f,g,h,i,j,k,l=this.colCnt,m=this.buildSegLevels(c),n=Math.max(1,m.length),o=a("<tbody/>"),p=[],q=[],r=[];for(e=0;n>e;e++){if(f=m[e],g=0,h=a("<tr/>"),p.push([]),q.push([]),r.push([]),f)for(i=0;i<f.length;i++){for(j=f[i],d(j.leftCol),k=a('<td class="fc-event-container"/>').append(j.el),j.leftCol!=j.rightCol?k.attr("colspan",j.rightCol-j.leftCol+1):r[e][g]=k;g<=j.rightCol;)q[e][g]=k,p[e][g]=j,g++;h.append(k)}d(l),this.bookendCells(h),o.append(h)}return{row:b,tbodyEl:o,cellMatrix:q,segMatrix:p,segLevels:m,segs:c}},buildSegLevels:function(a){var b,c,d,e=[];for(this.sortEventSegs(a),b=0;b<a.length;b++){for(c=a[b],d=0;d<e.length&&Ia(c,e[d]);d++);c.level=d,(e[d]||(e[d]=[])).push(c)}for(d=0;d<e.length;d++)e[d].sort(Ja);return e},groupSegRows:function(a){var b,c=[];for(b=0;b<this.rowCnt;b++)c.push([]);for(b=0;b<a.length;b++)c[a[b].row].push(a[b]);return c}}),ub.mixin({segPopover:null,popoverSegs:null,removeSegPopover:function(){this.segPopover&&this.segPopover.hide()},limitRows:function(a){var b,c,d=this.rowStructs||[];for(b=0;b<d.length;b++)this.unlimitRow(b),c=a?"number"==typeof a?a:this.computeRowLevelLimit(b):!1,c!==!1&&this.limitRow(b,c)},computeRowLevelLimit:function(b){function c(b,c){f=Math.max(f,a(c).outerHeight())}var d,e,f,g=this.rowEls.eq(b),h=g.height(),i=this.rowStructs[b].tbodyEl.children();for(d=0;d<i.length;d++)if(e=i.eq(d).removeClass("fc-limited"),f=0,e.find("> td > :first-child").each(c),e.position().top+f>h)return d;return!1},limitRow:function(b,c){function d(d){for(;d>w;)j=t.getCellSegs(b,w,c),j.length&&(m=f[c-1][w],s=t.renderMoreLink(b,w,j),r=a("<div/>").append(s),m.append(r),v.push(r[0])),w++}var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=this,u=this.rowStructs[b],v=[],w=0;if(c&&c<u.segLevels.length){for(e=u.segLevels[c-1],f=u.cellMatrix,g=u.tbodyEl.children().slice(c).addClass("fc-limited").get(),h=0;h<e.length;h++){for(i=e[h],d(i.leftCol),l=[],k=0;w<=i.rightCol;)j=this.getCellSegs(b,w,c),l.push(j),k+=j.length,w++;if(k){for(m=f[c-1][i.leftCol],n=m.attr("rowspan")||1,o=[],p=0;p<l.length;p++)q=a('<td class="fc-more-cell"/>').attr("rowspan",n),j=l[p],s=this.renderMoreLink(b,i.leftCol+p,[i].concat(j)),r=a("<div/>").append(s),q.append(r),o.push(q[0]),v.push(q[0]);m.addClass("fc-limited").after(a(o)),g.push(m[0])}}d(this.colCnt),u.moreEls=a(v),u.limitedEls=a(g)}},unlimitRow:function(a){var b=this.rowStructs[a];b.moreEls&&(b.moreEls.remove(),b.moreEls=null),b.limitedEls&&(b.limitedEls.removeClass("fc-limited"),b.limitedEls=null)},renderMoreLink:function(b,c,d){var e=this,f=this.view;return a('<a class="fc-more"/>').text(this.getMoreLinkText(d.length)).on("click",function(g){var h=f.opt("eventLimitClick"),i=e.getCellDate(b,c),j=a(this),k=e.getCellEl(b,c),l=e.getCellSegs(b,c),m=e.resliceDaySegs(l,i),n=e.resliceDaySegs(d,i);"function"==typeof h&&(h=f.trigger("eventLimitClick",null,{date:i,dayEl:k,moreEl:j,segs:m,hiddenSegs:n},g)),"popover"===h?e.showSegPopover(b,c,j,m):"string"==typeof h&&f.calendar.zoomTo(i,h)})},showSegPopover:function(a,b,c,d){var e,f,g=this,h=this.view,i=c.parent();e=1==this.rowCnt?h.el:this.rowEls.eq(a),f={className:"fc-more-popover",content:this.renderSegPopoverContent(a,b,d),parentEl:this.el,top:e.offset().top,autoHide:!0,viewportConstrain:h.opt("popoverViewportConstrain"),hide:function(){g.segPopover.removeElement(),g.segPopover=null,g.popoverSegs=null}},this.isRTL?f.right=i.offset().left+i.outerWidth()+1:f.left=i.offset().left-1,this.segPopover=new nb(f),this.segPopover.show()},renderSegPopoverContent:function(b,c,d){var e,f=this.view,g=f.opt("theme"),h=this.getCellDate(b,c).format(f.opt("dayPopoverFormat")),i=a('<div class="fc-header '+f.widgetHeaderClass+'"><span class="fc-close '+(g?"ui-icon ui-icon-closethick":"fc-icon fc-icon-x")+'"></span><span class="fc-title">'+ca(h)+'</span><div class="fc-clear"/></div><div class="fc-body '+f.widgetContentClass+'"><div class="fc-event-container"></div></div>'),j=i.find(".fc-event-container");for(d=this.renderFgSegEls(d,!0),this.popoverSegs=d,e=0;e<d.length;e++)this.prepareHits(),d[e].hit=this.getCellHit(b,c),this.releaseHits(),j.append(d[e].el);return i},resliceDaySegs:function(b,c){var d=a.map(b,function(a){return a.event}),e=c.clone(),f=e.clone().add(1,"days"),g={start:e,end:f};return b=this.eventsToSegs(d,function(a){var b=K(a,g);return b?[b]:[]}),this.sortEventSegs(b),b},getMoreLinkText:function(a){var b=this.view.opt("eventLimitText");return"function"==typeof b?b(a):"+"+a+" "+b},getCellSegs:function(a,b,c){for(var d,e=this.rowStructs[a].segMatrix,f=c||0,g=[];f<e.length;)d=e[f][b],d&&g.push(d),f++;return g}});var vb=Va.TimeGrid=sb.extend(tb,{slotDuration:null,snapDuration:null,snapsPerSlot:null,minTime:null,maxTime:null,labelFormat:null,labelInterval:null,colEls:null,slatContainerEl:null,slatEls:null,nowIndicatorEls:null,colCoordCache:null,slatCoordCache:null,constructor:function(){sb.apply(this,arguments),this.processOptions()},renderDates:function(){this.el.html(this.renderHtml()),this.colEls=this.el.find(".fc-day"),this.slatContainerEl=this.el.find(".fc-slats"),this.slatEls=this.slatContainerEl.find("tr"),this.colCoordCache=new ob({els:this.colEls,isHorizontal:!0}),this.slatCoordCache=new ob({els:this.slatEls,isVertical:!0}),this.renderContentSkeleton()},renderHtml:function(){return'<div class="fc-bg"><table>'+this.renderBgTrHtml(0)+'</table></div><div class="fc-slats"><table>'+this.renderSlatRowHtml()+"</table></div>"},renderSlatRowHtml:function(){for(var a,c,d,e=this.view,f=this.isRTL,g="",h=b.duration(+this.minTime);h<this.maxTime;)a=this.start.clone().time(h),c=ha(R(h,this.labelInterval)),d='<td class="fc-axis fc-time '+e.widgetContentClass+'" '+e.axisStyleAttr()+">"+(c?"<span>"+ca(a.format(this.labelFormat))+"</span>":"")+"</td>",g+='<tr data-time="'+a.format("HH:mm:ss")+'"'+(c?"":' class="fc-minor"')+">"+(f?"":d)+'<td class="'+e.widgetContentClass+'"/>'+(f?d:"")+"</tr>",h.add(this.slotDuration);return g},processOptions:function(){var c,d=this.view,e=d.opt("slotDuration"),f=d.opt("snapDuration");e=b.duration(e),f=f?b.duration(f):e,this.slotDuration=e,this.snapDuration=f,this.snapsPerSlot=e/f,this.minResizeDuration=f,this.minTime=b.duration(d.opt("minTime")),this.maxTime=b.duration(d.opt("maxTime")),c=d.opt("slotLabelFormat"),a.isArray(c)&&(c=c[c.length-1]),this.labelFormat=c||d.opt("axisFormat")||d.opt("smallTimeFormat"),c=d.opt("slotLabelInterval"),this.labelInterval=c?b.duration(c):this.computeLabelInterval(e)},computeLabelInterval:function(a){var c,d,e;for(c=Mb.length-1;c>=0;c--)if(d=b.duration(Mb[c]),e=R(d,a),ha(e)&&e>1)return d;return b.duration(a)},computeEventTimeFormat:function(){return this.view.opt("noMeridiemTimeFormat")},computeDisplayEventEnd:function(){return!0},prepareHits:function(){this.colCoordCache.build(),this.slatCoordCache.build()},releaseHits:function(){this.colCoordCache.clear()},queryHit:function(a,b){var c=this.snapsPerSlot,d=this.colCoordCache,e=this.slatCoordCache,f=d.getHorizontalIndex(a),g=e.getVerticalIndex(b);if(null!=f&&null!=g){var h=e.getTopOffset(g),i=e.getHeight(g),j=(b-h)/i,k=Math.floor(j*c),l=g*c+k,m=h+k/c*i,n=h+(k+1)/c*i;return{col:f,snap:l,component:this,left:d.getLeftOffset(f),right:d.getRightOffset(f),top:m,bottom:n}}},getHitSpan:function(a){var b,c=this.getCellDate(0,a.col),d=this.computeSnapTime(a.snap);return c.time(d),b=c.clone().add(this.snapDuration),{start:c,end:b}},getHitEl:function(a){return this.colEls.eq(a.col)},rangeUpdated:function(){this.updateDayTable()},computeSnapTime:function(a){return b.duration(this.minTime+this.snapDuration*a)},spanToSegs:function(a){var b,c=this.sliceRangeByTimes(a);for(b=0;b<c.length;b++)this.isRTL?c[b].col=this.daysPerRow-1-c[b].dayIndex:c[b].col=c[b].dayIndex;return c},sliceRangeByTimes:function(a){var b,c,d,e,f=[];for(c=0;c<this.daysPerRow;c++)d=this.dayDates[c].clone(),e={start:d.clone().time(this.minTime),end:d.clone().time(this.maxTime)},b=K(a,e),b&&(b.dayIndex=c,f.push(b));return f},updateSize:function(a){this.slatCoordCache.build(),a&&this.updateSegVerticals([].concat(this.fgSegs||[],this.bgSegs||[],this.businessSegs||[]))},getTotalSlatHeight:function(){return this.slatContainerEl.outerHeight()},computeDateTop:function(a,c){return this.computeTimeTop(b.duration(a-c.clone().stripTime()))},computeTimeTop:function(a){var b,c,d=this.slatEls.length,e=(a-this.minTime)/this.slotDuration;return e=Math.max(0,e),e=Math.min(d,e),b=Math.floor(e),b=Math.min(b,d-1),c=e-b,this.slatCoordCache.getTopPosition(b)+this.slatCoordCache.getHeight(b)*c},renderDrag:function(a,b){return b?this.renderEventLocationHelper(a,b):void this.renderHighlight(this.eventToSpan(a))},unrenderDrag:function(){this.unrenderHelper(),this.unrenderHighlight()},renderEventResize:function(a,b){return this.renderEventLocationHelper(a,b)},unrenderEventResize:function(){this.unrenderHelper()},renderHelper:function(a,b){return this.renderHelperSegs(this.eventToSegs(a),b)},unrenderHelper:function(){this.unrenderHelperSegs()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(),b=this.eventsToSegs(a);this.renderBusinessSegs(b)},unrenderBusinessHours:function(){this.unrenderBusinessSegs()},getNowIndicatorUnit:function(){return"minute"},renderNowIndicator:function(b){var c,d=this.spanToSegs({start:b,end:b}),e=this.computeDateTop(b,b),f=[];for(c=0;c<d.length;c++)f.push(a('<div class="fc-now-indicator fc-now-indicator-line"></div>').css("top",e).appendTo(this.colContainerEls.eq(d[c].col))[0]);d.length>0&&f.push(a('<div class="fc-now-indicator fc-now-indicator-arrow"></div>').css("top",e).appendTo(this.el.find(".fc-content-skeleton"))[0]),this.nowIndicatorEls=a(f)},unrenderNowIndicator:function(){this.nowIndicatorEls&&(this.nowIndicatorEls.remove(),this.nowIndicatorEls=null)},renderSelection:function(a){this.view.opt("selectHelper")?this.renderEventLocationHelper(a):this.renderHighlight(a)},unrenderSelection:function(){this.unrenderHelper(),this.unrenderHighlight()},renderHighlight:function(a){this.renderHighlightSegs(this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderHighlightSegs()}});vb.mixin({colContainerEls:null,fgContainerEls:null,bgContainerEls:null,helperContainerEls:null,highlightContainerEls:null,businessContainerEls:null,fgSegs:null,bgSegs:null,helperSegs:null,highlightSegs:null,businessSegs:null,renderContentSkeleton:function(){var b,c,d="";for(b=0;b<this.colCnt;b++)d+='<td><div class="fc-content-col"><div class="fc-event-container fc-helper-container"></div><div class="fc-event-container"></div><div class="fc-highlight-container"></div><div class="fc-bgevent-container"></div><div class="fc-business-container"></div></div></td>';c=a('<div class="fc-content-skeleton"><table><tr>'+d+"</tr></table></div>"),this.colContainerEls=c.find(".fc-content-col"),this.helperContainerEls=c.find(".fc-helper-container"),this.fgContainerEls=c.find(".fc-event-container:not(.fc-helper-container)"),this.bgContainerEls=c.find(".fc-bgevent-container"),this.highlightContainerEls=c.find(".fc-highlight-container"),this.businessContainerEls=c.find(".fc-business-container"),this.bookendCells(c.find("tr")),this.el.append(c)},renderFgSegs:function(a){return a=this.renderFgSegsIntoContainers(a,this.fgContainerEls),this.fgSegs=a,a},unrenderFgSegs:function(){this.unrenderNamedSegs("fgSegs")},renderHelperSegs:function(b,c){var d,e,f,g=[];for(b=this.renderFgSegsIntoContainers(b,this.helperContainerEls),d=0;d<b.length;d++)e=b[d],c&&c.col===e.col&&(f=c.el,e.el.css({left:f.css("left"),right:f.css("right"),"margin-left":f.css("margin-left"),"margin-right":f.css("margin-right")})),g.push(e.el[0]);return this.helperSegs=b,a(g)},unrenderHelperSegs:function(){this.unrenderNamedSegs("helperSegs")},renderBgSegs:function(a){return a=this.renderFillSegEls("bgEvent",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.bgContainerEls),this.bgSegs=a,a},unrenderBgSegs:function(){this.unrenderNamedSegs("bgSegs")},renderHighlightSegs:function(a){a=this.renderFillSegEls("highlight",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.highlightContainerEls),this.highlightSegs=a},unrenderHighlightSegs:function(){this.unrenderNamedSegs("highlightSegs")},renderBusinessSegs:function(a){a=this.renderFillSegEls("businessHours",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.businessContainerEls),this.businessSegs=a},unrenderBusinessSegs:function(){this.unrenderNamedSegs("businessSegs")},groupSegsByCol:function(a){var b,c=[];for(b=0;b<this.colCnt;b++)c.push([]);for(b=0;b<a.length;b++)c[a[b].col].push(a[b]);return c},attachSegsByCol:function(a,b){var c,d,e;for(c=0;c<this.colCnt;c++)for(d=a[c],e=0;e<d.length;e++)b.eq(c).append(d[e].el)},unrenderNamedSegs:function(a){var b,c=this[a];if(c){for(b=0;b<c.length;b++)c[b].el.remove();this[a]=null}},renderFgSegsIntoContainers:function(a,b){var c,d;for(a=this.renderFgSegEls(a),c=this.groupSegsByCol(a),d=0;d<this.colCnt;d++)this.updateFgSegCoords(c[d]);return this.attachSegsByCol(c,b),a},fgSegHtml:function(a,b){var c,d,e,f=this.view,g=a.event,h=f.isEventDraggable(g),i=!b&&a.isStart&&f.isEventResizableFromStart(g),j=!b&&a.isEnd&&f.isEventResizableFromEnd(g),k=this.getSegClasses(a,h,i||j),l=ea(this.getSegSkinCss(a));return k.unshift("fc-time-grid-event","fc-v-event"),f.isMultiDayEvent(g)?(a.isStart||a.isEnd)&&(c=this.getEventTimeText(a),d=this.getEventTimeText(a,"LT"),e=this.getEventTimeText(a,null,!1)):(c=this.getEventTimeText(g),d=this.getEventTimeText(g,"LT"),e=this.getEventTimeText(g,null,!1)),'<a class="'+k.join(" ")+'"'+(g.url?' href="'+ca(g.url)+'"':"")+(l?' style="'+l+'"':"")+'><div class="fc-content">'+(c?'<div class="fc-time" data-start="'+ca(e)+'" data-full="'+ca(d)+'"><span>'+ca(c)+"</span></div>":"")+(g.title?'<div class="fc-title">'+ca(g.title)+"</div>":"")+'</div><div class="fc-bg"/>'+(j?'<div class="fc-resizer fc-end-resizer" />':"")+"</a>"},updateSegVerticals:function(a){this.computeSegVerticals(a),this.assignSegVerticals(a)},computeSegVerticals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.top=this.computeDateTop(c.start,c.start),c.bottom=this.computeDateTop(c.end,c.start)},assignSegVerticals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.el.css(this.generateSegVerticalCss(c))},generateSegVerticalCss:function(a){return{top:a.top,bottom:-a.bottom}},updateFgSegCoords:function(a){this.computeSegVerticals(a),this.computeFgSegHorizontals(a),this.assignSegVerticals(a),this.assignFgSegHorizontals(a)},computeFgSegHorizontals:function(a){var b,c,d;if(this.sortEventSegs(a),b=Ka(a),La(b),c=b[0]){for(d=0;d<c.length;d++)Ma(c[d]);for(d=0;d<c.length;d++)this.computeFgSegForwardBack(c[d],0,0)}},computeFgSegForwardBack:function(a,b,c){var d,e=a.forwardSegs;if(void 0===a.forwardCoord)for(e.length?(this.sortForwardSegs(e),this.computeFgSegForwardBack(e[0],b+1,c),a.forwardCoord=e[0].backwardCoord):a.forwardCoord=1,a.backwardCoord=a.forwardCoord-(a.forwardCoord-c)/(b+1),d=0;d<e.length;d++)this.computeFgSegForwardBack(e[d],0,a.forwardCoord)},sortForwardSegs:function(a){a.sort(ia(this,"compareForwardSegs"))},compareForwardSegs:function(a,b){return b.forwardPressure-a.forwardPressure||(a.backwardCoord||0)-(b.backwardCoord||0)||this.compareEventSegs(a,b)},assignFgSegHorizontals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.el.css(this.generateFgSegHorizontalCss(c)),c.bottom-c.top<30&&c.el.addClass("fc-short")},generateFgSegHorizontalCss:function(a){var b,c,d=this.view.opt("slotEventOverlap"),e=a.backwardCoord,f=a.forwardCoord,g=this.generateSegVerticalCss(a);return d&&(f=Math.min(1,e+2*(f-e))),this.isRTL?(b=1-f,c=e):(b=e,c=1-f),g.zIndex=a.level+1,g.left=100*b+"%",g.right=100*c+"%",d&&a.forwardPressure&&(g[this.isRTL?"marginLeft":"marginRight"]=20),g}});var wb=Va.View=xa.extend(kb,lb,{type:null,name:null,title:null,calendar:null,options:null,el:null,displaying:null,isSkeletonRendered:!1,isEventsRendered:!1,start:null,end:null,intervalStart:null,intervalEnd:null,intervalDuration:null,intervalUnit:null,isRTL:!1,isSelected:!1,selectedEvent:null,eventOrderSpecs:null,widgetHeaderClass:null,widgetContentClass:null,highlightStateClass:null,nextDayThreshold:null,isHiddenDayHash:null,isNowIndicatorRendered:null,initialNowDate:null,initialNowQueriedMs:null,nowIndicatorTimeoutID:null,nowIndicatorIntervalID:null,constructor:function(a,c,d,e){this.calendar=a,this.type=this.name=c,this.options=d,this.intervalDuration=e||b.duration(1,"day"),this.nextDayThreshold=b.duration(this.opt("nextDayThreshold")),this.initThemingProps(),this.initHiddenDays(),this.isRTL=this.opt("isRTL"),this.eventOrderSpecs=G(this.opt("eventOrder")),this.initialize()},initialize:function(){},opt:function(a){return this.options[a]},trigger:function(a,b){var c=this.calendar;return c.trigger.apply(c,[a,b||this].concat(Array.prototype.slice.call(arguments,2),[this]))},setDate:function(a){this.setRange(this.computeRange(a))},setRange:function(b){a.extend(this,b),this.updateTitle()},computeRange:function(a){var b,c,d=O(this.intervalDuration),e=a.clone().startOf(d),f=e.clone().add(this.intervalDuration);return/year|month|week|day/.test(d)?(e.stripTime(),f.stripTime()):(e.hasTime()||(e=this.calendar.time(0)),f.hasTime()||(f=this.calendar.time(0))),b=e.clone(),b=this.skipHiddenDays(b),c=f.clone(),c=this.skipHiddenDays(c,-1,!0),{intervalUnit:d,intervalStart:e,intervalEnd:f,start:b,end:c}},computePrevDate:function(a){return this.massageCurrentDate(a.clone().startOf(this.intervalUnit).subtract(this.intervalDuration),-1)},computeNextDate:function(a){return this.massageCurrentDate(a.clone().startOf(this.intervalUnit).add(this.intervalDuration))},massageCurrentDate:function(a,b){return this.intervalDuration.as("days")<=1&&this.isHiddenDay(a)&&(a=this.skipHiddenDays(a,b),a.startOf("day")),a},updateTitle:function(){this.title=this.computeTitle()},computeTitle:function(){return this.formatRange({start:this.calendar.applyTimezone(this.intervalStart),end:this.calendar.applyTimezone(this.intervalEnd)},this.opt("titleFormat")||this.computeTitleFormat(),this.opt("titleRangeSeparator"))},computeTitleFormat:function(){return"year"==this.intervalUnit?"YYYY":"month"==this.intervalUnit?this.opt("monthYearFormat"):this.intervalDuration.as("days")>1?"ll":"LL"},formatRange:function(a,b,c){var d=a.end;return d.hasTime()||(d=d.clone().subtract(1)),sa(a.start,d,b,c,this.opt("isRTL"))},setElement:function(a){this.el=a,this.bindGlobalHandlers()},removeElement:function(){this.clear(),this.isSkeletonRendered&&(this.unrenderSkeleton(),this.isSkeletonRendered=!1),this.unbindGlobalHandlers(),this.el.remove()},display:function(b){var c=this,d=null;return this.displaying&&(d=this.queryScroll()),this.calendar.freezeContentHeight(),this.clear().then(function(){return c.displaying=a.when(c.displayView(b)).then(function(){c.forceScroll(c.computeInitialScroll(d)),c.calendar.unfreezeContentHeight(),c.triggerRender()})})},clear:function(){var b=this,c=this.displaying;return c?c.then(function(){return b.displaying=null,b.clearEvents(),b.clearView()}):a.when()},displayView:function(a){this.isSkeletonRendered||(this.renderSkeleton(),this.isSkeletonRendered=!0),a&&this.setDate(a),this.render&&this.render(),this.renderDates(),this.updateSize(),this.renderBusinessHours(),this.startNowIndicator()},clearView:function(){this.unselect(),this.stopNowIndicator(),this.triggerUnrender(),this.unrenderBusinessHours(),this.unrenderDates(),this.destroy&&this.destroy()},renderSkeleton:function(){},unrenderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},triggerRender:function(){this.trigger("viewRender",this,this,this.el)},triggerUnrender:function(){this.trigger("viewDestroy",this,this,this.el)},bindGlobalHandlers:function(){this.listenTo(a(document),"mousedown",this.handleDocumentMousedown),this.listenTo(a(document),"touchstart",this.processUnselect)},unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},initThemingProps:function(){var a=this.opt("theme")?"ui":"fc";this.widgetHeaderClass=a+"-widget-header",this.widgetContentClass=a+"-widget-content",this.highlightStateClass=a+"-state-highlight"},renderBusinessHours:function(){},unrenderBusinessHours:function(){},startNowIndicator:function(){var a,c,d,e=this;this.opt("nowIndicator")&&(a=this.getNowIndicatorUnit(),a&&(c=ia(this,"updateNowIndicator"),this.initialNowDate=this.calendar.getNow(),this.initialNowQueriedMs=+new Date,this.renderNowIndicator(this.initialNowDate),this.isNowIndicatorRendered=!0,d=this.initialNowDate.clone().startOf(a).add(1,a)-this.initialNowDate,this.nowIndicatorTimeoutID=setTimeout(function(){e.nowIndicatorTimeoutID=null,c(),d=+b.duration(1,a),d=Math.max(100,d),e.nowIndicatorIntervalID=setInterval(c,d)},d)))},updateNowIndicator:function(){this.isNowIndicatorRendered&&(this.unrenderNowIndicator(),this.renderNowIndicator(this.initialNowDate.clone().add(new Date-this.initialNowQueriedMs)))},stopNowIndicator:function(){this.isNowIndicatorRendered&&(this.nowIndicatorTimeoutID&&(clearTimeout(this.nowIndicatorTimeoutID),this.nowIndicatorTimeoutID=null),this.nowIndicatorIntervalID&&(clearTimeout(this.nowIndicatorIntervalID),this.nowIndicatorIntervalID=null),this.unrenderNowIndicator(),this.isNowIndicatorRendered=!1)},getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},updateSize:function(a){var b;a&&(b=this.queryScroll()),this.updateHeight(a),this.updateWidth(a),this.updateNowIndicator(),a&&this.setScroll(b)},updateWidth:function(a){},updateHeight:function(a){var b=this.calendar;this.setHeight(b.getSuggestedViewHeight(),b.isHeightAuto())},setHeight:function(a,b){},computeInitialScroll:function(a){return 0},queryScroll:function(){},setScroll:function(a){},forceScroll:function(a){var b=this;this.setScroll(a),setTimeout(function(){b.setScroll(a)},0)},displayEvents:function(a){var b=this.queryScroll();this.clearEvents(),this.renderEvents(a),this.isEventsRendered=!0,this.setScroll(b),this.triggerEventRender()},clearEvents:function(){var a;this.isEventsRendered&&(a=this.queryScroll(),this.triggerEventUnrender(),this.destroyEvents&&this.destroyEvents(),this.unrenderEvents(),this.setScroll(a),this.isEventsRendered=!1)},renderEvents:function(a){},unrenderEvents:function(){},triggerEventRender:function(){this.renderedEventSegEach(function(a){this.trigger("eventAfterRender",a.event,a.event,a.el)}),this.trigger("eventAfterAllRender")},triggerEventUnrender:function(){this.renderedEventSegEach(function(a){this.trigger("eventDestroy",a.event,a.event,a.el)})},resolveEventEl:function(b,c){var d=this.trigger("eventRender",b,b,c);return d===!1?c=null:d&&d!==!0&&(c=a(d)),c},showEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","")},a)},hideEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","hidden")},a)},renderedEventSegEach:function(a,b){var c,d=this.getEventSegs();for(c=0;c<d.length;c++)b&&d[c].event._id!==b._id||d[c].el&&a.call(this,d[c])},getEventSegs:function(){return[]},isEventDraggable:function(a){var b=a.source||{};return ba(a.startEditable,b.startEditable,this.opt("eventStartEditable"),a.editable,b.editable,this.opt("editable"))},reportEventDrop:function(a,b,c,d,e){var f=this.calendar,g=f.mutateEvent(a,b,c),h=function(){g.undo(),f.reportEventChange()};this.triggerEventDrop(a,g.dateDelta,h,d,e),f.reportEventChange()},triggerEventDrop:function(a,b,c,d,e){this.trigger("eventDrop",d[0],a,b,c,e,{})},reportExternalDrop:function(b,c,d,e,f){var g,h,i=b.eventProps;i&&(g=a.extend({},i,c),h=this.calendar.renderEvent(g,b.stick)[0]),this.triggerExternalDrop(h,c,d,e,f)},triggerExternalDrop:function(a,b,c,d,e){this.trigger("drop",c[0],b.start,d,e),a&&this.trigger("eventReceive",null,a)},renderDrag:function(a,b){},unrenderDrag:function(){},isEventResizableFromStart:function(a){return this.opt("eventResizableFromStart")&&this.isEventResizable(a)},isEventResizableFromEnd:function(a){return this.isEventResizable(a)},isEventResizable:function(a){var b=a.source||{};return ba(a.durationEditable,b.durationEditable,this.opt("eventDurationEditable"),a.editable,b.editable,this.opt("editable"))},reportEventResize:function(a,b,c,d,e){var f=this.calendar,g=f.mutateEvent(a,b,c),h=function(){g.undo(),f.reportEventChange()};this.triggerEventResize(a,g.durationDelta,h,d,e),f.reportEventChange()},triggerEventResize:function(a,b,c,d,e){this.trigger("eventResize",d[0],a,b,c,e,{})},select:function(a,b){this.unselect(b),this.renderSelection(a),this.reportSelection(a,b)},renderSelection:function(a){},reportSelection:function(a,b){this.isSelected=!0,this.triggerSelect(a,b)},triggerSelect:function(a,b){this.trigger("select",null,this.calendar.applyTimezone(a.start),this.calendar.applyTimezone(a.end),b)},unselect:function(a){this.isSelected&&(this.isSelected=!1,this.destroySelection&&this.destroySelection(),this.unrenderSelection(),this.trigger("unselect",null,a))},unrenderSelection:function(){},selectEvent:function(a){this.selectedEvent&&this.selectedEvent===a||(this.unselectEvent(),this.renderedEventSegEach(function(a){a.el.addClass("fc-selected")},a),this.selectedEvent=a)},unselectEvent:function(){this.selectedEvent&&(this.renderedEventSegEach(function(a){a.el.removeClass("fc-selected")},this.selectedEvent),this.selectedEvent=null)},isEventSelected:function(a){return this.selectedEvent&&this.selectedEvent._id===a._id},handleDocumentMousedown:function(a){
-u(a)&&this.processUnselect(a)},processUnselect:function(a){this.processRangeUnselect(a),this.processEventUnselect(a)},processRangeUnselect:function(b){var c;this.isSelected&&this.opt("unselectAuto")&&(c=this.opt("unselectCancel"),c&&a(b.target).closest(c).length||this.unselect(b))},processEventUnselect:function(b){this.selectedEvent&&(a(b.target).closest(".fc-selected").length||this.unselectEvent())},triggerDayClick:function(a,b,c){this.trigger("dayClick",b,this.calendar.applyTimezone(a.start),c)},initHiddenDays:function(){var b,c=this.opt("hiddenDays")||[],d=[],e=0;for(this.opt("weekends")===!1&&c.push(0,6),b=0;7>b;b++)(d[b]=-1!==a.inArray(b,c))||e++;if(!e)throw"invalid hiddenDays";this.isHiddenDayHash=d},isHiddenDay:function(a){return b.isMoment(a)&&(a=a.day()),this.isHiddenDayHash[a]},skipHiddenDays:function(a,b,c){var d=a.clone();for(b=b||1;this.isHiddenDayHash[(d.day()+(c?b:0)+7)%7];)d.add(b,"days");return d},computeDayRange:function(a){var b,c=a.start.clone().stripTime(),d=a.end,e=null;return d&&(e=d.clone().stripTime(),b=+d.time(),b&&b>=this.nextDayThreshold&&e.add(1,"days")),(!d||c>=e)&&(e=c.clone().add(1,"days")),{start:c,end:e}},isMultiDayEvent:function(a){var b=this.computeDayRange(a);return b.end.diff(b.start,"days")>1}}),xb=Va.Scroller=xa.extend({el:null,scrollEl:null,overflowX:null,overflowY:null,constructor:function(a){a=a||{},this.overflowX=a.overflowX||a.overflow||"auto",this.overflowY=a.overflowY||a.overflow||"auto"},render:function(){this.el=this.renderEl(),this.applyOverflow()},renderEl:function(){return this.scrollEl=a('<div class="fc-scroller"></div>')},clear:function(){this.setHeight("auto"),this.applyOverflow()},destroy:function(){this.el.remove()},applyOverflow:function(){this.scrollEl.css({"overflow-x":this.overflowX,"overflow-y":this.overflowY})},lockOverflow:function(a){var b=this.overflowX,c=this.overflowY;a=a||this.getScrollbarWidths(),"auto"===b&&(b=a.top||a.bottom||this.scrollEl[0].scrollWidth-1>this.scrollEl[0].clientWidth?"scroll":"hidden"),"auto"===c&&(c=a.left||a.right||this.scrollEl[0].scrollHeight-1>this.scrollEl[0].clientHeight?"scroll":"hidden"),this.scrollEl.css({"overflow-x":b,"overflow-y":c})},setHeight:function(a){this.scrollEl.height(a)},getScrollTop:function(){return this.scrollEl.scrollTop()},setScrollTop:function(a){this.scrollEl.scrollTop(a)},getClientWidth:function(){return this.scrollEl[0].clientWidth},getClientHeight:function(){return this.scrollEl[0].clientHeight},getScrollbarWidths:function(){return q(this.scrollEl)}}),yb=Va.Calendar=xa.extend({dirDefaults:null,langDefaults:null,overrides:null,options:null,viewSpecCache:null,view:null,header:null,loadingLevel:0,constructor:Pa,initialize:function(){},initOptions:function(a){var b,e,f,g;a=d(a),b=a.lang,e=zb[b],e||(b=yb.defaults.lang,e=zb[b]||{}),f=ba(a.isRTL,e.isRTL,yb.defaults.isRTL),g=f?yb.rtlDefaults:{},this.dirDefaults=g,this.langDefaults=e,this.overrides=a,this.options=c([yb.defaults,g,e,a]),Qa(this.options),this.viewSpecCache={}},getViewSpec:function(a){var b=this.viewSpecCache;return b[a]||(b[a]=this.buildViewSpec(a))},getUnitViewSpec:function(b){var c,d,e;if(-1!=a.inArray(b,$a))for(c=this.header.getViewsWithButtons(),a.each(Va.views,function(a){c.push(a)}),d=0;d<c.length;d++)if(e=this.getViewSpec(c[d]),e&&e.singleUnit==b)return e},buildViewSpec:function(a){for(var d,e,f,g,h=this.overrides.views||{},i=[],j=[],k=[],l=a;l;)d=Wa[l],e=h[l],l=null,"function"==typeof d&&(d={"class":d}),d&&(i.unshift(d),j.unshift(d.defaults||{}),f=f||d.duration,l=l||d.type),e&&(k.unshift(e),f=f||e.duration,l=l||e.type);return d=W(i),d.type=a,d["class"]?(f&&(f=b.duration(f),f.valueOf()&&(d.duration=f,g=O(f),1===f.as(g)&&(d.singleUnit=g,k.unshift(h[g]||{})))),d.defaults=c(j),d.overrides=c(k),this.buildViewSpecOptions(d),this.buildViewSpecButtonText(d,a),d):!1},buildViewSpecOptions:function(a){a.options=c([yb.defaults,a.defaults,this.dirDefaults,this.langDefaults,this.overrides,a.overrides]),Qa(a.options)},buildViewSpecButtonText:function(a,b){function c(c){var d=c.buttonText||{};return d[b]||(a.singleUnit?d[a.singleUnit]:null)}a.buttonTextOverride=c(this.overrides)||a.overrides.buttonText,a.buttonTextDefault=c(this.langDefaults)||c(this.dirDefaults)||a.defaults.buttonText||c(yb.defaults)||(a.duration?this.humanizeDuration(a.duration):null)||b},instantiateView:function(a){var b=this.getViewSpec(a);return new b["class"](this,a,b.options,b.duration)},isValidViewType:function(a){return Boolean(this.getViewSpec(a))},pushLoading:function(){this.loadingLevel++||this.trigger("loading",null,!0,this.view)},popLoading:function(){--this.loadingLevel||this.trigger("loading",null,!1,this.view)},buildSelectSpan:function(a,b){var c,d=this.moment(a).stripZone();return c=b?this.moment(b).stripZone():d.hasTime()?d.clone().add(this.defaultTimedEventDuration):d.clone().add(this.defaultAllDayEventDuration),{start:d,end:c}}});yb.mixin(kb),yb.defaults={titleRangeSeparator:" — ",monthYearFormat:"MMMM YYYY",defaultTimedEventDuration:"02:00:00",defaultAllDayEventDuration:{days:1},forceEventDuration:!1,nextDayThreshold:"09:00:00",defaultView:"month",aspectRatio:1.35,header:{left:"title",center:"",right:"today prev,next"},weekends:!0,weekNumbers:!1,weekNumberTitle:"W",weekNumberCalculation:"local",scrollTime:"06:00:00",lazyFetching:!0,startParam:"start",endParam:"end",timezoneParam:"timezone",timezone:!1,isRTL:!1,buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day"},buttonIcons:{prev:"left-single-arrow",next:"right-single-arrow",prevYear:"left-double-arrow",nextYear:"right-double-arrow"},theme:!1,themeButtonIcons:{prev:"circle-triangle-w",next:"circle-triangle-e",prevYear:"seek-prev",nextYear:"seek-next"},dragOpacity:.75,dragRevertDuration:500,dragScroll:!0,unselectAuto:!0,dropAccept:"*",eventOrder:"title",eventLimit:!1,eventLimitText:"more",eventLimitClick:"popover",dayPopoverFormat:"LL",handleWindowResize:!0,windowResizeDelay:200,longPressDelay:1e3},yb.englishDefaults={dayPopoverFormat:"dddd, MMMM D"},yb.rtlDefaults={header:{left:"next,prev today",center:"",right:"title"},buttonIcons:{prev:"right-single-arrow",next:"left-single-arrow",prevYear:"right-double-arrow",nextYear:"left-double-arrow"},themeButtonIcons:{prev:"circle-triangle-e",next:"circle-triangle-w",nextYear:"seek-prev",prevYear:"seek-next"}};var zb=Va.langs={};Va.datepickerLang=function(b,c,d){var e=zb[b]||(zb[b]={});e.isRTL=d.isRTL,e.weekNumberTitle=d.weekHeader,a.each(Ab,function(a,b){e[a]=b(d)}),a.datepicker&&(a.datepicker.regional[c]=a.datepicker.regional[b]=d,a.datepicker.regional.en=a.datepicker.regional[""],a.datepicker.setDefaults(d))},Va.lang=function(b,d){var e,f;e=zb[b]||(zb[b]={}),d&&(e=zb[b]=c([e,d])),f=Ra(b),a.each(Bb,function(a,b){null==e[a]&&(e[a]=b(f,e))}),yb.defaults.lang=b};var Ab={buttonText:function(a){return{prev:da(a.prevText),next:da(a.nextText),today:da(a.currentText)}},monthYearFormat:function(a){return a.showMonthAfterYear?"YYYY["+a.yearSuffix+"] MMMM":"MMMM YYYY["+a.yearSuffix+"]"}},Bb={dayOfMonthFormat:function(a,b){var c=a.longDateFormat("l");return c=c.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g,""),b.isRTL?c+=" ddd":c="ddd "+c,c},mediumTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"a")},smallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"a")},extraSmallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"t")},hourFormat:function(a){return a.longDateFormat("LT").replace(":mm","").replace(/(\Wmm)$/,"").replace(/\s*a$/i,"a")},noMeridiemTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"")}},Cb={smallDayDateFormat:function(a){return a.isRTL?"D dd":"dd D"},weekFormat:function(a){return a.isRTL?"w[ "+a.weekNumberTitle+"]":"["+a.weekNumberTitle+" ]w"},smallWeekFormat:function(a){return a.isRTL?"w["+a.weekNumberTitle+"]":"["+a.weekNumberTitle+"]w"}};Va.lang("en",yb.englishDefaults),Va.sourceNormalizers=[],Va.sourceFetchers=[];var Db={dataType:"json",cache:!1},Eb=1;yb.prototype.normalizeEvent=function(a){},yb.prototype.getPeerEvents=function(a,b){var c,d,e=this.getEventCache(),f=[];for(c=0;c<e.length;c++)d=e[c],b&&b._id===d._id||f.push(d);return f};var Fb=Va.BasicView=wb.extend({scroller:null,dayGridClass:ub,dayGrid:null,dayNumbersVisible:!1,weekNumbersVisible:!1,weekNumberWidth:null,headContainerEl:null,headRowEl:null,initialize:function(){this.dayGrid=this.instantiateDayGrid(),this.scroller=new xb({overflowX:"hidden",overflowY:"auto"})},instantiateDayGrid:function(){var a=this.dayGridClass.extend(Gb);return new a(this)},setRange:function(a){wb.prototype.setRange.call(this,a),this.dayGrid.breakOnWeeks=/year|month|week/.test(this.intervalUnit),this.dayGrid.setRange(a)},computeRange:function(a){var b=wb.prototype.computeRange.call(this,a);return/year|month/.test(b.intervalUnit)&&(b.start.startOf("week"),b.start=this.skipHiddenDays(b.start),b.end.weekday()&&(b.end.add(1,"week").startOf("week"),b.end=this.skipHiddenDays(b.end,-1,!0))),b},renderDates:function(){this.dayNumbersVisible=this.dayGrid.rowCnt>1,this.weekNumbersVisible=this.opt("weekNumbers"),this.dayGrid.numbersVisible=this.dayNumbersVisible||this.weekNumbersVisible,this.el.addClass("fc-basic-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-day-grid-container"),c=a('<div class="fc-day-grid" />').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.dayGrid.setElement(c),this.dayGrid.renderDates(this.hasRigidRows())},renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.dayGrid.renderHeadHtml()),this.headRowEl=this.headContainerEl.find(".fc-row")},unrenderDates:function(){this.dayGrid.unrenderDates(),this.dayGrid.removeElement(),this.scroller.destroy()},renderBusinessHours:function(){this.dayGrid.renderBusinessHours()},renderSkeletonHtml:function(){return'<table><thead class="fc-head"><tr><td class="fc-head-container '+this.widgetHeaderClass+'"></td></tr></thead><tbody class="fc-body"><tr><td class="'+this.widgetContentClass+'"></td></tr></tbody></table>'},weekNumberStyleAttr:function(){return null!==this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},hasRigidRows:function(){var a=this.opt("eventLimit");return a&&"number"!=typeof a},updateWidth:function(){this.weekNumbersVisible&&(this.weekNumberWidth=k(this.el.find(".fc-week-number")))},setHeight:function(a,b){var c,d,g=this.opt("eventLimit");this.scroller.clear(),f(this.headRowEl),this.dayGrid.removeSegPopover(),g&&"number"==typeof g&&this.dayGrid.limitRows(g),c=this.computeScrollerHeight(a),this.setGridHeight(c,b),g&&"number"!=typeof g&&this.dayGrid.limitRows(g),b||(this.scroller.setHeight(c),d=this.scroller.getScrollbarWidths(),(d.left||d.right)&&(e(this.headRowEl,d),c=this.computeScrollerHeight(a),this.scroller.setHeight(c)),this.scroller.lockOverflow(d))},computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},setGridHeight:function(a,b){b?j(this.dayGrid.rowEls):i(this.dayGrid.rowEls,a,!0)},queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},prepareHits:function(){this.dayGrid.prepareHits()},releaseHits:function(){this.dayGrid.releaseHits()},queryHit:function(a,b){return this.dayGrid.queryHit(a,b)},getHitSpan:function(a){return this.dayGrid.getHitSpan(a)},getHitEl:function(a){return this.dayGrid.getHitEl(a)},renderEvents:function(a){this.dayGrid.renderEvents(a),this.updateHeight()},getEventSegs:function(){return this.dayGrid.getEventSegs()},unrenderEvents:function(){this.dayGrid.unrenderEvents()},renderDrag:function(a,b){return this.dayGrid.renderDrag(a,b)},unrenderDrag:function(){this.dayGrid.unrenderDrag()},renderSelection:function(a){this.dayGrid.renderSelection(a)},unrenderSelection:function(){this.dayGrid.unrenderSelection()}}),Gb={renderHeadIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<th class="fc-week-number '+a.widgetHeaderClass+'" '+a.weekNumberStyleAttr()+"><span>"+ca(a.opt("weekNumberTitle"))+"</span></th>":""},renderNumberIntroHtml:function(a){var b=this.view;return b.weekNumbersVisible?'<td class="fc-week-number" '+b.weekNumberStyleAttr()+"><span>"+this.getCellDate(a,0).format("w")+"</span></td>":""},renderBgIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<td class="fc-week-number '+a.widgetContentClass+'" '+a.weekNumberStyleAttr()+"></td>":""},renderIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<td class="fc-week-number" '+a.weekNumberStyleAttr()+"></td>":""}},Hb=Va.MonthView=Fb.extend({computeRange:function(a){var b,c=Fb.prototype.computeRange.call(this,a);return this.isFixedWeeks()&&(b=Math.ceil(c.end.diff(c.start,"weeks",!0)),c.end.add(6-b,"weeks")),c},setGridHeight:function(a,b){b=b||"variable"===this.opt("weekMode"),b&&(a*=this.rowCnt/6),i(this.dayGrid.rowEls,a,!b)},isFixedWeeks:function(){var a=this.opt("weekMode");return a?"fixed"===a:this.opt("fixedWeekCount")}});Wa.basic={"class":Fb},Wa.basicDay={type:"basic",duration:{days:1}},Wa.basicWeek={type:"basic",duration:{weeks:1}},Wa.month={"class":Hb,duration:{months:1},defaults:{fixedWeekCount:!0}};var Ib=Va.AgendaView=wb.extend({scroller:null,timeGridClass:vb,timeGrid:null,dayGridClass:ub,dayGrid:null,axisWidth:null,headContainerEl:null,noScrollRowEls:null,bottomRuleEl:null,initialize:function(){this.timeGrid=this.instantiateTimeGrid(),this.opt("allDaySlot")&&(this.dayGrid=this.instantiateDayGrid()),this.scroller=new xb({overflowX:"hidden",overflowY:"auto"})},instantiateTimeGrid:function(){var a=this.timeGridClass.extend(Jb);return new a(this)},instantiateDayGrid:function(){var a=this.dayGridClass.extend(Kb);return new a(this)},setRange:function(a){wb.prototype.setRange.call(this,a),this.timeGrid.setRange(a),this.dayGrid&&this.dayGrid.setRange(a)},renderDates:function(){this.el.addClass("fc-agenda-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-time-grid-container"),c=a('<div class="fc-time-grid" />').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.timeGrid.setElement(c),this.timeGrid.renderDates(),this.bottomRuleEl=a('<hr class="fc-divider '+this.widgetHeaderClass+'"/>').appendTo(this.timeGrid.el),this.dayGrid&&(this.dayGrid.setElement(this.el.find(".fc-day-grid")),this.dayGrid.renderDates(),this.dayGrid.bottomCoordPadding=this.dayGrid.el.next("hr").outerHeight()),this.noScrollRowEls=this.el.find(".fc-row:not(.fc-scroller *)")},renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.timeGrid.renderHeadHtml())},unrenderDates:function(){this.timeGrid.unrenderDates(),this.timeGrid.removeElement(),this.dayGrid&&(this.dayGrid.unrenderDates(),this.dayGrid.removeElement()),this.scroller.destroy()},renderSkeletonHtml:function(){return'<table><thead class="fc-head"><tr><td class="fc-head-container '+this.widgetHeaderClass+'"></td></tr></thead><tbody class="fc-body"><tr><td class="'+this.widgetContentClass+'">'+(this.dayGrid?'<div class="fc-day-grid"/><hr class="fc-divider '+this.widgetHeaderClass+'"/>':"")+"</td></tr></tbody></table>"},axisStyleAttr:function(){return null!==this.axisWidth?'style="width:'+this.axisWidth+'px"':""},renderBusinessHours:function(){this.timeGrid.renderBusinessHours(),this.dayGrid&&this.dayGrid.renderBusinessHours()},unrenderBusinessHours:function(){this.timeGrid.unrenderBusinessHours(),this.dayGrid&&this.dayGrid.unrenderBusinessHours()},getNowIndicatorUnit:function(){return this.timeGrid.getNowIndicatorUnit()},renderNowIndicator:function(a){this.timeGrid.renderNowIndicator(a)},unrenderNowIndicator:function(){this.timeGrid.unrenderNowIndicator()},updateSize:function(a){this.timeGrid.updateSize(a),wb.prototype.updateSize.call(this,a)},updateWidth:function(){this.axisWidth=k(this.el.find(".fc-axis"))},setHeight:function(a,b){var c,d,g;this.bottomRuleEl.hide(),this.scroller.clear(),f(this.noScrollRowEls),this.dayGrid&&(this.dayGrid.removeSegPopover(),c=this.opt("eventLimit"),c&&"number"!=typeof c&&(c=Lb),c&&this.dayGrid.limitRows(c)),b||(d=this.computeScrollerHeight(a),this.scroller.setHeight(d),g=this.scroller.getScrollbarWidths(),(g.left||g.right)&&(e(this.noScrollRowEls,g),d=this.computeScrollerHeight(a),this.scroller.setHeight(d)),this.scroller.lockOverflow(g),this.timeGrid.getTotalSlatHeight()<d&&this.bottomRuleEl.show())},computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},computeInitialScroll:function(){var a=b.duration(this.opt("scrollTime")),c=this.timeGrid.computeTimeTop(a);return c=Math.ceil(c),c&&c++,c},queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},prepareHits:function(){this.timeGrid.prepareHits(),this.dayGrid&&this.dayGrid.prepareHits()},releaseHits:function(){this.timeGrid.releaseHits(),this.dayGrid&&this.dayGrid.releaseHits()},queryHit:function(a,b){var c=this.timeGrid.queryHit(a,b);return!c&&this.dayGrid&&(c=this.dayGrid.queryHit(a,b)),c},getHitSpan:function(a){return a.component.getHitSpan(a)},getHitEl:function(a){return a.component.getHitEl(a)},renderEvents:function(a){var b,c,d=[],e=[],f=[];for(c=0;c<a.length;c++)a[c].allDay?d.push(a[c]):e.push(a[c]);b=this.timeGrid.renderEvents(e),this.dayGrid&&(f=this.dayGrid.renderEvents(d)),this.updateHeight()},getEventSegs:function(){return this.timeGrid.getEventSegs().concat(this.dayGrid?this.dayGrid.getEventSegs():[])},unrenderEvents:function(){this.timeGrid.unrenderEvents(),this.dayGrid&&this.dayGrid.unrenderEvents()},renderDrag:function(a,b){return a.start.hasTime()?this.timeGrid.renderDrag(a,b):this.dayGrid?this.dayGrid.renderDrag(a,b):void 0},unrenderDrag:function(){this.timeGrid.unrenderDrag(),this.dayGrid&&this.dayGrid.unrenderDrag()},renderSelection:function(a){a.start.hasTime()||a.end.hasTime()?this.timeGrid.renderSelection(a):this.dayGrid&&this.dayGrid.renderSelection(a)},unrenderSelection:function(){this.timeGrid.unrenderSelection(),this.dayGrid&&this.dayGrid.unrenderSelection()}}),Jb={renderHeadIntroHtml:function(){var a,b=this.view;return b.opt("weekNumbers")?(a=this.start.format(b.opt("smallWeekFormat")),'<th class="fc-axis fc-week-number '+b.widgetHeaderClass+'" '+b.axisStyleAttr()+"><span>"+ca(a)+"</span></th>"):'<th class="fc-axis '+b.widgetHeaderClass+'" '+b.axisStyleAttr()+"></th>"},renderBgIntroHtml:function(){var a=this.view;return'<td class="fc-axis '+a.widgetContentClass+'" '+a.axisStyleAttr()+"></td>"},renderIntroHtml:function(){var a=this.view;return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"}},Kb={renderBgIntroHtml:function(){var a=this.view;return'<td class="fc-axis '+a.widgetContentClass+'" '+a.axisStyleAttr()+"><span>"+(a.opt("allDayHtml")||ca(a.opt("allDayText")))+"</span></td>"},renderIntroHtml:function(){var a=this.view;return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"}},Lb=5,Mb=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];return Wa.agenda={"class":Ib,defaults:{allDaySlot:!0,allDayText:"all-day",slotDuration:"00:30:00",minTime:"00:00:00",maxTime:"24:00:00",slotEventOverlap:!0}},Wa.agendaDay={type:"agenda",duration:{days:1}},Wa.agendaWeek={type:"agenda",duration:{weeks:1}},Va}); \ No newline at end of file
+!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){function c(a){return W(a,Ya)}function d(b){var c,d={views:b.views||{}};return a.each(b,function(b,e){"views"!=b&&(a.isPlainObject(e)&&!/(time|duration|interval)$/i.test(b)&&-1==a.inArray(b,Ya)?(c=null,a.each(e,function(a,e){/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(a)?(d.views[a]||(d.views[a]={}),d.views[a][b]=e):(c||(c={}),c[a]=e)}),c&&(d[b]=c)):d[b]=e)}),d}function e(a,b){b.left&&a.css({"border-left-width":1,"margin-left":b.left-1}),b.right&&a.css({"border-right-width":1,"margin-right":b.right-1})}function f(a){a.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})}function g(){a("body").addClass("fc-not-allowed")}function h(){a("body").removeClass("fc-not-allowed")}function i(b,c,d){var e=Math.floor(c/b.length),f=Math.floor(c-e*(b.length-1)),g=[],h=[],i=[],k=0;j(b),b.each(function(c,d){var j=c===b.length-1?f:e,l=a(d).outerHeight(!0);j>l?(g.push(d),h.push(l),i.push(a(d).height())):k+=l}),d&&(c-=k,e=Math.floor(c/g.length),f=Math.floor(c-e*(g.length-1))),a(g).each(function(b,c){var d=b===g.length-1?f:e,j=h[b],k=i[b],l=d-(j-k);d>j&&a(c).height(l)})}function j(a){a.height("")}function k(b){var c=0;return b.find("> span").each(function(b,d){var e=a(d).outerWidth();e>c&&(c=e)}),c++,b.width(c),c}function l(a,b){var c,d=a.add(b);return d.css({position:"relative",left:-1}),c=a.outerHeight()-b.outerHeight(),d.css({position:"",left:""}),c}function m(b){var c=b.css("position"),d=b.parents().filter(function(){var b=a(this);return/(auto|scroll)/.test(b.css("overflow")+b.css("overflow-y")+b.css("overflow-x"))}).eq(0);return"fixed"!==c&&d.length?d:a(b[0].ownerDocument||document)}function n(a,b){var c=a.offset(),d=c.left-(b?b.left:0),e=c.top-(b?b.top:0);return{left:d,right:d+a.outerWidth(),top:e,bottom:e+a.outerHeight()}}function o(a,b){var c=a.offset(),d=q(a),e=c.left+t(a,"border-left-width")+d.left-(b?b.left:0),f=c.top+t(a,"border-top-width")+d.top-(b?b.top:0);return{left:e,right:e+a[0].clientWidth,top:f,bottom:f+a[0].clientHeight}}function p(a,b){var c=a.offset(),d=c.left+t(a,"border-left-width")+t(a,"padding-left")-(b?b.left:0),e=c.top+t(a,"border-top-width")+t(a,"padding-top")-(b?b.top:0);return{left:d,right:d+a.width(),top:e,bottom:e+a.height()}}function q(a){var b=a.innerWidth()-a[0].clientWidth,c={left:0,right:0,top:0,bottom:a.innerHeight()-a[0].clientHeight};return r()&&"rtl"==a.css("direction")?c.left=b:c.right=b,c}function r(){return null===Za&&(Za=s()),Za}function s(){var b=a("<div><div/></div>").css({position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}).appendTo("body"),c=b.children(),d=c.offset().left>b.offset().left;return b.remove(),d}function t(a,b){return parseFloat(a.css(b))||0}function u(a){return 1==a.which&&!a.ctrlKey}function v(a){if(void 0!==a.pageX)return a.pageX;var b=a.originalEvent.touches;return b?b[0].pageX:void 0}function w(a){if(void 0!==a.pageY)return a.pageY;var b=a.originalEvent.touches;return b?b[0].pageY:void 0}function x(a){return/^touch/.test(a.type)}function y(a){a.addClass("fc-unselectable").on("selectstart",z)}function z(a){a.preventDefault()}function A(a){return window.addEventListener?(window.addEventListener("scroll",a,!0),!0):!1}function B(a){return window.removeEventListener?(window.removeEventListener("scroll",a,!0),!0):!1}function C(a,b){var c={left:Math.max(a.left,b.left),right:Math.min(a.right,b.right),top:Math.max(a.top,b.top),bottom:Math.min(a.bottom,b.bottom)};return c.left<c.right&&c.top<c.bottom?c:!1}function D(a,b){return{left:Math.min(Math.max(a.left,b.left),b.right),top:Math.min(Math.max(a.top,b.top),b.bottom)}}function E(a){return{left:(a.left+a.right)/2,top:(a.top+a.bottom)/2}}function F(a,b){return{left:a.left-b.left,top:a.top-b.top}}function G(b){var c,d,e=[],f=[];for("string"==typeof b?f=b.split(/\s*,\s*/):"function"==typeof b?f=[b]:a.isArray(b)&&(f=b),c=0;c<f.length;c++)d=f[c],"string"==typeof d?e.push("-"==d.charAt(0)?{field:d.substring(1),order:-1}:{field:d,order:1}):"function"==typeof d&&e.push({func:d});return e}function H(a,b,c){var d,e;for(d=0;d<c.length;d++)if(e=I(a,b,c[d]))return e;return 0}function I(a,b,c){return c.func?c.func(a,b):J(a[c.field],b[c.field])*(c.order||1)}function J(b,c){return b||c?null==c?-1:null==b?1:"string"===a.type(b)||"string"===a.type(c)?String(b).localeCompare(String(c)):b-c:0}function K(a,b){var c,d,e,f,g=a.start,h=a.end,i=b.start,j=b.end;return h>i&&j>g?(g>=i?(c=g.clone(),e=!0):(c=i.clone(),e=!1),j>=h?(d=h.clone(),f=!0):(d=j.clone(),f=!1),{start:c,end:d,isStart:e,isEnd:f}):void 0}function L(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days"),ms:a.time()-c.time()})}function M(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days")})}function N(a,c,d){return b.duration(Math.round(a.diff(c,d,!0)),d)}function O(a,b){var c,d,e;for(c=0;c<_a.length&&(d=_a[c],e=P(d,a,b),!(e>=1&&ha(e)));c++);return d}function P(a,c,d){return null!=d?d.diff(c,a,!0):b.isDuration(c)?c.as(a):c.end.diff(c.start,a,!0)}function Q(a,b,c){var d;return T(c)?(b-a)/c:(d=c.asMonths(),Math.abs(d)>=1&&ha(d)?b.diff(a,"months",!0)/d:b.diff(a,"days",!0)/c.asDays())}function R(a,b){var c,d;return T(a)||T(b)?a/b:(c=a.asMonths(),d=b.asMonths(),Math.abs(c)>=1&&ha(c)&&Math.abs(d)>=1&&ha(d)?c/d:a.asDays()/b.asDays())}function S(a,c){var d;return T(a)?b.duration(a*c):(d=a.asMonths(),Math.abs(d)>=1&&ha(d)?b.duration({months:d*c}):b.duration({days:a.asDays()*c}))}function T(a){return Boolean(a.hours()||a.minutes()||a.seconds()||a.milliseconds())}function U(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function V(a){return/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(a)}function W(a,b){var c,d,e,f,g,h,i={};if(b)for(c=0;c<b.length;c++){for(d=b[c],e=[],f=a.length-1;f>=0;f--)if(g=a[f][d],"object"==typeof g)e.unshift(g);else if(void 0!==g){i[d]=g;break}e.length&&(i[d]=W(e))}for(c=a.length-1;c>=0;c--){h=a[c];for(d in h)d in i||(i[d]=h[d])}return i}function X(a){var b=function(){};return b.prototype=a,new b}function Y(a,b){for(var c in a)$(a,c)&&(b[c]=a[c])}function Z(a,b){var c,d,e=["constructor","toString","valueOf"];for(c=0;c<e.length;c++)d=e[c],a[d]!==Object.prototype[d]&&(b[d]=a[d])}function $(a,b){return db.call(a,b)}function _(b){return/undefined|null|boolean|number|string/.test(a.type(b))}function aa(b,c,d){if(a.isFunction(b)&&(b=[b]),b){var e,f;for(e=0;e<b.length;e++)f=b[e].apply(c,d)||f;return f}}function ba(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]}function ca(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#039;").replace(/"/g,"&quot;").replace(/\n/g,"<br />")}function da(a){return a.replace(/&.*?;/g,"")}function ea(b){var c=[];return a.each(b,function(a,b){null!=b&&c.push(a+":"+b)}),c.join(";")}function fa(a){return a.charAt(0).toUpperCase()+a.slice(1)}function ga(a,b){return a-b}function ha(a){return a%1===0}function ia(a,b){var c=a[b];return function(){return c.apply(a,arguments)}}function ja(a,b,c){var d,e,f,g,h,i=function(){var j=+new Date-g;b>j?d=setTimeout(i,b-j):(d=null,c||(h=a.apply(f,e),f=e=null))};return function(){f=this,e=arguments,g=+new Date;var j=c&&!d;return d||(d=setTimeout(i,b)),j&&(h=a.apply(f,e),f=e=null),h}}function ka(b,c){return b&&b.then&&"resolved"!==b.state()?c?b.then(c):void 0:a.when(c())}function la(c,d,e){var f,g,h,i,j=c[0],k=1==c.length&&"string"==typeof j;return b.isMoment(j)?(i=b.apply(null,c),na(j,i)):U(j)||void 0===j?i=b.apply(null,c):(f=!1,g=!1,k?eb.test(j)?(j+="-01",c=[j],f=!0,g=!0):(h=fb.exec(j))&&(f=!h[5],g=!0):a.isArray(j)&&(g=!0),i=d||f?b.utc.apply(b,c):b.apply(null,c),f?(i._ambigTime=!0,i._ambigZone=!0):e&&(g?i._ambigZone=!0:k&&(i.utcOffset?i.utcOffset(j):i.zone(j)))),i._fullCalendar=!0,i}function ma(a,c){var d,e,f=!1,g=!1,h=a.length,i=[];for(d=0;h>d;d++)e=a[d],b.isMoment(e)||(e=Wa.moment.parseZone(e)),f=f||e._ambigTime,g=g||e._ambigZone,i.push(e);for(d=0;h>d;d++)e=i[d],c||!f||e._ambigTime?g&&!e._ambigZone&&(i[d]=e.clone().stripZone()):i[d]=e.clone().stripTime();return i}function na(a,b){a._ambigTime?b._ambigTime=!0:b._ambigTime&&(b._ambigTime=!1),a._ambigZone?b._ambigZone=!0:b._ambigZone&&(b._ambigZone=!1)}function oa(a,b){a.year(b[0]||0).month(b[1]||0).date(b[2]||0).hours(b[3]||0).minutes(b[4]||0).seconds(b[5]||0).milliseconds(b[6]||0)}function pa(a,b){return hb.format.call(a,b)}function qa(a,b){return ra(a,wa(b))}function ra(a,b){var c,d="";for(c=0;c<b.length;c++)d+=sa(a,b[c]);return d}function sa(a,b){var c,d;return"string"==typeof b?b:(c=b.token)?ib[c]?ib[c](a):pa(a,c):b.maybe&&(d=ra(a,b.maybe),d.match(/[1-9]/))?d:""}function ta(a,b,c,d,e){var f;return a=Wa.moment.parseZone(a),b=Wa.moment.parseZone(b),f=(a.localeData||a.lang).call(a),c=f.longDateFormat(c)||c,d=d||" - ",ua(a,b,wa(c),d,e)}function ua(a,b,c,d,e){var f,g,h,i,j=a.clone().stripZone(),k=b.clone().stripZone(),l="",m="",n="",o="",p="";for(g=0;g<c.length&&(f=va(a,b,j,k,c[g]),f!==!1);g++)l+=f;for(h=c.length-1;h>g&&(f=va(a,b,j,k,c[h]),f!==!1);h--)m=f+m;for(i=g;h>=i;i++)n+=sa(a,c[i]),o+=sa(b,c[i]);return(n||o)&&(p=e?o+d+n:n+d+o),l+p+m}function va(a,b,c,d,e){var f,g;return"string"==typeof e?e:(f=e.token)&&(g=jb[f.charAt(0)],g&&c.isSame(d,g))?pa(a,f):!1}function wa(a){return a in kb?kb[a]:kb[a]=xa(a)}function xa(a){for(var b,c=[],d=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;b=d.exec(a);)b[1]?c.push(b[1]):b[2]?c.push({maybe:xa(b[2])}):b[3]?c.push({token:b[3]}):b[5]&&c.push(b[5]);return c}function ya(){}function za(a,b){var c;return $(b,"constructor")&&(c=b.constructor),"function"!=typeof c&&(c=b.constructor=function(){a.apply(this,arguments)}),c.prototype=X(a.prototype),Y(b,c.prototype),Z(b,c.prototype),Y(a,c),c}function Aa(a,b){Y(b,a.prototype)}function Ba(a,b){return a||b?a&&b?a.component===b.component&&Ca(a,b)&&Ca(b,a):!1:!0}function Ca(a,b){for(var c in a)if(!/^(component|left|right|top|bottom)$/.test(c)&&a[c]!==b[c])return!1;return!0}function Da(a){var b=Fa(a);return"background"===b||"inverse-background"===b}function Ea(a){return"inverse-background"===Fa(a)}function Fa(a){return ba((a.source||{}).rendering,a.rendering)}function Ga(a){var b,c,d={};for(b=0;b<a.length;b++)c=a[b],(d[c._id]||(d[c._id]=[])).push(c);return d}function Ha(a,b){return a.start-b.start}function Ia(c){var d,e,f,g,h=Wa.dataAttrPrefix;return h&&(h+="-"),d=c.data(h+"event")||null,d&&(d="object"==typeof d?a.extend({},d):{},e=d.start,null==e&&(e=d.time),f=d.duration,g=d.stick,delete d.start,delete d.time,delete d.duration,delete d.stick),null==e&&(e=c.data(h+"start")),null==e&&(e=c.data(h+"time")),null==f&&(f=c.data(h+"duration")),null==g&&(g=c.data(h+"stick")),e=null!=e?b.duration(e):null,f=null!=f?b.duration(f):null,g=Boolean(g),{eventProps:d,startTime:e,duration:f,stick:g}}function Ja(a,b){var c,d;for(c=0;c<b.length;c++)if(d=b[c],d.leftCol<=a.rightCol&&d.rightCol>=a.leftCol)return!0;return!1}function Ka(a,b){return a.leftCol-b.leftCol}function La(a){var b,c,d,e=[];for(b=0;b<a.length;b++){for(c=a[b],d=0;d<e.length&&Oa(c,e[d]).length;d++);c.level=d,(e[d]||(e[d]=[])).push(c)}return e}function Ma(a){var b,c,d,e,f;for(b=0;b<a.length;b++)for(c=a[b],d=0;d<c.length;d++)for(e=c[d],e.forwardSegs=[],f=b+1;f<a.length;f++)Oa(e,a[f],e.forwardSegs)}function Na(a){var b,c,d=a.forwardSegs,e=0;if(void 0===a.forwardPressure){for(b=0;b<d.length;b++)c=d[b],Na(c),e=Math.max(e,1+c.forwardPressure);a.forwardPressure=e}}function Oa(a,b,c){c=c||[];for(var d=0;d<b.length;d++)Pa(a,b[d])&&c.push(b[d]);return c}function Pa(a,b){return a.bottom>b.top&&a.top<b.bottom}function Qa(c,d){function e(){T?h()&&(k(),i()):f()}function f(){U=O.theme?"ui":"fc",c.addClass("fc"),O.isRTL?c.addClass("fc-rtl"):c.addClass("fc-ltr"),O.theme?c.addClass("ui-widget"):c.addClass("fc-unthemed"),T=a("<div class='fc-view-container'/>").prependTo(c),R=N.header=new Ta(N,O),S=R.render(),S&&c.prepend(S),i(O.defaultView),O.handleWindowResize&&(Y=ja(m,O.windowResizeDelay),a(window).resize(Y))}function g(){V&&V.removeElement(),R.removeElement(),T.remove(),c.removeClass("fc fc-ltr fc-rtl fc-unthemed ui-widget"),Y&&a(window).unbind("resize",Y)}function h(){return c.is(":visible")}function i(b){da++,V&&b&&V.type!==b&&(R.deactivateButton(V.type),H(),V.removeElement(),V=N.view=null),!V&&b&&(V=N.view=ca[b]||(ca[b]=N.instantiateView(b)),V.setElement(a("<div class='fc-view fc-"+b+"-view' />").appendTo(T)),R.activateButton(b)),V&&(Z=V.massageCurrentDate(Z),V.displaying&&Z.isWithin(V.intervalStart,V.intervalEnd)||h()&&(V.display(Z),I(),u(),v(),q())),I(),da--}function j(a){return h()?(a&&l(),da++,V.updateSize(!0),da--,!0):void 0}function k(){h()&&l()}function l(){W="number"==typeof O.contentHeight?O.contentHeight:"number"==typeof O.height?O.height-(S?S.outerHeight(!0):0):Math.round(T.width()/Math.max(O.aspectRatio,.5))}function m(a){!da&&a.target===window&&V.start&&j(!0)&&V.trigger("windowResize",ba)}function n(){r()}function o(a){aa(N.getEventSourcesByMatchArray(a))}function p(){h()&&(H(),V.displayEvents(ea),I())}function q(){!O.lazyFetching||$(V.start,V.end)?r():p()}function r(){_(V.start,V.end)}function s(a){ea=a,p()}function t(){p()}function u(){R.updateTitle(V.title)}function v(){var a=N.getNow();a.isWithin(V.intervalStart,V.intervalEnd)?R.disableButton("today"):R.enableButton("today")}function w(a,b){V.select(N.buildSelectSpan.apply(N,arguments))}function x(){V&&V.unselect()}function y(){Z=V.computePrevDate(Z),i()}function z(){Z=V.computeNextDate(Z),i()}function A(){Z.add(-1,"years"),i()}function B(){Z.add(1,"years"),i()}function C(){Z=N.getNow(),i()}function D(a){Z=N.moment(a).stripZone(),i()}function E(a){Z.add(b.duration(a)),i()}function F(a,b){var c;b=b||"day",c=N.getViewSpec(b)||N.getUnitViewSpec(b),Z=a.clone(),i(c?c.type:null)}function G(){return N.applyTimezone(Z)}function H(){T.css({width:"100%",height:T.height(),overflow:"hidden"})}function I(){T.css({width:"",height:"",overflow:""})}function J(){return N}function K(){return V}function L(a,b){return void 0===b?O[a]:void("height"!=a&&"contentHeight"!=a&&"aspectRatio"!=a||(O[a]=b,j(!0)))}function M(a,b){var c=Array.prototype.slice.call(arguments,2);return b=b||ba,this.triggerWith(a,b,c),O[a]?O[a].apply(b,c):void 0}var N=this;N.initOptions(d||{});var O=this.options;N.render=e,N.destroy=g,N.refetchEvents=n,N.refetchEventSources=o,N.reportEvents=s,N.reportEventChange=t,N.rerenderEvents=p,N.changeView=i,N.select=w,N.unselect=x,N.prev=y,N.next=z,N.prevYear=A,N.nextYear=B,N.today=C,N.gotoDate=D,N.incrementDate=E,N.zoomTo=F,N.getDate=G,N.getCalendar=J,N.getView=K,N.option=L,N.trigger=M;var P=X(Sa(O.lang));if(O.monthNames&&(P._months=O.monthNames),O.monthNamesShort&&(P._monthsShort=O.monthNamesShort),O.dayNames&&(P._weekdays=O.dayNames),O.dayNamesShort&&(P._weekdaysShort=O.dayNamesShort),null!=O.firstDay){var Q=X(P._week);Q.dow=O.firstDay,P._week=Q}P._fullCalendar_weekCalc=function(a){return"function"==typeof a?a:"local"===a?a:"iso"===a||"ISO"===a?"ISO":void 0}(O.weekNumberCalculation),N.defaultAllDayEventDuration=b.duration(O.defaultAllDayEventDuration),N.defaultTimedEventDuration=b.duration(O.defaultTimedEventDuration),N.moment=function(){var a;return"local"===O.timezone?(a=Wa.moment.apply(null,arguments),a.hasTime()&&a.local()):a="UTC"===O.timezone?Wa.moment.utc.apply(null,arguments):Wa.moment.parseZone.apply(null,arguments),"_locale"in a?a._locale=P:a._lang=P,a},N.getIsAmbigTimezone=function(){return"local"!==O.timezone&&"UTC"!==O.timezone},N.applyTimezone=function(a){if(!a.hasTime())return a.clone();var b,c=N.moment(a.toArray()),d=a.time()-c.time();return d&&(b=c.clone().add(d),a.time()-b.time()===0&&(c=b)),c},N.getNow=function(){var a=O.now;return"function"==typeof a&&(a=a()),N.moment(a).stripZone()},N.getEventEnd=function(a){return a.end?a.end.clone():N.getDefaultEventEnd(a.allDay,a.start)},N.getDefaultEventEnd=function(a,b){var c=b.clone();return a?c.stripTime().add(N.defaultAllDayEventDuration):c.add(N.defaultTimedEventDuration),N.getIsAmbigTimezone()&&c.stripZone(),c},N.humanizeDuration=function(a){return(a.locale||a.lang).call(a,O.lang).humanize()},Ua.call(N,O);var R,S,T,U,V,W,Y,Z,$=N.isFetchNeeded,_=N.fetchEvents,aa=N.fetchEventSources,ba=c[0],ca={},da=0,ea=[];Z=null!=O.defaultDate?N.moment(O.defaultDate).stripZone():N.getNow(),N.getSuggestedViewHeight=function(){return void 0===W&&k(),W},N.isHeightAuto=function(){return"auto"===O.contentHeight||"auto"===O.height},N.freezeContentHeight=H,N.unfreezeContentHeight=I,N.initialize()}function Ra(b){a.each(Db,function(a,c){null==b[a]&&(b[a]=c(b))})}function Sa(a){var c=b.localeData||b.langData;return c.call(b,a)||c.call(b,"en")}function Ta(b,c){function d(){var b=c.header;return n=c.theme?"ui":"fc",b?o=a("<div class='fc-toolbar'/>").append(f("left")).append(f("right")).append(f("center")).append('<div class="fc-clear"/>'):void 0}function e(){o.remove(),o=a()}function f(d){var e=a('<div class="fc-'+d+'"/>'),f=c.header[d];return f&&a.each(f.split(" "),function(d){var f,g=a(),h=!0;a.each(this.split(","),function(d,e){var f,i,j,k,l,m,o,q,r,s;"title"==e?(g=g.add(a("<h2>&nbsp;</h2>")),h=!1):((f=(b.options.customButtons||{})[e])?(j=function(a){f.click&&f.click.call(s[0],a)},k="",l=f.text):(i=b.getViewSpec(e))?(j=function(){b.changeView(e)},p.push(e),k=i.buttonTextOverride,l=i.buttonTextDefault):b[e]&&(j=function(){b[e]()},k=(b.overrides.buttonText||{})[e],l=c.buttonText[e]),j&&(m=f?f.themeIcon:c.themeButtonIcons[e],o=f?f.icon:c.buttonIcons[e],q=k?ca(k):m&&c.theme?"<span class='ui-icon ui-icon-"+m+"'></span>":o&&!c.theme?"<span class='fc-icon fc-icon-"+o+"'></span>":ca(l),r=["fc-"+e+"-button",n+"-button",n+"-state-default"],s=a('<button type="button" class="'+r.join(" ")+'">'+q+"</button>").click(function(a){s.hasClass(n+"-state-disabled")||(j(a),(s.hasClass(n+"-state-active")||s.hasClass(n+"-state-disabled"))&&s.removeClass(n+"-state-hover"))}).mousedown(function(){s.not("."+n+"-state-active").not("."+n+"-state-disabled").addClass(n+"-state-down")}).mouseup(function(){s.removeClass(n+"-state-down")}).hover(function(){s.not("."+n+"-state-active").not("."+n+"-state-disabled").addClass(n+"-state-hover")},function(){s.removeClass(n+"-state-hover").removeClass(n+"-state-down")}),g=g.add(s)))}),h&&g.first().addClass(n+"-corner-left").end().last().addClass(n+"-corner-right").end(),g.length>1?(f=a("<div/>"),h&&f.addClass("fc-button-group"),f.append(g),e.append(f)):e.append(g)}),e}function g(a){o.find("h2").text(a)}function h(a){o.find(".fc-"+a+"-button").addClass(n+"-state-active")}function i(a){o.find(".fc-"+a+"-button").removeClass(n+"-state-active")}function j(a){o.find(".fc-"+a+"-button").prop("disabled",!0).addClass(n+"-state-disabled")}function k(a){o.find(".fc-"+a+"-button").prop("disabled",!1).removeClass(n+"-state-disabled")}function l(){return p}var m=this;m.render=d,m.removeElement=e,m.updateTitle=g,m.activateButton=h,m.deactivateButton=i,m.disableButton=j,m.enableButton=k,m.getViewsWithButtons=l;var n,o=a(),p=[]}function Ua(c){function d(a,b){return!W||W>a||b>X}function e(a,b){W=a,X=b,f($,"reset")}function f(a,b){var c,d;for("reset"===b?da=[]:"add"!==b&&(da=v(da,a)),c=0;c<a.length;c++)d=a[c],"pending"!==d._status&&ca++,d._fetchId=(d._fetchId||0)+1,d._status="pending";for(c=0;c<a.length;c++)d=a[c],g(d,d._fetchId)}function g(b,c){j(b,function(d){var e,f,g,h=a.isArray(b.events);if(c===b._fetchId&&"rejected"!==b._status){if(b._status="resolved",d)for(e=0;e<d.length;e++)f=d[e],g=h?f:C(f,b),g&&da.push.apply(da,G(g));i()}})}function h(a){var b="pending"===a._status;a._status="rejected",b&&i()}function i(){ca--,ca||Y(da)}function j(b,d){var e,f,g=Wa.sourceFetchers;for(e=0;e<g.length;e++){if(f=g[e].call(U,b,W.clone(),X.clone(),c.timezone,d),f===!0)return;if("object"==typeof f)return void j(f,d)}var h=b.events;if(h)a.isFunction(h)?(U.pushLoading(),h.call(U,W.clone(),X.clone(),c.timezone,function(a){d(a),U.popLoading()})):a.isArray(h)?d(h):d();else{var i=b.url;if(i){var k,l=b.success,m=b.error,n=b.complete;k=a.isFunction(b.data)?b.data():b.data;var o=a.extend({},k||{}),p=ba(b.startParam,c.startParam),q=ba(b.endParam,c.endParam),r=ba(b.timezoneParam,c.timezoneParam);p&&(o[p]=W.format()),q&&(o[q]=X.format()),c.timezone&&"local"!=c.timezone&&(o[r]=c.timezone),U.pushLoading(),a.ajax(a.extend({},Eb,b,{data:o,success:function(b){b=b||[];var c=aa(l,this,arguments);a.isArray(c)&&(b=c),d(b)},error:function(){aa(m,this,arguments),d()},complete:function(){aa(n,this,arguments),U.popLoading()}}))}else d()}}function k(a){var b=l(a);b&&($.push(b),f([b],"add"))}function l(b){var c,d,e=Wa.sourceNormalizers;if(a.isFunction(b)||a.isArray(b)?c={events:b}:"string"==typeof b?c={url:b}:"object"==typeof b&&(c=a.extend({},b)),c){for(c.className?"string"==typeof c.className&&(c.className=c.className.split(/\s+/)):c.className=[],a.isArray(c.events)&&(c.origArray=c.events,c.events=a.map(c.events,function(a){return C(a,c)})),d=0;d<e.length;d++)e[d].call(U,c);return c}}function m(a){o(s(a))}function n(a){null==a?o($,!0):o(r(a))}function o(b,c){var d;for(d=0;d<b.length;d++)h(b[d]);c?($=[],da=[]):($=a.grep($,function(a){for(d=0;d<b.length;d++)if(a===b[d])return!1;return!0}),da=v(da,b)),Y(da)}function p(){return $.slice(1)}function q(b){return a.grep($,function(a){return a.id&&a.id===b})[0]}function r(b){b?a.isArray(b)||(b=[b]):b=[];var c,d=[];for(c=0;c<b.length;c++)d.push.apply(d,s(b[c]));return d}function s(b){var c,d;for(c=0;c<$.length;c++)if(d=$[c],d===b)return[d];return d=q(b),d?[d]:a.grep($,function(a){return t(b,a)})}function t(a,b){return a&&b&&u(a)==u(b)}function u(a){return("object"==typeof a?a.origArray||a.googleCalendarId||a.url||a.events:null)||a}function v(b,c){return a.grep(b,function(a){for(var b=0;b<c.length;b++)if(a.source===c[b])return!1;return!0})}function w(a){a.start=U.moment(a.start),a.end?a.end=U.moment(a.end):a.end=null,H(a,x(a)),Y(da)}function x(b){var c={};return a.each(b,function(a,b){y(a)&&void 0!==b&&_(b)&&(c[a]=b)}),c}function y(a){return!/^_|^(id|allDay|start|end)$/.test(a)}function z(a,b){var c,d,e,f=C(a);if(f){for(c=G(f),d=0;d<c.length;d++)e=c[d],e.source||(b&&(Z.events.push(e),e.source=Z),da.push(e));return Y(da),c}return[]}function A(b){var c,d;for(null==b?b=function(){return!0}:a.isFunction(b)||(c=b+"",b=function(a){return a._id==c}),da=a.grep(da,b,!0),d=0;d<$.length;d++)a.isArray($[d].events)&&($[d].events=a.grep($[d].events,b,!0));Y(da)}function B(b){return a.isFunction(b)?a.grep(da,b):null!=b?(b+="",a.grep(da,function(a){return a._id==b})):da}function C(d,e){var f,g,h,i={};if(c.eventDataTransform&&(d=c.eventDataTransform(d)),e&&e.eventDataTransform&&(d=e.eventDataTransform(d)),a.extend(i,d),e&&(i.source=e),i._id=d._id||(void 0===d.id?"_fc"+Fb++:d.id+""),d.className?"string"==typeof d.className?i.className=d.className.split(/\s+/):i.className=d.className:i.className=[],f=d.start||d.date,g=d.end,V(f)&&(f=b.duration(f)),V(g)&&(g=b.duration(g)),d.dow||b.isDuration(f)||b.isDuration(g))i.start=f?b.duration(f):null,i.end=g?b.duration(g):null,i._recurring=!0;else{if(f&&(f=U.moment(f),!f.isValid()))return!1;g&&(g=U.moment(g),g.isValid()||(g=null)),h=d.allDay,void 0===h&&(h=ba(e?e.allDayDefault:void 0,c.allDayDefault)),D(f,g,h,i)}return U.normalizeEvent(i),i}function D(a,b,c,d){d.start=a,d.end=b,d.allDay=c,E(d),Va(d)}function E(a){F(a),a.end&&!a.end.isAfter(a.start)&&(a.end=null),a.end||(c.forceEventDuration?a.end=U.getDefaultEventEnd(a.allDay,a.start):a.end=null)}function F(a){null==a.allDay&&(a.allDay=!(a.start.hasTime()||a.end&&a.end.hasTime())),a.allDay?(a.start.stripTime(),a.end&&a.end.stripTime()):(a.start.hasTime()||(a.start=U.applyTimezone(a.start.time(0))),a.end&&!a.end.hasTime()&&(a.end=U.applyTimezone(a.end.time(0))))}function G(b,c,d){var e,f,g,h,i,j,k,l,m,n=[];if(c=c||W,d=d||X,b)if(b._recurring){if(f=b.dow)for(e={},g=0;g<f.length;g++)e[f[g]]=!0;for(h=c.clone().stripTime();h.isBefore(d);)e&&!e[h.day()]||(i=b.start,j=b.end,k=h.clone(),l=null,i&&(k=k.time(i)),j&&(l=h.clone().time(j)),m=a.extend({},b),D(k,l,!i&&!j,m),n.push(m)),h.add(1,"days")}else n.push(b);return n}function H(b,c,d){function e(a,b){return d?N(a,b,d):c.allDay?M(a,b):L(a,b)}var f,g,h,i,j,k,l={};return c=c||{},c.start||(c.start=b.start.clone()),void 0===c.end&&(c.end=b.end?b.end.clone():null),null==c.allDay&&(c.allDay=b.allDay),E(c),f={start:b._start.clone(),end:b._end?b._end.clone():U.getDefaultEventEnd(b._allDay,b._start),allDay:c.allDay},E(f),g=null!==b._end&&null===c.end,h=e(c.start,f.start),c.end?(i=e(c.end,f.end),j=i.subtract(h)):j=null,a.each(c,function(a,b){y(a)&&void 0!==b&&(l[a]=b)}),k=I(B(b._id),g,c.allDay,h,j,l),{dateDelta:h,durationDelta:j,undo:k}}function I(b,c,d,e,f,g){var h=U.getIsAmbigTimezone(),i=[];return e&&!e.valueOf()&&(e=null),f&&!f.valueOf()&&(f=null),a.each(b,function(b,j){var k,l;k={start:j.start.clone(),end:j.end?j.end.clone():null,allDay:j.allDay},a.each(g,function(a){k[a]=j[a]}),l={start:j._start,end:j._end,allDay:d},E(l),c?l.end=null:f&&!l.end&&(l.end=U.getDefaultEventEnd(l.allDay,l.start)),e&&(l.start.add(e),l.end&&l.end.add(e)),f&&l.end.add(f),h&&!l.allDay&&(e||f)&&(l.start.stripZone(),l.end&&l.end.stripZone()),a.extend(j,g,l),Va(j),i.push(function(){a.extend(j,k),Va(j)})}),function(){for(var a=0;a<i.length;a++)i[a]()}}function J(b){var d,e=c.businessHours,f={className:"fc-nonbusiness",start:"09:00",end:"17:00",dow:[1,2,3,4,5],rendering:"inverse-background"},g=U.getView();return e&&(d=a.extend({},f,"object"==typeof e?e:{})),d?(b&&(d.start=null,d.end=null),G(C(d),g.start,g.end)):[]}function K(a,b){var d=b.source||{},e=ba(b.constraint,d.constraint,c.eventConstraint),f=ba(b.overlap,d.overlap,c.eventOverlap);return Q(a,e,f,b)}function O(b,c,d){var e,f;return d&&(e=a.extend({},d,c),f=G(C(e))[0]),f?K(b,f):P(b)}function P(a){return Q(a,c.selectConstraint,c.selectOverlap)}function Q(a,b,c,d){var e,f,g,h,i,j;if(null!=b){for(e=R(b),f=!1,h=0;h<e.length;h++)if(S(e[h],a)){f=!0;break}if(!f)return!1}for(g=U.getPeerEvents(a,d),h=0;h<g.length;h++)if(i=g[h],T(i,a)){if(c===!1)return!1;if("function"==typeof c&&!c(i,d))return!1;if(d){if(j=ba(i.overlap,(i.source||{}).overlap),j===!1)return!1;if("function"==typeof j&&!j(d,i))return!1}}return!0}function R(a){return"businessHours"===a?J():"object"==typeof a?G(C(a)):B(a)}function S(a,b){var c=a.start.clone().stripZone(),d=U.getEventEnd(a).stripZone();return b.start>=c&&b.end<=d}function T(a,b){var c=a.start.clone().stripZone(),d=U.getEventEnd(a).stripZone();return b.start<d&&b.end>c}var U=this;U.isFetchNeeded=d,U.fetchEvents=e,U.fetchEventSources=f,U.getEventSources=p,U.getEventSourceById=q,U.getEventSourcesByMatchArray=r,U.getEventSourcesByMatch=s,U.addEventSource=k,U.removeEventSource=m,U.removeEventSources=n,U.updateEvent=w,U.renderEvent=z,U.removeEvents=A,U.clientEvents=B,U.mutateEvent=H,U.normalizeEventDates=E,U.normalizeEventTimes=F;var W,X,Y=U.reportEvents,Z={events:[]},$=[Z],ca=0,da=[];a.each((c.events?[c.events]:[]).concat(c.eventSources||[]),function(a,b){var c=l(b);c&&$.push(c)}),U.getBusinessHoursEvents=J,U.isEventSpanAllowed=K,U.isExternalSpanAllowed=O,U.isSelectionSpanAllowed=P,U.getEventCache=function(){return da}}function Va(a){a._allDay=a.allDay,a._start=a.start.clone(),a._end=a.end?a.end.clone():null}var Wa=a.fullCalendar={version:"2.8.0",internalApiVersion:4},Xa=Wa.views={};a.fn.fullCalendar=function(b){var c=Array.prototype.slice.call(arguments,1),d=this;return this.each(function(e,f){var g,h=a(f),i=h.data("fullCalendar");"string"==typeof b?i&&a.isFunction(i[b])&&(g=i[b].apply(i,c),e||(d=g),"destroy"===b&&h.removeData("fullCalendar")):i||(i=new zb(h,b),h.data("fullCalendar",i),i.render())}),d};var Ya=["header","buttonText","buttonIcons","themeButtonIcons"];Wa.intersectRanges=K,Wa.applyAll=aa,Wa.debounce=ja,Wa.isInt=ha,Wa.htmlEscape=ca,Wa.cssToStr=ea,Wa.proxy=ia,Wa.capitaliseFirstLetter=fa,Wa.getOuterRect=n,Wa.getClientRect=o,Wa.getContentRect=p,Wa.getScrollbarWidths=q;var Za=null;Wa.preventDefault=z,Wa.intersectRects=C,Wa.parseFieldSpecs=G,Wa.compareByFieldSpecs=H,Wa.compareByFieldSpec=I,Wa.flexibleCompare=J,Wa.computeIntervalUnit=O,Wa.divideRangeByDuration=Q,Wa.divideDurationByDuration=R,Wa.multiplyDuration=S,Wa.durationHasTime=T;var $a=["sun","mon","tue","wed","thu","fri","sat"],_a=["year","month","week","day","hour","minute","second","millisecond"];Wa.log=function(){var a=window.console;return a&&a.log?a.log.apply(a,arguments):void 0},Wa.warn=function(){var a=window.console;return a&&a.warn?a.warn.apply(a,arguments):Wa.log.apply(Wa,arguments)};var ab,bb,cb,db={}.hasOwnProperty,eb=/^\s*\d{4}-\d\d$/,fb=/^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/,gb=b.fn,hb=a.extend({},gb);Wa.moment=function(){return la(arguments)},Wa.moment.utc=function(){var a=la(arguments,!0);return a.hasTime()&&a.utc(),a},Wa.moment.parseZone=function(){return la(arguments,!0,!0)},gb.clone=function(){var a=hb.clone.apply(this,arguments);return na(this,a),this._fullCalendar&&(a._fullCalendar=!0),a},gb.week=gb.weeks=function(a){var b=(this._locale||this._lang)._fullCalendar_weekCalc;return null==a&&"function"==typeof b?b(this):"ISO"===b?hb.isoWeek.apply(this,arguments):hb.week.apply(this,arguments)},gb.time=function(a){if(!this._fullCalendar)return hb.time.apply(this,arguments);if(null==a)return b.duration({hours:this.hours(),minutes:this.minutes(),seconds:this.seconds(),milliseconds:this.milliseconds()});this._ambigTime=!1,b.isDuration(a)||b.isMoment(a)||(a=b.duration(a));var c=0;return b.isDuration(a)&&(c=24*Math.floor(a.asDays())),this.hours(c+a.hours()).minutes(a.minutes()).seconds(a.seconds()).milliseconds(a.milliseconds())},gb.stripTime=function(){var a;return this._ambigTime||(a=this.toArray(),this.utc(),bb(this,a.slice(0,3)),this._ambigTime=!0,this._ambigZone=!0),this},gb.hasTime=function(){return!this._ambigTime},gb.stripZone=function(){var a,b;return this._ambigZone||(a=this.toArray(),b=this._ambigTime,this.utc(),bb(this,a),this._ambigTime=b||!1,this._ambigZone=!0),this},gb.hasZone=function(){return!this._ambigZone},gb.local=function(){var a=this.toArray(),b=this._ambigZone;return hb.local.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,b&&cb(this,a),this},gb.utc=function(){return hb.utc.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,this},a.each(["zone","utcOffset"],function(a,b){hb[b]&&(gb[b]=function(a){return null!=a&&(this._ambigTime=!1,this._ambigZone=!1),hb[b].apply(this,arguments)})}),gb.format=function(){return this._fullCalendar&&arguments[0]?qa(this,arguments[0]):this._ambigTime?pa(this,"YYYY-MM-DD"):this._ambigZone?pa(this,"YYYY-MM-DD[T]HH:mm:ss"):hb.format.apply(this,arguments)},gb.toISOString=function(){return this._ambigTime?pa(this,"YYYY-MM-DD"):this._ambigZone?pa(this,"YYYY-MM-DD[T]HH:mm:ss"):hb.toISOString.apply(this,arguments)},gb.isWithin=function(a,b){var c=ma([this,a,b]);return c[0]>=c[1]&&c[0]<c[2]},gb.isSame=function(a,b){var c;return this._fullCalendar?b?(c=ma([this,a],!0),hb.isSame.call(c[0],c[1],b)):(a=Wa.moment.parseZone(a),hb.isSame.call(this,a)&&Boolean(this._ambigTime)===Boolean(a._ambigTime)&&Boolean(this._ambigZone)===Boolean(a._ambigZone)):hb.isSame.apply(this,arguments)},a.each(["isBefore","isAfter"],function(a,b){gb[b]=function(a,c){var d;return this._fullCalendar?(d=ma([this,a]),hb[b].call(d[0],d[1],c)):hb[b].apply(this,arguments)}}),ab="_d"in b()&&"updateOffset"in b,bb=ab?function(a,c){a._d.setTime(Date.UTC.apply(Date,c)),b.updateOffset(a,!1)}:oa,cb=ab?function(a,c){a._d.setTime(+new Date(c[0]||0,c[1]||0,c[2]||0,c[3]||0,c[4]||0,c[5]||0,c[6]||0)),b.updateOffset(a,!1)}:oa;var ib={t:function(a){return pa(a,"a").charAt(0)},T:function(a){return pa(a,"A").charAt(0)}};Wa.formatRange=ta;var jb={Y:"year",M:"month",D:"day",d:"day",A:"second",a:"second",T:"second",t:"second",H:"second",h:"second",m:"second",s:"second"},kb={};Wa.Class=ya,ya.extend=function(){var a,b,c=arguments.length;for(a=0;c>a;a++)b=arguments[a],c-1>a&&Aa(this,b);return za(this,b||{});
+},ya.mixin=function(a){Aa(this,a)};var lb=Wa.EmitterMixin={on:function(b,c){var d=function(a,b){return c.apply(b.context||this,b.args||[])};return c.guid||(c.guid=a.guid++),d.guid=c.guid,a(this).on(b,d),this},off:function(b,c){return a(this).off(b,c),this},trigger:function(b){var c=Array.prototype.slice.call(arguments,1);return a(this).triggerHandler(b,{args:c}),this},triggerWith:function(b,c,d){return a(this).triggerHandler(b,{context:c,args:d}),this}},mb=Wa.ListenerMixin=function(){var b=0,c={listenerId:null,listenTo:function(b,c,d){if("object"==typeof c)for(var e in c)c.hasOwnProperty(e)&&this.listenTo(b,e,c[e]);else"string"==typeof c&&b.on(c+"."+this.getListenerNamespace(),a.proxy(d,this))},stopListeningTo:function(a,b){a.off((b||"")+"."+this.getListenerNamespace())},getListenerNamespace:function(){return null==this.listenerId&&(this.listenerId=b++),"_listener"+this.listenerId}};return c}(),nb={isIgnoringMouse:!1,delayUnignoreMouse:null,initMouseIgnoring:function(a){this.delayUnignoreMouse=ja(ia(this,"unignoreMouse"),a||1e3)},tempIgnoreMouse:function(){this.isIgnoringMouse=!0,this.delayUnignoreMouse()},unignoreMouse:function(){this.isIgnoringMouse=!1}},ob=ya.extend(mb,{isHidden:!0,options:null,el:null,margin:10,constructor:function(a){this.options=a||{}},show:function(){this.isHidden&&(this.el||this.render(),this.el.show(),this.position(),this.isHidden=!1,this.trigger("show"))},hide:function(){this.isHidden||(this.el.hide(),this.isHidden=!0,this.trigger("hide"))},render:function(){var b=this,c=this.options;this.el=a('<div class="fc-popover"/>').addClass(c.className||"").css({top:0,left:0}).append(c.content).appendTo(c.parentEl),this.el.on("click",".fc-close",function(){b.hide()}),c.autoHide&&this.listenTo(a(document),"mousedown",this.documentMousedown)},documentMousedown:function(b){this.el&&!a(b.target).closest(this.el).length&&this.hide()},removeElement:function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(a(document),"mousedown")},position:function(){var b,c,d,e,f,g=this.options,h=this.el.offsetParent().offset(),i=this.el.outerWidth(),j=this.el.outerHeight(),k=a(window),l=m(this.el);e=g.top||0,f=void 0!==g.left?g.left:void 0!==g.right?g.right-i:0,l.is(window)||l.is(document)?(l=k,b=0,c=0):(d=l.offset(),b=d.top,c=d.left),b+=k.scrollTop(),c+=k.scrollLeft(),g.viewportConstrain!==!1&&(e=Math.min(e,b+l.outerHeight()-j-this.margin),e=Math.max(e,b+this.margin),f=Math.min(f,c+l.outerWidth()-i-this.margin),f=Math.max(f,c+this.margin)),this.el.css({top:e-h.top,left:f-h.left})},trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1))}}),pb=Wa.CoordCache=ya.extend({els:null,forcedOffsetParentEl:null,origin:null,boundingRect:null,isHorizontal:!1,isVertical:!1,lefts:null,rights:null,tops:null,bottoms:null,constructor:function(b){this.els=a(b.els),this.isHorizontal=b.isHorizontal,this.isVertical=b.isVertical,this.forcedOffsetParentEl=b.offsetParent?a(b.offsetParent):null},build:function(){var a=this.forcedOffsetParentEl||this.els.eq(0).offsetParent();this.origin=a.offset(),this.boundingRect=this.queryBoundingRect(),this.isHorizontal&&this.buildElHorizontals(),this.isVertical&&this.buildElVerticals()},clear:function(){this.origin=null,this.boundingRect=null,this.lefts=null,this.rights=null,this.tops=null,this.bottoms=null},ensureBuilt:function(){this.origin||this.build()},queryBoundingRect:function(){var a=m(this.els.eq(0));return a.is(document)?void 0:o(a)},buildElHorizontals:function(){var b=[],c=[];this.els.each(function(d,e){var f=a(e),g=f.offset().left,h=f.outerWidth();b.push(g),c.push(g+h)}),this.lefts=b,this.rights=c},buildElVerticals:function(){var b=[],c=[];this.els.each(function(d,e){var f=a(e),g=f.offset().top,h=f.outerHeight();b.push(g),c.push(g+h)}),this.tops=b,this.bottoms=c},getHorizontalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.lefts,e=this.rights,f=d.length;if(!c||a>=c.left&&a<c.right)for(b=0;f>b;b++)if(a>=d[b]&&a<e[b])return b},getVerticalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.tops,e=this.bottoms,f=d.length;if(!c||a>=c.top&&a<c.bottom)for(b=0;f>b;b++)if(a>=d[b]&&a<e[b])return b},getLeftOffset:function(a){return this.ensureBuilt(),this.lefts[a]},getLeftPosition:function(a){return this.ensureBuilt(),this.lefts[a]-this.origin.left},getRightOffset:function(a){return this.ensureBuilt(),this.rights[a]},getRightPosition:function(a){return this.ensureBuilt(),this.rights[a]-this.origin.left},getWidth:function(a){return this.ensureBuilt(),this.rights[a]-this.lefts[a]},getTopOffset:function(a){return this.ensureBuilt(),this.tops[a]},getTopPosition:function(a){return this.ensureBuilt(),this.tops[a]-this.origin.top},getBottomOffset:function(a){return this.ensureBuilt(),this.bottoms[a]},getBottomPosition:function(a){return this.ensureBuilt(),this.bottoms[a]-this.origin.top},getHeight:function(a){return this.ensureBuilt(),this.bottoms[a]-this.tops[a]}}),qb=Wa.DragListener=ya.extend(mb,nb,{options:null,subjectEl:null,subjectHref:null,originX:null,originY:null,scrollEl:null,isInteracting:!1,isDistanceSurpassed:!1,isDelayEnded:!1,isDragging:!1,isTouch:!1,delay:null,delayTimeoutId:null,minDistance:null,handleTouchScrollProxy:null,constructor:function(a){this.options=a||{},this.handleTouchScrollProxy=ia(this,"handleTouchScroll"),this.initMouseIgnoring(500)},startInteraction:function(b,c){var d=x(b);if("mousedown"===b.type){if(this.isIgnoringMouse)return;if(!u(b))return;b.preventDefault()}this.isInteracting||(c=c||{},this.delay=ba(c.delay,this.options.delay,0),this.minDistance=ba(c.distance,this.options.distance,0),this.subjectEl=this.options.subjectEl,this.isInteracting=!0,this.isTouch=d,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,this.originX=v(b),this.originY=w(b),this.scrollEl=m(a(b.target)),this.bindHandlers(),this.initAutoScroll(),this.handleInteractionStart(b),this.startDelay(b),this.minDistance||this.handleDistanceSurpassed(b))},handleInteractionStart:function(a){this.trigger("interactionStart",a)},endInteraction:function(a,b){this.isInteracting&&(this.endDrag(a),this.delayTimeoutId&&(clearTimeout(this.delayTimeoutId),this.delayTimeoutId=null),this.destroyAutoScroll(),this.unbindHandlers(),this.isInteracting=!1,this.handleInteractionEnd(a,b),this.isTouch&&this.tempIgnoreMouse())},handleInteractionEnd:function(a,b){this.trigger("interactionEnd",a,b||!1)},bindHandlers:function(){var b=this,c=1;this.isTouch?(this.listenTo(a(document),{touchmove:this.handleTouchMove,touchend:this.endInteraction,touchcancel:this.endInteraction,touchstart:function(a){c?c--:b.endInteraction(a,!0)}}),!A(this.handleTouchScrollProxy)&&this.scrollEl&&this.listenTo(this.scrollEl,"scroll",this.handleTouchScroll)):this.listenTo(a(document),{mousemove:this.handleMouseMove,mouseup:this.endInteraction}),this.listenTo(a(document),{selectstart:z,contextmenu:z})},unbindHandlers:function(){this.stopListeningTo(a(document)),B(this.handleTouchScrollProxy),this.scrollEl&&this.stopListeningTo(this.scrollEl,"scroll")},startDrag:function(a,b){this.startInteraction(a,b),this.isDragging||(this.isDragging=!0,this.handleDragStart(a))},handleDragStart:function(a){this.trigger("dragStart",a),this.initHrefHack()},handleMove:function(a){var b,c=v(a)-this.originX,d=w(a)-this.originY,e=this.minDistance;this.isDistanceSurpassed||(b=c*c+d*d,b>=e*e&&this.handleDistanceSurpassed(a)),this.isDragging&&this.handleDrag(c,d,a)},handleDrag:function(a,b,c){this.trigger("drag",a,b,c),this.updateAutoScroll(c)},endDrag:function(a){this.isDragging&&(this.isDragging=!1,this.handleDragEnd(a))},handleDragEnd:function(a){this.trigger("dragEnd",a),this.destroyHrefHack()},startDelay:function(a){var b=this;this.delay?this.delayTimeoutId=setTimeout(function(){b.handleDelayEnd(a)},this.delay):this.handleDelayEnd(a)},handleDelayEnd:function(a){this.isDelayEnded=!0,this.isDistanceSurpassed&&this.startDrag(a)},handleDistanceSurpassed:function(a){this.isDistanceSurpassed=!0,this.isDelayEnded&&this.startDrag(a)},handleTouchMove:function(a){this.isDragging&&a.preventDefault(),this.handleMove(a)},handleMouseMove:function(a){this.handleMove(a)},handleTouchScroll:function(a){this.isDragging||this.endInteraction(a,!0)},initHrefHack:function(){var a=this.subjectEl;(this.subjectHref=a?a.attr("href"):null)&&a.removeAttr("href")},destroyHrefHack:function(){var a=this.subjectEl,b=this.subjectHref;setTimeout(function(){b&&a.attr("href",b)},0)},trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1)),this["_"+a]&&this["_"+a].apply(this,Array.prototype.slice.call(arguments,1))}});qb.mixin({isAutoScroll:!1,scrollBounds:null,scrollTopVel:null,scrollLeftVel:null,scrollIntervalId:null,scrollSensitivity:30,scrollSpeed:200,scrollIntervalMs:50,initAutoScroll:function(){var a=this.scrollEl;this.isAutoScroll=this.options.scroll&&a&&!a.is(window)&&!a.is(document),this.isAutoScroll&&this.listenTo(a,"scroll",ja(this.handleDebouncedScroll,100))},destroyAutoScroll:function(){this.endAutoScroll(),this.isAutoScroll&&this.stopListeningTo(this.scrollEl,"scroll")},computeScrollBounds:function(){this.isAutoScroll&&(this.scrollBounds=n(this.scrollEl))},updateAutoScroll:function(a){var b,c,d,e,f=this.scrollSensitivity,g=this.scrollBounds,h=0,i=0;g&&(b=(f-(w(a)-g.top))/f,c=(f-(g.bottom-w(a)))/f,d=(f-(v(a)-g.left))/f,e=(f-(g.right-v(a)))/f,b>=0&&1>=b?h=b*this.scrollSpeed*-1:c>=0&&1>=c&&(h=c*this.scrollSpeed),d>=0&&1>=d?i=d*this.scrollSpeed*-1:e>=0&&1>=e&&(i=e*this.scrollSpeed)),this.setScrollVel(h,i)},setScrollVel:function(a,b){this.scrollTopVel=a,this.scrollLeftVel=b,this.constrainScrollVel(),!this.scrollTopVel&&!this.scrollLeftVel||this.scrollIntervalId||(this.scrollIntervalId=setInterval(ia(this,"scrollIntervalFunc"),this.scrollIntervalMs))},constrainScrollVel:function(){var a=this.scrollEl;this.scrollTopVel<0?a.scrollTop()<=0&&(this.scrollTopVel=0):this.scrollTopVel>0&&a.scrollTop()+a[0].clientHeight>=a[0].scrollHeight&&(this.scrollTopVel=0),this.scrollLeftVel<0?a.scrollLeft()<=0&&(this.scrollLeftVel=0):this.scrollLeftVel>0&&a.scrollLeft()+a[0].clientWidth>=a[0].scrollWidth&&(this.scrollLeftVel=0)},scrollIntervalFunc:function(){var a=this.scrollEl,b=this.scrollIntervalMs/1e3;this.scrollTopVel&&a.scrollTop(a.scrollTop()+this.scrollTopVel*b),this.scrollLeftVel&&a.scrollLeft(a.scrollLeft()+this.scrollLeftVel*b),this.constrainScrollVel(),this.scrollTopVel||this.scrollLeftVel||this.endAutoScroll()},endAutoScroll:function(){this.scrollIntervalId&&(clearInterval(this.scrollIntervalId),this.scrollIntervalId=null,this.handleScrollEnd())},handleDebouncedScroll:function(){this.scrollIntervalId||this.handleScrollEnd()},handleScrollEnd:function(){}});var rb=qb.extend({component:null,origHit:null,hit:null,coordAdjust:null,constructor:function(a,b){qb.call(this,b),this.component=a},handleInteractionStart:function(a){var b,c,d,e=this.subjectEl;this.computeCoords(),a?(c={left:v(a),top:w(a)},d=c,e&&(b=n(e),d=D(d,b)),this.origHit=this.queryHit(d.left,d.top),e&&this.options.subjectCenter&&(this.origHit&&(b=C(this.origHit,b)||b),d=E(b)),this.coordAdjust=F(d,c)):(this.origHit=null,this.coordAdjust=null),qb.prototype.handleInteractionStart.apply(this,arguments)},computeCoords:function(){this.component.prepareHits(),this.computeScrollBounds()},handleDragStart:function(a){var b;qb.prototype.handleDragStart.apply(this,arguments),b=this.queryHit(v(a),w(a)),b&&this.handleHitOver(b)},handleDrag:function(a,b,c){var d;qb.prototype.handleDrag.apply(this,arguments),d=this.queryHit(v(c),w(c)),Ba(d,this.hit)||(this.hit&&this.handleHitOut(),d&&this.handleHitOver(d))},handleDragEnd:function(){this.handleHitDone(),qb.prototype.handleDragEnd.apply(this,arguments)},handleHitOver:function(a){var b=Ba(a,this.origHit);this.hit=a,this.trigger("hitOver",this.hit,b,this.origHit)},handleHitOut:function(){this.hit&&(this.trigger("hitOut",this.hit),this.handleHitDone(),this.hit=null)},handleHitDone:function(){this.hit&&this.trigger("hitDone",this.hit)},handleInteractionEnd:function(){qb.prototype.handleInteractionEnd.apply(this,arguments),this.origHit=null,this.hit=null,this.component.releaseHits()},handleScrollEnd:function(){qb.prototype.handleScrollEnd.apply(this,arguments),this.computeCoords()},queryHit:function(a,b){return this.coordAdjust&&(a+=this.coordAdjust.left,b+=this.coordAdjust.top),this.component.queryHit(a,b)}}),sb=ya.extend(mb,{options:null,sourceEl:null,el:null,parentEl:null,top0:null,left0:null,y0:null,x0:null,topDelta:null,leftDelta:null,isFollowing:!1,isHidden:!1,isAnimating:!1,constructor:function(b,c){this.options=c=c||{},this.sourceEl=b,this.parentEl=c.parentEl?a(c.parentEl):b.parent()},start:function(b){this.isFollowing||(this.isFollowing=!0,this.y0=w(b),this.x0=v(b),this.topDelta=0,this.leftDelta=0,this.isHidden||this.updatePosition(),x(b)?this.listenTo(a(document),"touchmove",this.handleMove):this.listenTo(a(document),"mousemove",this.handleMove))},stop:function(b,c){function d(){this.isAnimating=!1,e.removeElement(),this.top0=this.left0=null,c&&c()}var e=this,f=this.options.revertDuration;this.isFollowing&&!this.isAnimating&&(this.isFollowing=!1,this.stopListeningTo(a(document)),b&&f&&!this.isHidden?(this.isAnimating=!0,this.el.animate({top:this.top0,left:this.left0},{duration:f,complete:d})):d())},getEl:function(){var a=this.el;return a||(this.sourceEl.width(),a=this.el=this.sourceEl.clone().addClass(this.options.additionalClass||"").css({position:"absolute",visibility:"",display:this.isHidden?"none":"",margin:0,right:"auto",bottom:"auto",width:this.sourceEl.width(),height:this.sourceEl.height(),opacity:this.options.opacity||"",zIndex:this.options.zIndex}),a.addClass("fc-unselectable"),a.appendTo(this.parentEl)),a},removeElement:function(){this.el&&(this.el.remove(),this.el=null)},updatePosition:function(){var a,b;this.getEl(),null===this.top0&&(this.sourceEl.width(),a=this.sourceEl.offset(),b=this.el.offsetParent().offset(),this.top0=a.top-b.top,this.left0=a.left-b.left),this.el.css({top:this.top0+this.topDelta,left:this.left0+this.leftDelta})},handleMove:function(a){this.topDelta=w(a)-this.y0,this.leftDelta=v(a)-this.x0,this.isHidden||this.updatePosition()},hide:function(){this.isHidden||(this.isHidden=!0,this.el&&this.el.hide())},show:function(){this.isHidden&&(this.isHidden=!1,this.updatePosition(),this.getEl().show())}}),tb=Wa.Grid=ya.extend(mb,nb,{view:null,isRTL:null,start:null,end:null,el:null,elsByFill:null,eventTimeFormat:null,displayEventTime:null,displayEventEnd:null,minResizeDuration:null,largeUnit:null,dayDragListener:null,segDragListener:null,segResizeListener:null,externalDragListener:null,constructor:function(a){this.view=a,this.isRTL=a.opt("isRTL"),this.elsByFill={},this.dayDragListener=this.buildDayDragListener(),this.initMouseIgnoring()},computeEventTimeFormat:function(){return this.view.opt("smallTimeFormat")},computeDisplayEventTime:function(){return!0},computeDisplayEventEnd:function(){return!0},setRange:function(a){this.start=a.start.clone(),this.end=a.end.clone(),this.rangeUpdated(),this.processRangeOptions()},rangeUpdated:function(){},processRangeOptions:function(){var a,b,c=this.view;this.eventTimeFormat=c.opt("eventTimeFormat")||c.opt("timeFormat")||this.computeEventTimeFormat(),a=c.opt("displayEventTime"),null==a&&(a=this.computeDisplayEventTime()),b=c.opt("displayEventEnd"),null==b&&(b=this.computeDisplayEventEnd()),this.displayEventTime=a,this.displayEventEnd=b},spanToSegs:function(a){},diffDates:function(a,b){return this.largeUnit?N(a,b,this.largeUnit):L(a,b)},prepareHits:function(){},releaseHits:function(){},queryHit:function(a,b){},getHitSpan:function(a){},getHitEl:function(a){},setElement:function(a){this.el=a,y(a),this.bindDayHandler("touchstart",this.dayTouchStart),this.bindDayHandler("mousedown",this.dayMousedown),this.bindSegHandlers(),this.bindGlobalHandlers()},bindDayHandler:function(b,c){var d=this;this.el.on(b,function(b){return a(b.target).is(".fc-event-container *, .fc-more")||a(b.target).closest(".fc-popover").length?void 0:c.call(d,b)})},removeElement:function(){this.unbindGlobalHandlers(),this.clearDragListeners(),this.el.remove()},renderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},bindGlobalHandlers:function(){this.listenTo(a(document),{dragstart:this.externalDragStart,sortstart:this.externalDragStart})},unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},dayMousedown:function(a){this.isIgnoringMouse||this.dayDragListener.startInteraction(a,{})},dayTouchStart:function(a){var b=this.view;(b.isSelected||b.selectedEvent)&&this.tempIgnoreMouse(),this.dayDragListener.startInteraction(a,{delay:this.view.opt("longPressDelay")})},buildDayDragListener:function(){var a,b,c=this,d=this.view,e=d.opt("selectable"),f=new rb(this,{scroll:d.opt("dragScroll"),interactionStart:function(){a=f.origHit},dragStart:function(){d.unselect()},hitOver:function(d,f,h){h&&(f||(a=null),e&&(b=c.computeSelection(c.getHitSpan(h),c.getHitSpan(d)),b?c.renderSelection(b):b===!1&&g()))},hitOut:function(){a=null,b=null,c.unrenderSelection(),h()},interactionEnd:function(e,f){f||(a&&!c.isIgnoringMouse&&d.triggerDayClick(c.getHitSpan(a),c.getHitEl(a),e),b&&d.reportSelection(b,e),h())}});return f},clearDragListeners:function(){this.dayDragListener.endInteraction(),this.segDragListener&&this.segDragListener.endInteraction(),this.segResizeListener&&this.segResizeListener.endInteraction(),this.externalDragListener&&this.externalDragListener.endInteraction()},renderEventLocationHelper:function(a,b){var c=this.fabricateHelperEvent(a,b);return this.renderHelper(c,b)},fabricateHelperEvent:function(a,b){var c=b?X(b.event):{};return c.start=a.start.clone(),c.end=a.end?a.end.clone():null,c.allDay=null,this.view.calendar.normalizeEventDates(c),c.className=(c.className||[]).concat("fc-helper"),b||(c.editable=!1),c},renderHelper:function(a,b){},unrenderHelper:function(){},renderSelection:function(a){this.renderHighlight(a)},unrenderSelection:function(){this.unrenderHighlight()},computeSelection:function(a,b){var c=this.computeSelectionSpan(a,b);return c&&!this.view.calendar.isSelectionSpanAllowed(c)?!1:c},computeSelectionSpan:function(a,b){var c=[a.start,a.end,b.start,b.end];return c.sort(ga),{start:c[0].clone(),end:c[3].clone()}},renderHighlight:function(a){this.renderFill("highlight",this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderFill("highlight")},highlightSegClasses:function(){return["fc-highlight"]},renderBusinessHours:function(){},unrenderBusinessHours:function(){},getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},renderFill:function(a,b){},unrenderFill:function(a){var b=this.elsByFill[a];b&&(b.remove(),delete this.elsByFill[a])},renderFillSegEls:function(b,c){var d,e=this,f=this[b+"SegEl"],g="",h=[];if(c.length){for(d=0;d<c.length;d++)g+=this.fillSegHtml(b,c[d]);a(g).each(function(b,d){var g=c[b],i=a(d);f&&(i=f.call(e,g,i)),i&&(i=a(i),i.is(e.fillSegTag)&&(g.el=i,h.push(g)))})}return h},fillSegTag:"div",fillSegHtml:function(a,b){var c=this[a+"SegClasses"],d=this[a+"SegCss"],e=c?c.call(this,b):[],f=ea(d?d.call(this,b):{});return"<"+this.fillSegTag+(e.length?' class="'+e.join(" ")+'"':"")+(f?' style="'+f+'"':"")+" />"},getDayClasses:function(a){var b=this.view,c=b.calendar.getNow(),d=["fc-"+$a[a.day()]];return 1==b.intervalDuration.as("months")&&a.month()!=b.intervalStart.month()&&d.push("fc-other-month"),a.isSame(c,"day")?d.push("fc-today",b.highlightStateClass):c>a?d.push("fc-past"):d.push("fc-future"),d}});tb.mixin({mousedOverSeg:null,isDraggingSeg:!1,isResizingSeg:!1,isDraggingExternal:!1,segs:null,renderEvents:function(a){var b,c=[],d=[];for(b=0;b<a.length;b++)(Da(a[b])?c:d).push(a[b]);this.segs=[].concat(this.renderBgEvents(c),this.renderFgEvents(d))},renderBgEvents:function(a){var b=this.eventsToSegs(a);return this.renderBgSegs(b)||b},renderFgEvents:function(a){var b=this.eventsToSegs(a);return this.renderFgSegs(b)||b},unrenderEvents:function(){this.handleSegMouseout(),this.clearDragListeners(),this.unrenderFgSegs(),this.unrenderBgSegs(),this.segs=null},getEventSegs:function(){return this.segs||[]},renderFgSegs:function(a){},unrenderFgSegs:function(){},renderFgSegEls:function(b,c){var d,e=this.view,f="",g=[];if(b.length){for(d=0;d<b.length;d++)f+=this.fgSegHtml(b[d],c);a(f).each(function(c,d){var f=b[c],h=e.resolveEventEl(f.event,a(d));h&&(h.data("fc-seg",f),f.el=h,g.push(f))})}return g},fgSegHtml:function(a,b){},renderBgSegs:function(a){return this.renderFill("bgEvent",a)},unrenderBgSegs:function(){this.unrenderFill("bgEvent")},bgEventSegEl:function(a,b){return this.view.resolveEventEl(a.event,b)},bgEventSegClasses:function(a){var b=a.event,c=b.source||{};return["fc-bgevent"].concat(b.className,c.className||[])},bgEventSegCss:function(a){return{"background-color":this.getSegSkinCss(a)["background-color"]}},businessHoursSegClasses:function(a){return["fc-nonbusiness","fc-bgevent"]},bindSegHandlers:function(){this.bindSegHandler("touchstart",this.handleSegTouchStart),this.bindSegHandler("touchend",this.handleSegTouchEnd),this.bindSegHandler("mouseenter",this.handleSegMouseover),this.bindSegHandler("mouseleave",this.handleSegMouseout),this.bindSegHandler("mousedown",this.handleSegMousedown),this.bindSegHandler("click",this.handleSegClick)},bindSegHandler:function(b,c){var d=this;this.el.on(b,".fc-event-container > *",function(b){var e=a(this).data("fc-seg");return!e||d.isDraggingSeg||d.isResizingSeg?void 0:c.call(d,e,b)})},handleSegClick:function(a,b){return this.view.trigger("eventClick",a.el[0],a.event,b)},handleSegMouseover:function(a,b){this.isIgnoringMouse||this.mousedOverSeg||(this.mousedOverSeg=a,a.el.addClass("fc-allow-mouse-resize"),this.view.trigger("eventMouseover",a.el[0],a.event,b))},handleSegMouseout:function(a,b){b=b||{},this.mousedOverSeg&&(a=a||this.mousedOverSeg,this.mousedOverSeg=null,a.el.removeClass("fc-allow-mouse-resize"),this.view.trigger("eventMouseout",a.el[0],a.event,b))},handleSegMousedown:function(a,b){var c=this.startSegResize(a,b,{distance:5});!c&&this.view.isEventDraggable(a.event)&&this.buildSegDragListener(a).startInteraction(b,{distance:5})},handleSegTouchStart:function(a,b){var c,d=this.view,e=a.event,f=d.isEventSelected(e),g=d.isEventDraggable(e),h=d.isEventResizable(e),i=!1;f&&h&&(i=this.startSegResize(a,b)),i||!g&&!h||(c=g?this.buildSegDragListener(a):this.buildSegSelectListener(a),c.startInteraction(b,{delay:f?0:this.view.opt("longPressDelay")})),this.tempIgnoreMouse()},handleSegTouchEnd:function(a,b){this.tempIgnoreMouse()},startSegResize:function(b,c,d){return a(c.target).is(".fc-resizer")?(this.buildSegResizeListener(b,a(c.target).is(".fc-start-resizer")).startInteraction(c,d),!0):!1},buildSegDragListener:function(a){var b,c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event;if(this.segDragListener)return this.segDragListener;var l=this.segDragListener=new rb(f,{scroll:f.opt("dragScroll"),subjectEl:j,subjectCenter:!0,interactionStart:function(d){b=!1,c=new sb(a.el,{additionalClass:"fc-dragging",parentEl:f.el,opacity:l.isTouch?null:f.opt("dragOpacity"),revertDuration:f.opt("dragRevertDuration"),zIndex:2}),c.hide(),c.start(d)},dragStart:function(c){l.isTouch&&!f.isEventSelected(k)&&f.selectEvent(k),b=!0,e.handleSegMouseout(a,c),e.segDragStart(a,c),f.hideEvent(k)},hitOver:function(b,h,j){var m;a.hit&&(j=a.hit),d=e.computeEventDrop(j.component.getHitSpan(j),b.component.getHitSpan(b),k),d&&!i.isEventSpanAllowed(e.eventToSpan(d),k)&&(g(),d=null),d&&(m=f.renderDrag(d,a))?(m.addClass("fc-dragging"),l.isTouch||e.applyDragOpacity(m),c.hide()):c.show(),h&&(d=null)},hitOut:function(){f.unrenderDrag(),c.show(),d=null},hitDone:function(){h()},interactionEnd:function(g){c.stop(!d,function(){b&&(f.unrenderDrag(),f.showEvent(k),e.segDragStop(a,g)),d&&f.reportEventDrop(k,d,this.largeUnit,j,g)}),e.segDragListener=null}});return l},buildSegSelectListener:function(a){var b=this,c=this.view,d=a.event;if(this.segDragListener)return this.segDragListener;var e=this.segDragListener=new qb({dragStart:function(a){e.isTouch&&!c.isEventSelected(d)&&c.selectEvent(d)},interactionEnd:function(a){b.segDragListener=null}});return e},segDragStart:function(a,b){this.isDraggingSeg=!0,this.view.trigger("eventDragStart",a.el[0],a.event,b,{})},segDragStop:function(a,b){this.isDraggingSeg=!1,this.view.trigger("eventDragStop",a.el[0],a.event,b,{})},computeEventDrop:function(a,b,c){var d,e,f=this.view.calendar,g=a.start,h=b.start;return g.hasTime()===h.hasTime()?(d=this.diffDates(h,g),c.allDay&&T(d)?(e={start:c.start.clone(),end:f.getEventEnd(c),allDay:!1},f.normalizeEventTimes(e)):e={start:c.start.clone(),end:c.end?c.end.clone():null,allDay:c.allDay},e.start.add(d),e.end&&e.end.add(d)):e={start:h.clone(),end:null,allDay:!h.hasTime()},e},applyDragOpacity:function(a){var b=this.view.opt("dragOpacity");null!=b&&a.each(function(a,c){c.style.opacity=b})},externalDragStart:function(b,c){var d,e,f=this.view;f.opt("droppable")&&(d=a((c?c.item:null)||b.target),e=f.opt("dropAccept"),(a.isFunction(e)?e.call(d[0],d):d.is(e))&&(this.isDraggingExternal||this.listenToExternalDrag(d,b,c)))},listenToExternalDrag:function(a,b,c){var d,e=this,f=this.view.calendar,i=Ia(a),j=e.externalDragListener=new rb(this,{interactionStart:function(){e.isDraggingExternal=!0},hitOver:function(a){d=e.computeExternalDrop(a.component.getHitSpan(a),i),d&&!f.isExternalSpanAllowed(e.eventToSpan(d),d,i.eventProps)&&(g(),d=null),d&&e.renderDrag(d)},hitOut:function(){d=null},hitDone:function(){h(),e.unrenderDrag()},interactionEnd:function(b){d&&e.view.reportExternalDrop(i,d,a,b,c),e.isDraggingExternal=!1,e.externalDragListener=null}});j.startDrag(b)},computeExternalDrop:function(a,b){var c=this.view.calendar,d={start:c.applyTimezone(a.start),end:null};return b.startTime&&!d.start.hasTime()&&d.start.time(b.startTime),b.duration&&(d.end=d.start.clone().add(b.duration)),d},renderDrag:function(a,b){},unrenderDrag:function(){},buildSegResizeListener:function(a,b){var c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event,l=i.getEventEnd(k),m=this.segResizeListener=new rb(this,{scroll:f.opt("dragScroll"),subjectEl:j,interactionStart:function(){c=!1},dragStart:function(b){c=!0,e.handleSegMouseout(a,b),e.segResizeStart(a,b)},hitOver:function(c,h,j){var m=e.getHitSpan(j),n=e.getHitSpan(c);d=b?e.computeEventStartResize(m,n,k):e.computeEventEndResize(m,n,k),d&&(i.isEventSpanAllowed(e.eventToSpan(d),k)?d.start.isSame(k.start)&&d.end.isSame(l)&&(d=null):(g(),d=null)),d&&(f.hideEvent(k),e.renderEventResize(d,a))},hitOut:function(){d=null},hitDone:function(){e.unrenderEventResize(),f.showEvent(k),h()},interactionEnd:function(b){c&&e.segResizeStop(a,b),d&&f.reportEventResize(k,d,this.largeUnit,j,b),e.segResizeListener=null}});return m},segResizeStart:function(a,b){this.isResizingSeg=!0,this.view.trigger("eventResizeStart",a.el[0],a.event,b,{})},segResizeStop:function(a,b){this.isResizingSeg=!1,this.view.trigger("eventResizeStop",a.el[0],a.event,b,{})},computeEventStartResize:function(a,b,c){return this.computeEventResize("start",a,b,c)},computeEventEndResize:function(a,b,c){return this.computeEventResize("end",a,b,c)},computeEventResize:function(a,b,c,d){var e,f,g=this.view.calendar,h=this.diffDates(c[a],b[a]);return e={start:d.start.clone(),end:g.getEventEnd(d),allDay:d.allDay},e.allDay&&T(h)&&(e.allDay=!1,g.normalizeEventTimes(e)),e[a].add(h),e.start.isBefore(e.end)||(f=this.minResizeDuration||(d.allDay?g.defaultAllDayEventDuration:g.defaultTimedEventDuration),"start"==a?e.start=e.end.clone().subtract(f):e.end=e.start.clone().add(f)),e},renderEventResize:function(a,b){},unrenderEventResize:function(){},getEventTimeText:function(a,b,c){return null==b&&(b=this.eventTimeFormat),null==c&&(c=this.displayEventEnd),this.displayEventTime&&a.start.hasTime()?c&&a.end?this.view.formatRange(a,b):a.start.format(b):""},getSegClasses:function(a,b,c){var d=this.view,e=a.event,f=["fc-event",a.isStart?"fc-start":"fc-not-start",a.isEnd?"fc-end":"fc-not-end"].concat(e.className,e.source?e.source.className:[]);return b&&f.push("fc-draggable"),c&&f.push("fc-resizable"),d.isEventSelected(e)&&f.push("fc-selected"),f},getSegSkinCss:function(a){var b=a.event,c=this.view,d=b.source||{},e=b.color,f=d.color,g=c.opt("eventColor");return{"background-color":b.backgroundColor||e||d.backgroundColor||f||c.opt("eventBackgroundColor")||g,"border-color":b.borderColor||e||d.borderColor||f||c.opt("eventBorderColor")||g,color:b.textColor||d.textColor||c.opt("eventTextColor")}},eventToSegs:function(a){return this.eventsToSegs([a])},eventToSpan:function(a){return this.eventToSpans(a)[0]},eventToSpans:function(a){var b=this.eventToRange(a);return this.eventRangeToSpans(b,a)},eventsToSegs:function(b,c){var d=this,e=Ga(b),f=[];return a.each(e,function(a,b){var e,g=[];for(e=0;e<b.length;e++)g.push(d.eventToRange(b[e]));if(Ea(b[0]))for(g=d.invertRanges(g),e=0;e<g.length;e++)f.push.apply(f,d.eventRangeToSegs(g[e],b[0],c));else for(e=0;e<g.length;e++)f.push.apply(f,d.eventRangeToSegs(g[e],b[e],c))}),f},eventToRange:function(a){return{start:a.start.clone().stripZone(),end:(a.end?a.end.clone():this.view.calendar.getDefaultEventEnd(null!=a.allDay?a.allDay:!a.start.hasTime(),a.start)).stripZone()}},eventRangeToSegs:function(a,b,c){var d,e=this.eventRangeToSpans(a,b),f=[];for(d=0;d<e.length;d++)f.push.apply(f,this.eventSpanToSegs(e[d],b,c));return f},eventRangeToSpans:function(b,c){return[a.extend({},b)]},eventSpanToSegs:function(a,b,c){var d,e,f=c?c(a):this.spanToSegs(a);for(d=0;d<f.length;d++)e=f[d],e.event=b,e.eventStartMS=+a.start,e.eventDurationMS=a.end-a.start;return f},invertRanges:function(a){var b,c,d=this.view,e=d.start.clone(),f=d.end.clone(),g=[],h=e;for(a.sort(Ha),b=0;b<a.length;b++)c=a[b],c.start>h&&g.push({start:h,end:c.start}),h=c.end;return f>h&&g.push({start:h,end:f}),g},sortEventSegs:function(a){a.sort(ia(this,"compareEventSegs"))},compareEventSegs:function(a,b){return a.eventStartMS-b.eventStartMS||b.eventDurationMS-a.eventDurationMS||b.event.allDay-a.event.allDay||H(a.event,b.event,this.view.eventOrderSpecs)}}),Wa.isBgEvent=Da,Wa.dataAttrPrefix="";var ub=Wa.DayTableMixin={breakOnWeeks:!1,dayDates:null,dayIndices:null,daysPerRow:null,rowCnt:null,colCnt:null,colHeadFormat:null,updateDayTable:function(){for(var a,b,c,d=this.view,e=this.start.clone(),f=-1,g=[],h=[];e.isBefore(this.end);)d.isHiddenDay(e)?g.push(f+.5):(f++,g.push(f),h.push(e.clone())),e.add(1,"days");if(this.breakOnWeeks){for(b=h[0].day(),a=1;a<h.length&&h[a].day()!=b;a++);c=Math.ceil(h.length/a)}else c=1,a=h.length;this.dayDates=h,this.dayIndices=g,this.daysPerRow=a,this.rowCnt=c,this.updateDayTableCols()},updateDayTableCols:function(){this.colCnt=this.computeColCnt(),this.colHeadFormat=this.view.opt("columnFormat")||this.computeColHeadFormat()},computeColCnt:function(){return this.daysPerRow},getCellDate:function(a,b){return this.dayDates[this.getCellDayIndex(a,b)].clone()},getCellRange:function(a,b){var c=this.getCellDate(a,b),d=c.clone().add(1,"days");return{start:c,end:d}},getCellDayIndex:function(a,b){return a*this.daysPerRow+this.getColDayIndex(b)},getColDayIndex:function(a){return this.isRTL?this.colCnt-1-a:a},getDateDayIndex:function(a){var b=this.dayIndices,c=a.diff(this.start,"days");return 0>c?b[0]-1:c>=b.length?b[b.length-1]+1:b[c]},computeColHeadFormat:function(){return this.rowCnt>1||this.colCnt>10?"ddd":this.colCnt>1?this.view.opt("dayOfMonthFormat"):"dddd"},sliceRangeByRow:function(a){var b,c,d,e,f,g=this.daysPerRow,h=this.view.computeDayRange(a),i=this.getDateDayIndex(h.start),j=this.getDateDayIndex(h.end.clone().subtract(1,"days")),k=[];for(b=0;b<this.rowCnt;b++)c=b*g,d=c+g-1,e=Math.max(i,c),f=Math.min(j,d),e=Math.ceil(e),f=Math.floor(f),f>=e&&k.push({row:b,firstRowDayIndex:e-c,lastRowDayIndex:f-c,isStart:e===i,isEnd:f===j});return k},sliceRangeByDay:function(a){var b,c,d,e,f,g,h=this.daysPerRow,i=this.view.computeDayRange(a),j=this.getDateDayIndex(i.start),k=this.getDateDayIndex(i.end.clone().subtract(1,"days")),l=[];for(b=0;b<this.rowCnt;b++)for(c=b*h,
+d=c+h-1,e=c;d>=e;e++)f=Math.max(j,e),g=Math.min(k,e),f=Math.ceil(f),g=Math.floor(g),g>=f&&l.push({row:b,firstRowDayIndex:f-c,lastRowDayIndex:g-c,isStart:f===j,isEnd:g===k});return l},renderHeadHtml:function(){var a=this.view;return'<div class="fc-row '+a.widgetHeaderClass+'"><table><thead>'+this.renderHeadTrHtml()+"</thead></table></div>"},renderHeadIntroHtml:function(){return this.renderIntroHtml()},renderHeadTrHtml:function(){return"<tr>"+(this.isRTL?"":this.renderHeadIntroHtml())+this.renderHeadDateCellsHtml()+(this.isRTL?this.renderHeadIntroHtml():"")+"</tr>"},renderHeadDateCellsHtml:function(){var a,b,c=[];for(a=0;a<this.colCnt;a++)b=this.getCellDate(0,a),c.push(this.renderHeadDateCellHtml(b));return c.join("")},renderHeadDateCellHtml:function(a,b,c){var d=this.view;return'<th class="fc-day-header '+d.widgetHeaderClass+" fc-"+$a[a.day()]+'"'+(1==this.rowCnt?' data-date="'+a.format("YYYY-MM-DD")+'"':"")+(b>1?' colspan="'+b+'"':"")+(c?" "+c:"")+">"+ca(a.format(this.colHeadFormat))+"</th>"},renderBgTrHtml:function(a){return"<tr>"+(this.isRTL?"":this.renderBgIntroHtml(a))+this.renderBgCellsHtml(a)+(this.isRTL?this.renderBgIntroHtml(a):"")+"</tr>"},renderBgIntroHtml:function(a){return this.renderIntroHtml()},renderBgCellsHtml:function(a){var b,c,d=[];for(b=0;b<this.colCnt;b++)c=this.getCellDate(a,b),d.push(this.renderBgCellHtml(c));return d.join("")},renderBgCellHtml:function(a,b){var c=this.view,d=this.getDayClasses(a);return d.unshift("fc-day",c.widgetContentClass),'<td class="'+d.join(" ")+'" data-date="'+a.format("YYYY-MM-DD")+'"'+(b?" "+b:"")+"></td>"},renderIntroHtml:function(){},bookendCells:function(a){var b=this.renderIntroHtml();b&&(this.isRTL?a.append(b):a.prepend(b))}},vb=Wa.DayGrid=tb.extend(ub,{numbersVisible:!1,bottomCoordPadding:0,rowEls:null,cellEls:null,helperEls:null,rowCoordCache:null,colCoordCache:null,renderDates:function(a){var b,c,d=this.view,e=this.rowCnt,f=this.colCnt,g="";for(b=0;e>b;b++)g+=this.renderDayRowHtml(b,a);for(this.el.html(g),this.rowEls=this.el.find(".fc-row"),this.cellEls=this.el.find(".fc-day"),this.rowCoordCache=new pb({els:this.rowEls,isVertical:!0}),this.colCoordCache=new pb({els:this.cellEls.slice(0,this.colCnt),isHorizontal:!0}),b=0;e>b;b++)for(c=0;f>c;c++)d.trigger("dayRender",null,this.getCellDate(b,c),this.getCellEl(b,c))},unrenderDates:function(){this.removeSegPopover()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(!0),b=this.eventsToSegs(a);this.renderFill("businessHours",b,"bgevent")},renderDayRowHtml:function(a,b){var c=this.view,d=["fc-row","fc-week",c.widgetContentClass];return b&&d.push("fc-rigid"),'<div class="'+d.join(" ")+'"><div class="fc-bg"><table>'+this.renderBgTrHtml(a)+'</table></div><div class="fc-content-skeleton"><table>'+(this.numbersVisible?"<thead>"+this.renderNumberTrHtml(a)+"</thead>":"")+"</table></div></div>"},renderNumberTrHtml:function(a){return"<tr>"+(this.isRTL?"":this.renderNumberIntroHtml(a))+this.renderNumberCellsHtml(a)+(this.isRTL?this.renderNumberIntroHtml(a):"")+"</tr>"},renderNumberIntroHtml:function(a){return this.renderIntroHtml()},renderNumberCellsHtml:function(a){var b,c,d=[];for(b=0;b<this.colCnt;b++)c=this.getCellDate(a,b),d.push(this.renderNumberCellHtml(c));return d.join("")},renderNumberCellHtml:function(a){var b;return this.view.dayNumbersVisible?(b=this.getDayClasses(a),b.unshift("fc-day-number"),'<td class="'+b.join(" ")+'" data-date="'+a.format()+'">'+a.date()+"</td>"):"<td/>"},computeEventTimeFormat:function(){return this.view.opt("extraSmallTimeFormat")},computeDisplayEventEnd:function(){return 1==this.colCnt},rangeUpdated:function(){this.updateDayTable()},spanToSegs:function(a){var b,c,d=this.sliceRangeByRow(a);for(b=0;b<d.length;b++)c=d[b],this.isRTL?(c.leftCol=this.daysPerRow-1-c.lastRowDayIndex,c.rightCol=this.daysPerRow-1-c.firstRowDayIndex):(c.leftCol=c.firstRowDayIndex,c.rightCol=c.lastRowDayIndex);return d},prepareHits:function(){this.colCoordCache.build(),this.rowCoordCache.build(),this.rowCoordCache.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},releaseHits:function(){this.colCoordCache.clear(),this.rowCoordCache.clear()},queryHit:function(a,b){var c=this.colCoordCache.getHorizontalIndex(a),d=this.rowCoordCache.getVerticalIndex(b);return null!=d&&null!=c?this.getCellHit(d,c):void 0},getHitSpan:function(a){return this.getCellRange(a.row,a.col)},getHitEl:function(a){return this.getCellEl(a.row,a.col)},getCellHit:function(a,b){return{row:a,col:b,component:this,left:this.colCoordCache.getLeftOffset(b),right:this.colCoordCache.getRightOffset(b),top:this.rowCoordCache.getTopOffset(a),bottom:this.rowCoordCache.getBottomOffset(a)}},getCellEl:function(a,b){return this.cellEls.eq(a*this.colCnt+b)},renderDrag:function(a,b){return this.renderHighlight(this.eventToSpan(a)),b&&!b.el.closest(this.el).length?this.renderEventLocationHelper(a,b):void 0},unrenderDrag:function(){this.unrenderHighlight(),this.unrenderHelper()},renderEventResize:function(a,b){return this.renderHighlight(this.eventToSpan(a)),this.renderEventLocationHelper(a,b)},unrenderEventResize:function(){this.unrenderHighlight(),this.unrenderHelper()},renderHelper:function(b,c){var d,e=[],f=this.eventToSegs(b);return f=this.renderFgSegEls(f),d=this.renderSegRows(f),this.rowEls.each(function(b,f){var g,h=a(f),i=a('<div class="fc-helper-skeleton"><table/></div>');g=c&&c.row===b?c.el.position().top:h.find(".fc-content-skeleton tbody").position().top,i.css("top",g).find("table").append(d[b].tbodyEl),h.append(i),e.push(i[0])}),this.helperEls=a(e)},unrenderHelper:function(){this.helperEls&&(this.helperEls.remove(),this.helperEls=null)},fillSegTag:"td",renderFill:function(b,c,d){var e,f,g,h=[];for(c=this.renderFillSegEls(b,c),e=0;e<c.length;e++)f=c[e],g=this.renderFillRow(b,f,d),this.rowEls.eq(f.row).append(g),h.push(g[0]);return this.elsByFill[b]=a(h),c},renderFillRow:function(b,c,d){var e,f,g=this.colCnt,h=c.leftCol,i=c.rightCol+1;return d=d||b.toLowerCase(),e=a('<div class="fc-'+d+'-skeleton"><table><tr/></table></div>'),f=e.find("tr"),h>0&&f.append('<td colspan="'+h+'"/>'),f.append(c.el.attr("colspan",i-h)),g>i&&f.append('<td colspan="'+(g-i)+'"/>'),this.bookendCells(f),e}});vb.mixin({rowStructs:null,unrenderEvents:function(){this.removeSegPopover(),tb.prototype.unrenderEvents.apply(this,arguments)},getEventSegs:function(){return tb.prototype.getEventSegs.call(this).concat(this.popoverSegs||[])},renderBgSegs:function(b){var c=a.grep(b,function(a){return a.event.allDay});return tb.prototype.renderBgSegs.call(this,c)},renderFgSegs:function(b){var c;return b=this.renderFgSegEls(b),c=this.rowStructs=this.renderSegRows(b),this.rowEls.each(function(b,d){a(d).find(".fc-content-skeleton > table").append(c[b].tbodyEl)}),b},unrenderFgSegs:function(){for(var a,b=this.rowStructs||[];a=b.pop();)a.tbodyEl.remove();this.rowStructs=null},renderSegRows:function(a){var b,c,d=[];for(b=this.groupSegRows(a),c=0;c<b.length;c++)d.push(this.renderSegRow(c,b[c]));return d},fgSegHtml:function(a,b){var c,d,e=this.view,f=a.event,g=e.isEventDraggable(f),h=!b&&f.allDay&&a.isStart&&e.isEventResizableFromStart(f),i=!b&&f.allDay&&a.isEnd&&e.isEventResizableFromEnd(f),j=this.getSegClasses(a,g,h||i),k=ea(this.getSegSkinCss(a)),l="";return j.unshift("fc-day-grid-event","fc-h-event"),a.isStart&&(c=this.getEventTimeText(f),c&&(l='<span class="fc-time">'+ca(c)+"</span>")),d='<span class="fc-title">'+(ca(f.title||"")||"&nbsp;")+"</span>",'<a class="'+j.join(" ")+'"'+(f.url?' href="'+ca(f.url)+'"':"")+(k?' style="'+k+'"':"")+'><div class="fc-content">'+(this.isRTL?d+" "+l:l+" "+d)+"</div>"+(h?'<div class="fc-resizer fc-start-resizer" />':"")+(i?'<div class="fc-resizer fc-end-resizer" />':"")+"</a>"},renderSegRow:function(b,c){function d(b){for(;b>g;)k=(r[e-1]||[])[g],k?k.attr("rowspan",parseInt(k.attr("rowspan")||1,10)+1):(k=a("<td/>"),h.append(k)),q[e][g]=k,r[e][g]=k,g++}var e,f,g,h,i,j,k,l=this.colCnt,m=this.buildSegLevels(c),n=Math.max(1,m.length),o=a("<tbody/>"),p=[],q=[],r=[];for(e=0;n>e;e++){if(f=m[e],g=0,h=a("<tr/>"),p.push([]),q.push([]),r.push([]),f)for(i=0;i<f.length;i++){for(j=f[i],d(j.leftCol),k=a('<td class="fc-event-container"/>').append(j.el),j.leftCol!=j.rightCol?k.attr("colspan",j.rightCol-j.leftCol+1):r[e][g]=k;g<=j.rightCol;)q[e][g]=k,p[e][g]=j,g++;h.append(k)}d(l),this.bookendCells(h),o.append(h)}return{row:b,tbodyEl:o,cellMatrix:q,segMatrix:p,segLevels:m,segs:c}},buildSegLevels:function(a){var b,c,d,e=[];for(this.sortEventSegs(a),b=0;b<a.length;b++){for(c=a[b],d=0;d<e.length&&Ja(c,e[d]);d++);c.level=d,(e[d]||(e[d]=[])).push(c)}for(d=0;d<e.length;d++)e[d].sort(Ka);return e},groupSegRows:function(a){var b,c=[];for(b=0;b<this.rowCnt;b++)c.push([]);for(b=0;b<a.length;b++)c[a[b].row].push(a[b]);return c}}),vb.mixin({segPopover:null,popoverSegs:null,removeSegPopover:function(){this.segPopover&&this.segPopover.hide()},limitRows:function(a){var b,c,d=this.rowStructs||[];for(b=0;b<d.length;b++)this.unlimitRow(b),c=a?"number"==typeof a?a:this.computeRowLevelLimit(b):!1,c!==!1&&this.limitRow(b,c)},computeRowLevelLimit:function(b){function c(b,c){f=Math.max(f,a(c).outerHeight())}var d,e,f,g=this.rowEls.eq(b),h=g.height(),i=this.rowStructs[b].tbodyEl.children();for(d=0;d<i.length;d++)if(e=i.eq(d).removeClass("fc-limited"),f=0,e.find("> td > :first-child").each(c),e.position().top+f>h)return d;return!1},limitRow:function(b,c){function d(d){for(;d>w;)j=t.getCellSegs(b,w,c),j.length&&(m=f[c-1][w],s=t.renderMoreLink(b,w,j),r=a("<div/>").append(s),m.append(r),v.push(r[0])),w++}var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=this,u=this.rowStructs[b],v=[],w=0;if(c&&c<u.segLevels.length){for(e=u.segLevels[c-1],f=u.cellMatrix,g=u.tbodyEl.children().slice(c).addClass("fc-limited").get(),h=0;h<e.length;h++){for(i=e[h],d(i.leftCol),l=[],k=0;w<=i.rightCol;)j=this.getCellSegs(b,w,c),l.push(j),k+=j.length,w++;if(k){for(m=f[c-1][i.leftCol],n=m.attr("rowspan")||1,o=[],p=0;p<l.length;p++)q=a('<td class="fc-more-cell"/>').attr("rowspan",n),j=l[p],s=this.renderMoreLink(b,i.leftCol+p,[i].concat(j)),r=a("<div/>").append(s),q.append(r),o.push(q[0]),v.push(q[0]);m.addClass("fc-limited").after(a(o)),g.push(m[0])}}d(this.colCnt),u.moreEls=a(v),u.limitedEls=a(g)}},unlimitRow:function(a){var b=this.rowStructs[a];b.moreEls&&(b.moreEls.remove(),b.moreEls=null),b.limitedEls&&(b.limitedEls.removeClass("fc-limited"),b.limitedEls=null)},renderMoreLink:function(b,c,d){var e=this,f=this.view;return a('<a class="fc-more"/>').text(this.getMoreLinkText(d.length)).on("click",function(g){var h=f.opt("eventLimitClick"),i=e.getCellDate(b,c),j=a(this),k=e.getCellEl(b,c),l=e.getCellSegs(b,c),m=e.resliceDaySegs(l,i),n=e.resliceDaySegs(d,i);"function"==typeof h&&(h=f.trigger("eventLimitClick",null,{date:i,dayEl:k,moreEl:j,segs:m,hiddenSegs:n},g)),"popover"===h?e.showSegPopover(b,c,j,m):"string"==typeof h&&f.calendar.zoomTo(i,h)})},showSegPopover:function(a,b,c,d){var e,f,g=this,h=this.view,i=c.parent();e=1==this.rowCnt?h.el:this.rowEls.eq(a),f={className:"fc-more-popover",content:this.renderSegPopoverContent(a,b,d),parentEl:this.el,top:e.offset().top,autoHide:!0,viewportConstrain:h.opt("popoverViewportConstrain"),hide:function(){g.segPopover.removeElement(),g.segPopover=null,g.popoverSegs=null}},this.isRTL?f.right=i.offset().left+i.outerWidth()+1:f.left=i.offset().left-1,this.segPopover=new ob(f),this.segPopover.show()},renderSegPopoverContent:function(b,c,d){var e,f=this.view,g=f.opt("theme"),h=this.getCellDate(b,c).format(f.opt("dayPopoverFormat")),i=a('<div class="fc-header '+f.widgetHeaderClass+'"><span class="fc-close '+(g?"ui-icon ui-icon-closethick":"fc-icon fc-icon-x")+'"></span><span class="fc-title">'+ca(h)+'</span><div class="fc-clear"/></div><div class="fc-body '+f.widgetContentClass+'"><div class="fc-event-container"></div></div>'),j=i.find(".fc-event-container");for(d=this.renderFgSegEls(d,!0),this.popoverSegs=d,e=0;e<d.length;e++)this.prepareHits(),d[e].hit=this.getCellHit(b,c),this.releaseHits(),j.append(d[e].el);return i},resliceDaySegs:function(b,c){var d=a.map(b,function(a){return a.event}),e=c.clone(),f=e.clone().add(1,"days"),g={start:e,end:f};return b=this.eventsToSegs(d,function(a){var b=K(a,g);return b?[b]:[]}),this.sortEventSegs(b),b},getMoreLinkText:function(a){var b=this.view.opt("eventLimitText");return"function"==typeof b?b(a):"+"+a+" "+b},getCellSegs:function(a,b,c){for(var d,e=this.rowStructs[a].segMatrix,f=c||0,g=[];f<e.length;)d=e[f][b],d&&g.push(d),f++;return g}});var wb=Wa.TimeGrid=tb.extend(ub,{slotDuration:null,snapDuration:null,snapsPerSlot:null,minTime:null,maxTime:null,labelFormat:null,labelInterval:null,colEls:null,slatContainerEl:null,slatEls:null,nowIndicatorEls:null,colCoordCache:null,slatCoordCache:null,constructor:function(){tb.apply(this,arguments),this.processOptions()},renderDates:function(){this.el.html(this.renderHtml()),this.colEls=this.el.find(".fc-day"),this.slatContainerEl=this.el.find(".fc-slats"),this.slatEls=this.slatContainerEl.find("tr"),this.colCoordCache=new pb({els:this.colEls,isHorizontal:!0}),this.slatCoordCache=new pb({els:this.slatEls,isVertical:!0}),this.renderContentSkeleton()},renderHtml:function(){return'<div class="fc-bg"><table>'+this.renderBgTrHtml(0)+'</table></div><div class="fc-slats"><table>'+this.renderSlatRowHtml()+"</table></div>"},renderSlatRowHtml:function(){for(var a,c,d,e=this.view,f=this.isRTL,g="",h=b.duration(+this.minTime);h<this.maxTime;)a=this.start.clone().time(h),c=ha(R(h,this.labelInterval)),d='<td class="fc-axis fc-time '+e.widgetContentClass+'" '+e.axisStyleAttr()+">"+(c?"<span>"+ca(a.format(this.labelFormat))+"</span>":"")+"</td>",g+='<tr data-time="'+a.format("HH:mm:ss")+'"'+(c?"":' class="fc-minor"')+">"+(f?"":d)+'<td class="'+e.widgetContentClass+'"/>'+(f?d:"")+"</tr>",h.add(this.slotDuration);return g},processOptions:function(){var c,d=this.view,e=d.opt("slotDuration"),f=d.opt("snapDuration");e=b.duration(e),f=f?b.duration(f):e,this.slotDuration=e,this.snapDuration=f,this.snapsPerSlot=e/f,this.minResizeDuration=f,this.minTime=b.duration(d.opt("minTime")),this.maxTime=b.duration(d.opt("maxTime")),c=d.opt("slotLabelFormat"),a.isArray(c)&&(c=c[c.length-1]),this.labelFormat=c||d.opt("axisFormat")||d.opt("smallTimeFormat"),c=d.opt("slotLabelInterval"),this.labelInterval=c?b.duration(c):this.computeLabelInterval(e)},computeLabelInterval:function(a){var c,d,e;for(c=Nb.length-1;c>=0;c--)if(d=b.duration(Nb[c]),e=R(d,a),ha(e)&&e>1)return d;return b.duration(a)},computeEventTimeFormat:function(){return this.view.opt("noMeridiemTimeFormat")},computeDisplayEventEnd:function(){return!0},prepareHits:function(){this.colCoordCache.build(),this.slatCoordCache.build()},releaseHits:function(){this.colCoordCache.clear()},queryHit:function(a,b){var c=this.snapsPerSlot,d=this.colCoordCache,e=this.slatCoordCache,f=d.getHorizontalIndex(a),g=e.getVerticalIndex(b);if(null!=f&&null!=g){var h=e.getTopOffset(g),i=e.getHeight(g),j=(b-h)/i,k=Math.floor(j*c),l=g*c+k,m=h+k/c*i,n=h+(k+1)/c*i;return{col:f,snap:l,component:this,left:d.getLeftOffset(f),right:d.getRightOffset(f),top:m,bottom:n}}},getHitSpan:function(a){var b,c=this.getCellDate(0,a.col),d=this.computeSnapTime(a.snap);return c.time(d),b=c.clone().add(this.snapDuration),{start:c,end:b}},getHitEl:function(a){return this.colEls.eq(a.col)},rangeUpdated:function(){this.updateDayTable()},computeSnapTime:function(a){return b.duration(this.minTime+this.snapDuration*a)},spanToSegs:function(a){var b,c=this.sliceRangeByTimes(a);for(b=0;b<c.length;b++)this.isRTL?c[b].col=this.daysPerRow-1-c[b].dayIndex:c[b].col=c[b].dayIndex;return c},sliceRangeByTimes:function(a){var b,c,d,e,f=[];for(c=0;c<this.daysPerRow;c++)d=this.dayDates[c].clone(),e={start:d.clone().time(this.minTime),end:d.clone().time(this.maxTime)},b=K(a,e),b&&(b.dayIndex=c,f.push(b));return f},updateSize:function(a){this.slatCoordCache.build(),a&&this.updateSegVerticals([].concat(this.fgSegs||[],this.bgSegs||[],this.businessSegs||[]))},getTotalSlatHeight:function(){return this.slatContainerEl.outerHeight()},computeDateTop:function(a,c){return this.computeTimeTop(b.duration(a-c.clone().stripTime()))},computeTimeTop:function(a){var b,c,d=this.slatEls.length,e=(a-this.minTime)/this.slotDuration;return e=Math.max(0,e),e=Math.min(d,e),b=Math.floor(e),b=Math.min(b,d-1),c=e-b,this.slatCoordCache.getTopPosition(b)+this.slatCoordCache.getHeight(b)*c},renderDrag:function(a,b){return b?this.renderEventLocationHelper(a,b):void this.renderHighlight(this.eventToSpan(a))},unrenderDrag:function(){this.unrenderHelper(),this.unrenderHighlight()},renderEventResize:function(a,b){return this.renderEventLocationHelper(a,b)},unrenderEventResize:function(){this.unrenderHelper()},renderHelper:function(a,b){return this.renderHelperSegs(this.eventToSegs(a),b)},unrenderHelper:function(){this.unrenderHelperSegs()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(),b=this.eventsToSegs(a);this.renderBusinessSegs(b)},unrenderBusinessHours:function(){this.unrenderBusinessSegs()},getNowIndicatorUnit:function(){return"minute"},renderNowIndicator:function(b){var c,d=this.spanToSegs({start:b,end:b}),e=this.computeDateTop(b,b),f=[];for(c=0;c<d.length;c++)f.push(a('<div class="fc-now-indicator fc-now-indicator-line"></div>').css("top",e).appendTo(this.colContainerEls.eq(d[c].col))[0]);d.length>0&&f.push(a('<div class="fc-now-indicator fc-now-indicator-arrow"></div>').css("top",e).appendTo(this.el.find(".fc-content-skeleton"))[0]),this.nowIndicatorEls=a(f)},unrenderNowIndicator:function(){this.nowIndicatorEls&&(this.nowIndicatorEls.remove(),this.nowIndicatorEls=null)},renderSelection:function(a){this.view.opt("selectHelper")?this.renderEventLocationHelper(a):this.renderHighlight(a)},unrenderSelection:function(){this.unrenderHelper(),this.unrenderHighlight()},renderHighlight:function(a){this.renderHighlightSegs(this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderHighlightSegs()}});wb.mixin({colContainerEls:null,fgContainerEls:null,bgContainerEls:null,helperContainerEls:null,highlightContainerEls:null,businessContainerEls:null,fgSegs:null,bgSegs:null,helperSegs:null,highlightSegs:null,businessSegs:null,renderContentSkeleton:function(){var b,c,d="";for(b=0;b<this.colCnt;b++)d+='<td><div class="fc-content-col"><div class="fc-event-container fc-helper-container"></div><div class="fc-event-container"></div><div class="fc-highlight-container"></div><div class="fc-bgevent-container"></div><div class="fc-business-container"></div></div></td>';c=a('<div class="fc-content-skeleton"><table><tr>'+d+"</tr></table></div>"),this.colContainerEls=c.find(".fc-content-col"),this.helperContainerEls=c.find(".fc-helper-container"),this.fgContainerEls=c.find(".fc-event-container:not(.fc-helper-container)"),this.bgContainerEls=c.find(".fc-bgevent-container"),this.highlightContainerEls=c.find(".fc-highlight-container"),this.businessContainerEls=c.find(".fc-business-container"),this.bookendCells(c.find("tr")),this.el.append(c)},renderFgSegs:function(a){return a=this.renderFgSegsIntoContainers(a,this.fgContainerEls),this.fgSegs=a,a},unrenderFgSegs:function(){this.unrenderNamedSegs("fgSegs")},renderHelperSegs:function(b,c){var d,e,f,g=[];for(b=this.renderFgSegsIntoContainers(b,this.helperContainerEls),d=0;d<b.length;d++)e=b[d],c&&c.col===e.col&&(f=c.el,e.el.css({left:f.css("left"),right:f.css("right"),"margin-left":f.css("margin-left"),"margin-right":f.css("margin-right")})),g.push(e.el[0]);return this.helperSegs=b,a(g)},unrenderHelperSegs:function(){this.unrenderNamedSegs("helperSegs")},renderBgSegs:function(a){return a=this.renderFillSegEls("bgEvent",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.bgContainerEls),this.bgSegs=a,a},unrenderBgSegs:function(){this.unrenderNamedSegs("bgSegs")},renderHighlightSegs:function(a){a=this.renderFillSegEls("highlight",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.highlightContainerEls),this.highlightSegs=a},unrenderHighlightSegs:function(){this.unrenderNamedSegs("highlightSegs")},renderBusinessSegs:function(a){a=this.renderFillSegEls("businessHours",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.businessContainerEls),this.businessSegs=a},unrenderBusinessSegs:function(){this.unrenderNamedSegs("businessSegs")},groupSegsByCol:function(a){var b,c=[];for(b=0;b<this.colCnt;b++)c.push([]);for(b=0;b<a.length;b++)c[a[b].col].push(a[b]);return c},attachSegsByCol:function(a,b){var c,d,e;for(c=0;c<this.colCnt;c++)for(d=a[c],e=0;e<d.length;e++)b.eq(c).append(d[e].el)},unrenderNamedSegs:function(a){var b,c=this[a];if(c){for(b=0;b<c.length;b++)c[b].el.remove();this[a]=null}},renderFgSegsIntoContainers:function(a,b){var c,d;for(a=this.renderFgSegEls(a),c=this.groupSegsByCol(a),d=0;d<this.colCnt;d++)this.updateFgSegCoords(c[d]);return this.attachSegsByCol(c,b),a},fgSegHtml:function(a,b){var c,d,e,f=this.view,g=a.event,h=f.isEventDraggable(g),i=!b&&a.isStart&&f.isEventResizableFromStart(g),j=!b&&a.isEnd&&f.isEventResizableFromEnd(g),k=this.getSegClasses(a,h,i||j),l=ea(this.getSegSkinCss(a));return k.unshift("fc-time-grid-event","fc-v-event"),f.isMultiDayEvent(g)?(a.isStart||a.isEnd)&&(c=this.getEventTimeText(a),d=this.getEventTimeText(a,"LT"),e=this.getEventTimeText(a,null,!1)):(c=this.getEventTimeText(g),d=this.getEventTimeText(g,"LT"),e=this.getEventTimeText(g,null,!1)),'<a class="'+k.join(" ")+'"'+(g.url?' href="'+ca(g.url)+'"':"")+(l?' style="'+l+'"':"")+'><div class="fc-content">'+(c?'<div class="fc-time" data-start="'+ca(e)+'" data-full="'+ca(d)+'"><span>'+ca(c)+"</span></div>":"")+(g.title?'<div class="fc-title">'+ca(g.title)+"</div>":"")+'</div><div class="fc-bg"/>'+(j?'<div class="fc-resizer fc-end-resizer" />':"")+"</a>"},updateSegVerticals:function(a){this.computeSegVerticals(a),this.assignSegVerticals(a)},computeSegVerticals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.top=this.computeDateTop(c.start,c.start),c.bottom=this.computeDateTop(c.end,c.start)},assignSegVerticals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.el.css(this.generateSegVerticalCss(c))},generateSegVerticalCss:function(a){return{top:a.top,bottom:-a.bottom}},updateFgSegCoords:function(a){this.computeSegVerticals(a),this.computeFgSegHorizontals(a),this.assignSegVerticals(a),this.assignFgSegHorizontals(a)},computeFgSegHorizontals:function(a){var b,c,d;if(this.sortEventSegs(a),b=La(a),Ma(b),c=b[0]){for(d=0;d<c.length;d++)Na(c[d]);for(d=0;d<c.length;d++)this.computeFgSegForwardBack(c[d],0,0)}},computeFgSegForwardBack:function(a,b,c){var d,e=a.forwardSegs;if(void 0===a.forwardCoord)for(e.length?(this.sortForwardSegs(e),this.computeFgSegForwardBack(e[0],b+1,c),a.forwardCoord=e[0].backwardCoord):a.forwardCoord=1,a.backwardCoord=a.forwardCoord-(a.forwardCoord-c)/(b+1),d=0;d<e.length;d++)this.computeFgSegForwardBack(e[d],0,a.forwardCoord)},sortForwardSegs:function(a){a.sort(ia(this,"compareForwardSegs"))},compareForwardSegs:function(a,b){return b.forwardPressure-a.forwardPressure||(a.backwardCoord||0)-(b.backwardCoord||0)||this.compareEventSegs(a,b)},assignFgSegHorizontals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.el.css(this.generateFgSegHorizontalCss(c)),c.bottom-c.top<30&&c.el.addClass("fc-short")},generateFgSegHorizontalCss:function(a){var b,c,d=this.view.opt("slotEventOverlap"),e=a.backwardCoord,f=a.forwardCoord,g=this.generateSegVerticalCss(a);return d&&(f=Math.min(1,e+2*(f-e))),this.isRTL?(b=1-f,c=e):(b=e,c=1-f),g.zIndex=a.level+1,g.left=100*b+"%",g.right=100*c+"%",d&&a.forwardPressure&&(g[this.isRTL?"marginLeft":"marginRight"]=20),g}});var xb=Wa.View=ya.extend(lb,mb,{type:null,name:null,title:null,calendar:null,options:null,el:null,displaying:null,isSkeletonRendered:!1,isEventsRendered:!1,start:null,end:null,intervalStart:null,intervalEnd:null,intervalDuration:null,intervalUnit:null,isRTL:!1,isSelected:!1,selectedEvent:null,eventOrderSpecs:null,widgetHeaderClass:null,widgetContentClass:null,highlightStateClass:null,nextDayThreshold:null,isHiddenDayHash:null,isNowIndicatorRendered:null,initialNowDate:null,initialNowQueriedMs:null,nowIndicatorTimeoutID:null,nowIndicatorIntervalID:null,constructor:function(a,c,d,e){this.calendar=a,this.type=this.name=c,this.options=d,this.intervalDuration=e||b.duration(1,"day"),this.nextDayThreshold=b.duration(this.opt("nextDayThreshold")),this.initThemingProps(),this.initHiddenDays(),this.isRTL=this.opt("isRTL"),this.eventOrderSpecs=G(this.opt("eventOrder")),this.initialize()},initialize:function(){},opt:function(a){return this.options[a]},trigger:function(a,b){var c=this.calendar;return c.trigger.apply(c,[a,b||this].concat(Array.prototype.slice.call(arguments,2),[this]))},setDate:function(a){this.setRange(this.computeRange(a))},setRange:function(b){a.extend(this,b),this.updateTitle()},computeRange:function(a){var b,c,d=O(this.intervalDuration),e=a.clone().startOf(d),f=e.clone().add(this.intervalDuration);return/year|month|week|day/.test(d)?(e.stripTime(),f.stripTime()):(e.hasTime()||(e=this.calendar.time(0)),f.hasTime()||(f=this.calendar.time(0))),b=e.clone(),b=this.skipHiddenDays(b),c=f.clone(),c=this.skipHiddenDays(c,-1,!0),{intervalUnit:d,intervalStart:e,intervalEnd:f,start:b,end:c}},computePrevDate:function(a){return this.massageCurrentDate(a.clone().startOf(this.intervalUnit).subtract(this.intervalDuration),-1)},computeNextDate:function(a){return this.massageCurrentDate(a.clone().startOf(this.intervalUnit).add(this.intervalDuration))},massageCurrentDate:function(a,b){return this.intervalDuration.as("days")<=1&&this.isHiddenDay(a)&&(a=this.skipHiddenDays(a,b),a.startOf("day")),a},updateTitle:function(){this.title=this.computeTitle()},computeTitle:function(){return this.formatRange({start:this.calendar.applyTimezone(this.intervalStart),end:this.calendar.applyTimezone(this.intervalEnd)},this.opt("titleFormat")||this.computeTitleFormat(),this.opt("titleRangeSeparator"))},computeTitleFormat:function(){return"year"==this.intervalUnit?"YYYY":"month"==this.intervalUnit?this.opt("monthYearFormat"):this.intervalDuration.as("days")>1?"ll":"LL"},formatRange:function(a,b,c){var d=a.end;return d.hasTime()||(d=d.clone().subtract(1)),ta(a.start,d,b,c,this.opt("isRTL"))},setElement:function(a){this.el=a,this.bindGlobalHandlers()},removeElement:function(){this.clear(),this.isSkeletonRendered&&(this.unrenderSkeleton(),this.isSkeletonRendered=!1),this.unbindGlobalHandlers(),this.el.remove()},display:function(a){var b=this,c=null;return this.displaying&&(c=this.queryScroll()),this.calendar.freezeContentHeight(),ka(this.clear(),function(){return b.displaying=ka(b.displayView(a),function(){b.forceScroll(b.computeInitialScroll(c)),b.calendar.unfreezeContentHeight(),b.triggerRender()})})},clear:function(){var b=this,c=this.displaying;return c?ka(c,function(){return b.displaying=null,b.clearEvents(),b.clearView()}):a.when()},displayView:function(a){this.isSkeletonRendered||(this.renderSkeleton(),this.isSkeletonRendered=!0),a&&this.setDate(a),this.render&&this.render(),this.renderDates(),this.updateSize(),this.renderBusinessHours(),this.startNowIndicator()},clearView:function(){this.unselect(),this.stopNowIndicator(),this.triggerUnrender(),this.unrenderBusinessHours(),this.unrenderDates(),this.destroy&&this.destroy()},renderSkeleton:function(){},unrenderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},triggerRender:function(){this.trigger("viewRender",this,this,this.el)},triggerUnrender:function(){this.trigger("viewDestroy",this,this,this.el)},bindGlobalHandlers:function(){this.listenTo(a(document),"mousedown",this.handleDocumentMousedown),this.listenTo(a(document),"touchstart",this.processUnselect)},unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},initThemingProps:function(){var a=this.opt("theme")?"ui":"fc";this.widgetHeaderClass=a+"-widget-header",this.widgetContentClass=a+"-widget-content",this.highlightStateClass=a+"-state-highlight"},renderBusinessHours:function(){},unrenderBusinessHours:function(){},startNowIndicator:function(){var a,c,d,e=this;this.opt("nowIndicator")&&(a=this.getNowIndicatorUnit(),a&&(c=ia(this,"updateNowIndicator"),this.initialNowDate=this.calendar.getNow(),this.initialNowQueriedMs=+new Date,this.renderNowIndicator(this.initialNowDate),this.isNowIndicatorRendered=!0,d=this.initialNowDate.clone().startOf(a).add(1,a)-this.initialNowDate,this.nowIndicatorTimeoutID=setTimeout(function(){e.nowIndicatorTimeoutID=null,c(),d=+b.duration(1,a),d=Math.max(100,d),e.nowIndicatorIntervalID=setInterval(c,d)},d)))},updateNowIndicator:function(){this.isNowIndicatorRendered&&(this.unrenderNowIndicator(),this.renderNowIndicator(this.initialNowDate.clone().add(new Date-this.initialNowQueriedMs)))},stopNowIndicator:function(){this.isNowIndicatorRendered&&(this.nowIndicatorTimeoutID&&(clearTimeout(this.nowIndicatorTimeoutID),this.nowIndicatorTimeoutID=null),this.nowIndicatorIntervalID&&(clearTimeout(this.nowIndicatorIntervalID),this.nowIndicatorIntervalID=null),this.unrenderNowIndicator(),this.isNowIndicatorRendered=!1)},getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},updateSize:function(a){var b;a&&(b=this.queryScroll()),this.updateHeight(a),this.updateWidth(a),this.updateNowIndicator(),a&&this.setScroll(b)},updateWidth:function(a){},updateHeight:function(a){var b=this.calendar;this.setHeight(b.getSuggestedViewHeight(),b.isHeightAuto())},setHeight:function(a,b){},computeInitialScroll:function(a){return 0},queryScroll:function(){},setScroll:function(a){},forceScroll:function(a){var b=this;this.setScroll(a),setTimeout(function(){b.setScroll(a)},0)},displayEvents:function(a){var b=this.queryScroll();this.clearEvents(),this.renderEvents(a),this.isEventsRendered=!0,this.setScroll(b),this.triggerEventRender()},clearEvents:function(){var a;this.isEventsRendered&&(a=this.queryScroll(),this.triggerEventUnrender(),this.destroyEvents&&this.destroyEvents(),this.unrenderEvents(),this.setScroll(a),this.isEventsRendered=!1)},renderEvents:function(a){},unrenderEvents:function(){},triggerEventRender:function(){this.renderedEventSegEach(function(a){this.trigger("eventAfterRender",a.event,a.event,a.el)}),this.trigger("eventAfterAllRender")},triggerEventUnrender:function(){this.renderedEventSegEach(function(a){this.trigger("eventDestroy",a.event,a.event,a.el)})},resolveEventEl:function(b,c){var d=this.trigger("eventRender",b,b,c);return d===!1?c=null:d&&d!==!0&&(c=a(d)),c},showEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","")},a)},hideEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","hidden")},a)},renderedEventSegEach:function(a,b){var c,d=this.getEventSegs();for(c=0;c<d.length;c++)b&&d[c].event._id!==b._id||d[c].el&&a.call(this,d[c])},getEventSegs:function(){return[]},isEventDraggable:function(a){var b=a.source||{};return ba(a.startEditable,b.startEditable,this.opt("eventStartEditable"),a.editable,b.editable,this.opt("editable"))},reportEventDrop:function(a,b,c,d,e){var f=this.calendar,g=f.mutateEvent(a,b,c),h=function(){g.undo(),f.reportEventChange()};this.triggerEventDrop(a,g.dateDelta,h,d,e),f.reportEventChange()},triggerEventDrop:function(a,b,c,d,e){this.trigger("eventDrop",d[0],a,b,c,e,{})},reportExternalDrop:function(b,c,d,e,f){var g,h,i=b.eventProps;i&&(g=a.extend({},i,c),h=this.calendar.renderEvent(g,b.stick)[0]),this.triggerExternalDrop(h,c,d,e,f)},triggerExternalDrop:function(a,b,c,d,e){this.trigger("drop",c[0],b.start,d,e),a&&this.trigger("eventReceive",null,a)},renderDrag:function(a,b){},unrenderDrag:function(){},isEventResizableFromStart:function(a){return this.opt("eventResizableFromStart")&&this.isEventResizable(a)},isEventResizableFromEnd:function(a){return this.isEventResizable(a)},isEventResizable:function(a){var b=a.source||{};return ba(a.durationEditable,b.durationEditable,this.opt("eventDurationEditable"),a.editable,b.editable,this.opt("editable"))},reportEventResize:function(a,b,c,d,e){var f=this.calendar,g=f.mutateEvent(a,b,c),h=function(){g.undo(),
+f.reportEventChange()};this.triggerEventResize(a,g.durationDelta,h,d,e),f.reportEventChange()},triggerEventResize:function(a,b,c,d,e){this.trigger("eventResize",d[0],a,b,c,e,{})},select:function(a,b){this.unselect(b),this.renderSelection(a),this.reportSelection(a,b)},renderSelection:function(a){},reportSelection:function(a,b){this.isSelected=!0,this.triggerSelect(a,b)},triggerSelect:function(a,b){this.trigger("select",null,this.calendar.applyTimezone(a.start),this.calendar.applyTimezone(a.end),b)},unselect:function(a){this.isSelected&&(this.isSelected=!1,this.destroySelection&&this.destroySelection(),this.unrenderSelection(),this.trigger("unselect",null,a))},unrenderSelection:function(){},selectEvent:function(a){this.selectedEvent&&this.selectedEvent===a||(this.unselectEvent(),this.renderedEventSegEach(function(a){a.el.addClass("fc-selected")},a),this.selectedEvent=a)},unselectEvent:function(){this.selectedEvent&&(this.renderedEventSegEach(function(a){a.el.removeClass("fc-selected")},this.selectedEvent),this.selectedEvent=null)},isEventSelected:function(a){return this.selectedEvent&&this.selectedEvent._id===a._id},handleDocumentMousedown:function(a){u(a)&&this.processUnselect(a)},processUnselect:function(a){this.processRangeUnselect(a),this.processEventUnselect(a)},processRangeUnselect:function(b){var c;this.isSelected&&this.opt("unselectAuto")&&(c=this.opt("unselectCancel"),c&&a(b.target).closest(c).length||this.unselect(b))},processEventUnselect:function(b){this.selectedEvent&&(a(b.target).closest(".fc-selected").length||this.unselectEvent())},triggerDayClick:function(a,b,c){this.trigger("dayClick",b,this.calendar.applyTimezone(a.start),c)},initHiddenDays:function(){var b,c=this.opt("hiddenDays")||[],d=[],e=0;for(this.opt("weekends")===!1&&c.push(0,6),b=0;7>b;b++)(d[b]=-1!==a.inArray(b,c))||e++;if(!e)throw"invalid hiddenDays";this.isHiddenDayHash=d},isHiddenDay:function(a){return b.isMoment(a)&&(a=a.day()),this.isHiddenDayHash[a]},skipHiddenDays:function(a,b,c){var d=a.clone();for(b=b||1;this.isHiddenDayHash[(d.day()+(c?b:0)+7)%7];)d.add(b,"days");return d},computeDayRange:function(a){var b,c=a.start.clone().stripTime(),d=a.end,e=null;return d&&(e=d.clone().stripTime(),b=+d.time(),b&&b>=this.nextDayThreshold&&e.add(1,"days")),(!d||c>=e)&&(e=c.clone().add(1,"days")),{start:c,end:e}},isMultiDayEvent:function(a){var b=this.computeDayRange(a);return b.end.diff(b.start,"days")>1}}),yb=Wa.Scroller=ya.extend({el:null,scrollEl:null,overflowX:null,overflowY:null,constructor:function(a){a=a||{},this.overflowX=a.overflowX||a.overflow||"auto",this.overflowY=a.overflowY||a.overflow||"auto"},render:function(){this.el=this.renderEl(),this.applyOverflow()},renderEl:function(){return this.scrollEl=a('<div class="fc-scroller"></div>')},clear:function(){this.setHeight("auto"),this.applyOverflow()},destroy:function(){this.el.remove()},applyOverflow:function(){this.scrollEl.css({"overflow-x":this.overflowX,"overflow-y":this.overflowY})},lockOverflow:function(a){var b=this.overflowX,c=this.overflowY;a=a||this.getScrollbarWidths(),"auto"===b&&(b=a.top||a.bottom||this.scrollEl[0].scrollWidth-1>this.scrollEl[0].clientWidth?"scroll":"hidden"),"auto"===c&&(c=a.left||a.right||this.scrollEl[0].scrollHeight-1>this.scrollEl[0].clientHeight?"scroll":"hidden"),this.scrollEl.css({"overflow-x":b,"overflow-y":c})},setHeight:function(a){this.scrollEl.height(a)},getScrollTop:function(){return this.scrollEl.scrollTop()},setScrollTop:function(a){this.scrollEl.scrollTop(a)},getClientWidth:function(){return this.scrollEl[0].clientWidth},getClientHeight:function(){return this.scrollEl[0].clientHeight},getScrollbarWidths:function(){return q(this.scrollEl)}}),zb=Wa.Calendar=ya.extend({dirDefaults:null,langDefaults:null,overrides:null,options:null,viewSpecCache:null,view:null,header:null,loadingLevel:0,constructor:Qa,initialize:function(){},initOptions:function(a){var b,e,f,g;a=d(a),b=a.lang,e=Ab[b],e||(b=zb.defaults.lang,e=Ab[b]||{}),f=ba(a.isRTL,e.isRTL,zb.defaults.isRTL),g=f?zb.rtlDefaults:{},this.dirDefaults=g,this.langDefaults=e,this.overrides=a,this.options=c([zb.defaults,g,e,a]),Ra(this.options),this.viewSpecCache={}},getViewSpec:function(a){var b=this.viewSpecCache;return b[a]||(b[a]=this.buildViewSpec(a))},getUnitViewSpec:function(b){var c,d,e;if(-1!=a.inArray(b,_a))for(c=this.header.getViewsWithButtons(),a.each(Wa.views,function(a){c.push(a)}),d=0;d<c.length;d++)if(e=this.getViewSpec(c[d]),e&&e.singleUnit==b)return e},buildViewSpec:function(a){for(var d,e,f,g,h=this.overrides.views||{},i=[],j=[],k=[],l=a;l;)d=Xa[l],e=h[l],l=null,"function"==typeof d&&(d={"class":d}),d&&(i.unshift(d),j.unshift(d.defaults||{}),f=f||d.duration,l=l||d.type),e&&(k.unshift(e),f=f||e.duration,l=l||e.type);return d=W(i),d.type=a,d["class"]?(f&&(f=b.duration(f),f.valueOf()&&(d.duration=f,g=O(f),1===f.as(g)&&(d.singleUnit=g,k.unshift(h[g]||{})))),d.defaults=c(j),d.overrides=c(k),this.buildViewSpecOptions(d),this.buildViewSpecButtonText(d,a),d):!1},buildViewSpecOptions:function(a){a.options=c([zb.defaults,a.defaults,this.dirDefaults,this.langDefaults,this.overrides,a.overrides]),Ra(a.options)},buildViewSpecButtonText:function(a,b){function c(c){var d=c.buttonText||{};return d[b]||(a.singleUnit?d[a.singleUnit]:null)}a.buttonTextOverride=c(this.overrides)||a.overrides.buttonText,a.buttonTextDefault=c(this.langDefaults)||c(this.dirDefaults)||a.defaults.buttonText||c(zb.defaults)||(a.duration?this.humanizeDuration(a.duration):null)||b},instantiateView:function(a){var b=this.getViewSpec(a);return new b["class"](this,a,b.options,b.duration)},isValidViewType:function(a){return Boolean(this.getViewSpec(a))},pushLoading:function(){this.loadingLevel++||this.trigger("loading",null,!0,this.view)},popLoading:function(){--this.loadingLevel||this.trigger("loading",null,!1,this.view)},buildSelectSpan:function(a,b){var c,d=this.moment(a).stripZone();return c=b?this.moment(b).stripZone():d.hasTime()?d.clone().add(this.defaultTimedEventDuration):d.clone().add(this.defaultAllDayEventDuration),{start:d,end:c}}});zb.mixin(lb),zb.defaults={titleRangeSeparator:" – ",monthYearFormat:"MMMM YYYY",defaultTimedEventDuration:"02:00:00",defaultAllDayEventDuration:{days:1},forceEventDuration:!1,nextDayThreshold:"09:00:00",defaultView:"month",aspectRatio:1.35,header:{left:"title",center:"",right:"today prev,next"},weekends:!0,weekNumbers:!1,weekNumberTitle:"W",weekNumberCalculation:"local",scrollTime:"06:00:00",lazyFetching:!0,startParam:"start",endParam:"end",timezoneParam:"timezone",timezone:!1,isRTL:!1,buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day"},buttonIcons:{prev:"left-single-arrow",next:"right-single-arrow",prevYear:"left-double-arrow",nextYear:"right-double-arrow"},theme:!1,themeButtonIcons:{prev:"circle-triangle-w",next:"circle-triangle-e",prevYear:"seek-prev",nextYear:"seek-next"},dragOpacity:.75,dragRevertDuration:500,dragScroll:!0,unselectAuto:!0,dropAccept:"*",eventOrder:"title",eventLimit:!1,eventLimitText:"more",eventLimitClick:"popover",dayPopoverFormat:"LL",handleWindowResize:!0,windowResizeDelay:200,longPressDelay:1e3},zb.englishDefaults={dayPopoverFormat:"dddd, MMMM D"},zb.rtlDefaults={header:{left:"next,prev today",center:"",right:"title"},buttonIcons:{prev:"right-single-arrow",next:"left-single-arrow",prevYear:"right-double-arrow",nextYear:"left-double-arrow"},themeButtonIcons:{prev:"circle-triangle-e",next:"circle-triangle-w",nextYear:"seek-prev",prevYear:"seek-next"}};var Ab=Wa.langs={};Wa.datepickerLang=function(b,c,d){var e=Ab[b]||(Ab[b]={});e.isRTL=d.isRTL,e.weekNumberTitle=d.weekHeader,a.each(Bb,function(a,b){e[a]=b(d)}),a.datepicker&&(a.datepicker.regional[c]=a.datepicker.regional[b]=d,a.datepicker.regional.en=a.datepicker.regional[""],a.datepicker.setDefaults(d))},Wa.lang=function(b,d){var e,f;e=Ab[b]||(Ab[b]={}),d&&(e=Ab[b]=c([e,d])),f=Sa(b),a.each(Cb,function(a,b){null==e[a]&&(e[a]=b(f,e))}),zb.defaults.lang=b};var Bb={buttonText:function(a){return{prev:da(a.prevText),next:da(a.nextText),today:da(a.currentText)}},monthYearFormat:function(a){return a.showMonthAfterYear?"YYYY["+a.yearSuffix+"] MMMM":"MMMM YYYY["+a.yearSuffix+"]"}},Cb={dayOfMonthFormat:function(a,b){var c=a.longDateFormat("l");return c=c.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g,""),b.isRTL?c+=" ddd":c="ddd "+c,c},mediumTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"a")},smallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"a")},extraSmallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"t")},hourFormat:function(a){return a.longDateFormat("LT").replace(":mm","").replace(/(\Wmm)$/,"").replace(/\s*a$/i,"a")},noMeridiemTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"")}},Db={smallDayDateFormat:function(a){return a.isRTL?"D dd":"dd D"},weekFormat:function(a){return a.isRTL?"w[ "+a.weekNumberTitle+"]":"["+a.weekNumberTitle+" ]w"},smallWeekFormat:function(a){return a.isRTL?"w["+a.weekNumberTitle+"]":"["+a.weekNumberTitle+"]w"}};Wa.lang("en",zb.englishDefaults),Wa.sourceNormalizers=[],Wa.sourceFetchers=[];var Eb={dataType:"json",cache:!1},Fb=1;zb.prototype.normalizeEvent=function(a){},zb.prototype.getPeerEvents=function(a,b){var c,d,e=this.getEventCache(),f=[];for(c=0;c<e.length;c++)d=e[c],b&&b._id===d._id||f.push(d);return f};var Gb=Wa.BasicView=xb.extend({scroller:null,dayGridClass:vb,dayGrid:null,dayNumbersVisible:!1,weekNumbersVisible:!1,weekNumberWidth:null,headContainerEl:null,headRowEl:null,initialize:function(){this.dayGrid=this.instantiateDayGrid(),this.scroller=new yb({overflowX:"hidden",overflowY:"auto"})},instantiateDayGrid:function(){var a=this.dayGridClass.extend(Hb);return new a(this)},setRange:function(a){xb.prototype.setRange.call(this,a),this.dayGrid.breakOnWeeks=/year|month|week/.test(this.intervalUnit),this.dayGrid.setRange(a)},computeRange:function(a){var b=xb.prototype.computeRange.call(this,a);return/year|month/.test(b.intervalUnit)&&(b.start.startOf("week"),b.start=this.skipHiddenDays(b.start),b.end.weekday()&&(b.end.add(1,"week").startOf("week"),b.end=this.skipHiddenDays(b.end,-1,!0))),b},renderDates:function(){this.dayNumbersVisible=this.dayGrid.rowCnt>1,this.weekNumbersVisible=this.opt("weekNumbers"),this.dayGrid.numbersVisible=this.dayNumbersVisible||this.weekNumbersVisible,this.el.addClass("fc-basic-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-day-grid-container"),c=a('<div class="fc-day-grid" />').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.dayGrid.setElement(c),this.dayGrid.renderDates(this.hasRigidRows())},renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.dayGrid.renderHeadHtml()),this.headRowEl=this.headContainerEl.find(".fc-row")},unrenderDates:function(){this.dayGrid.unrenderDates(),this.dayGrid.removeElement(),this.scroller.destroy()},renderBusinessHours:function(){this.dayGrid.renderBusinessHours()},renderSkeletonHtml:function(){return'<table><thead class="fc-head"><tr><td class="fc-head-container '+this.widgetHeaderClass+'"></td></tr></thead><tbody class="fc-body"><tr><td class="'+this.widgetContentClass+'"></td></tr></tbody></table>'},weekNumberStyleAttr:function(){return null!==this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},hasRigidRows:function(){var a=this.opt("eventLimit");return a&&"number"!=typeof a},updateWidth:function(){this.weekNumbersVisible&&(this.weekNumberWidth=k(this.el.find(".fc-week-number")))},setHeight:function(a,b){var c,d,g=this.opt("eventLimit");this.scroller.clear(),f(this.headRowEl),this.dayGrid.removeSegPopover(),g&&"number"==typeof g&&this.dayGrid.limitRows(g),c=this.computeScrollerHeight(a),this.setGridHeight(c,b),g&&"number"!=typeof g&&this.dayGrid.limitRows(g),b||(this.scroller.setHeight(c),d=this.scroller.getScrollbarWidths(),(d.left||d.right)&&(e(this.headRowEl,d),c=this.computeScrollerHeight(a),this.scroller.setHeight(c)),this.scroller.lockOverflow(d))},computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},setGridHeight:function(a,b){b?j(this.dayGrid.rowEls):i(this.dayGrid.rowEls,a,!0)},queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},prepareHits:function(){this.dayGrid.prepareHits()},releaseHits:function(){this.dayGrid.releaseHits()},queryHit:function(a,b){return this.dayGrid.queryHit(a,b)},getHitSpan:function(a){return this.dayGrid.getHitSpan(a)},getHitEl:function(a){return this.dayGrid.getHitEl(a)},renderEvents:function(a){this.dayGrid.renderEvents(a),this.updateHeight()},getEventSegs:function(){return this.dayGrid.getEventSegs()},unrenderEvents:function(){this.dayGrid.unrenderEvents()},renderDrag:function(a,b){return this.dayGrid.renderDrag(a,b)},unrenderDrag:function(){this.dayGrid.unrenderDrag()},renderSelection:function(a){this.dayGrid.renderSelection(a)},unrenderSelection:function(){this.dayGrid.unrenderSelection()}}),Hb={renderHeadIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<th class="fc-week-number '+a.widgetHeaderClass+'" '+a.weekNumberStyleAttr()+"><span>"+ca(a.opt("weekNumberTitle"))+"</span></th>":""},renderNumberIntroHtml:function(a){var b=this.view;return b.weekNumbersVisible?'<td class="fc-week-number" '+b.weekNumberStyleAttr()+"><span>"+this.getCellDate(a,0).format("w")+"</span></td>":""},renderBgIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<td class="fc-week-number '+a.widgetContentClass+'" '+a.weekNumberStyleAttr()+"></td>":""},renderIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<td class="fc-week-number" '+a.weekNumberStyleAttr()+"></td>":""}},Ib=Wa.MonthView=Gb.extend({computeRange:function(a){var b,c=Gb.prototype.computeRange.call(this,a);return this.isFixedWeeks()&&(b=Math.ceil(c.end.diff(c.start,"weeks",!0)),c.end.add(6-b,"weeks")),c},setGridHeight:function(a,b){b=b||"variable"===this.opt("weekMode"),b&&(a*=this.rowCnt/6),i(this.dayGrid.rowEls,a,!b)},isFixedWeeks:function(){var a=this.opt("weekMode");return a?"fixed"===a:this.opt("fixedWeekCount")}});Xa.basic={"class":Gb},Xa.basicDay={type:"basic",duration:{days:1}},Xa.basicWeek={type:"basic",duration:{weeks:1}},Xa.month={"class":Ib,duration:{months:1},defaults:{fixedWeekCount:!0}};var Jb=Wa.AgendaView=xb.extend({scroller:null,timeGridClass:wb,timeGrid:null,dayGridClass:vb,dayGrid:null,axisWidth:null,headContainerEl:null,noScrollRowEls:null,bottomRuleEl:null,initialize:function(){this.timeGrid=this.instantiateTimeGrid(),this.opt("allDaySlot")&&(this.dayGrid=this.instantiateDayGrid()),this.scroller=new yb({overflowX:"hidden",overflowY:"auto"})},instantiateTimeGrid:function(){var a=this.timeGridClass.extend(Kb);return new a(this)},instantiateDayGrid:function(){var a=this.dayGridClass.extend(Lb);return new a(this)},setRange:function(a){xb.prototype.setRange.call(this,a),this.timeGrid.setRange(a),this.dayGrid&&this.dayGrid.setRange(a)},renderDates:function(){this.el.addClass("fc-agenda-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-time-grid-container"),c=a('<div class="fc-time-grid" />').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.timeGrid.setElement(c),this.timeGrid.renderDates(),this.bottomRuleEl=a('<hr class="fc-divider '+this.widgetHeaderClass+'"/>').appendTo(this.timeGrid.el),this.dayGrid&&(this.dayGrid.setElement(this.el.find(".fc-day-grid")),this.dayGrid.renderDates(),this.dayGrid.bottomCoordPadding=this.dayGrid.el.next("hr").outerHeight()),this.noScrollRowEls=this.el.find(".fc-row:not(.fc-scroller *)")},renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.timeGrid.renderHeadHtml())},unrenderDates:function(){this.timeGrid.unrenderDates(),this.timeGrid.removeElement(),this.dayGrid&&(this.dayGrid.unrenderDates(),this.dayGrid.removeElement()),this.scroller.destroy()},renderSkeletonHtml:function(){return'<table><thead class="fc-head"><tr><td class="fc-head-container '+this.widgetHeaderClass+'"></td></tr></thead><tbody class="fc-body"><tr><td class="'+this.widgetContentClass+'">'+(this.dayGrid?'<div class="fc-day-grid"/><hr class="fc-divider '+this.widgetHeaderClass+'"/>':"")+"</td></tr></tbody></table>"},axisStyleAttr:function(){return null!==this.axisWidth?'style="width:'+this.axisWidth+'px"':""},renderBusinessHours:function(){this.timeGrid.renderBusinessHours(),this.dayGrid&&this.dayGrid.renderBusinessHours()},unrenderBusinessHours:function(){this.timeGrid.unrenderBusinessHours(),this.dayGrid&&this.dayGrid.unrenderBusinessHours()},getNowIndicatorUnit:function(){return this.timeGrid.getNowIndicatorUnit()},renderNowIndicator:function(a){this.timeGrid.renderNowIndicator(a)},unrenderNowIndicator:function(){this.timeGrid.unrenderNowIndicator()},updateSize:function(a){this.timeGrid.updateSize(a),xb.prototype.updateSize.call(this,a)},updateWidth:function(){this.axisWidth=k(this.el.find(".fc-axis"))},setHeight:function(a,b){var c,d,g;this.bottomRuleEl.hide(),this.scroller.clear(),f(this.noScrollRowEls),this.dayGrid&&(this.dayGrid.removeSegPopover(),c=this.opt("eventLimit"),c&&"number"!=typeof c&&(c=Mb),c&&this.dayGrid.limitRows(c)),b||(d=this.computeScrollerHeight(a),this.scroller.setHeight(d),g=this.scroller.getScrollbarWidths(),(g.left||g.right)&&(e(this.noScrollRowEls,g),d=this.computeScrollerHeight(a),this.scroller.setHeight(d)),this.scroller.lockOverflow(g),this.timeGrid.getTotalSlatHeight()<d&&this.bottomRuleEl.show())},computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},computeInitialScroll:function(){var a=b.duration(this.opt("scrollTime")),c=this.timeGrid.computeTimeTop(a);return c=Math.ceil(c),c&&c++,c},queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},prepareHits:function(){this.timeGrid.prepareHits(),this.dayGrid&&this.dayGrid.prepareHits()},releaseHits:function(){this.timeGrid.releaseHits(),this.dayGrid&&this.dayGrid.releaseHits()},queryHit:function(a,b){var c=this.timeGrid.queryHit(a,b);return!c&&this.dayGrid&&(c=this.dayGrid.queryHit(a,b)),c},getHitSpan:function(a){return a.component.getHitSpan(a)},getHitEl:function(a){return a.component.getHitEl(a)},renderEvents:function(a){var b,c,d=[],e=[],f=[];for(c=0;c<a.length;c++)a[c].allDay?d.push(a[c]):e.push(a[c]);b=this.timeGrid.renderEvents(e),this.dayGrid&&(f=this.dayGrid.renderEvents(d)),this.updateHeight()},getEventSegs:function(){return this.timeGrid.getEventSegs().concat(this.dayGrid?this.dayGrid.getEventSegs():[])},unrenderEvents:function(){this.timeGrid.unrenderEvents(),this.dayGrid&&this.dayGrid.unrenderEvents()},renderDrag:function(a,b){return a.start.hasTime()?this.timeGrid.renderDrag(a,b):this.dayGrid?this.dayGrid.renderDrag(a,b):void 0},unrenderDrag:function(){this.timeGrid.unrenderDrag(),this.dayGrid&&this.dayGrid.unrenderDrag()},renderSelection:function(a){a.start.hasTime()||a.end.hasTime()?this.timeGrid.renderSelection(a):this.dayGrid&&this.dayGrid.renderSelection(a)},unrenderSelection:function(){this.timeGrid.unrenderSelection(),this.dayGrid&&this.dayGrid.unrenderSelection()}}),Kb={renderHeadIntroHtml:function(){var a,b=this.view;return b.opt("weekNumbers")?(a=this.start.format(b.opt("smallWeekFormat")),'<th class="fc-axis fc-week-number '+b.widgetHeaderClass+'" '+b.axisStyleAttr()+"><span>"+ca(a)+"</span></th>"):'<th class="fc-axis '+b.widgetHeaderClass+'" '+b.axisStyleAttr()+"></th>"},renderBgIntroHtml:function(){var a=this.view;return'<td class="fc-axis '+a.widgetContentClass+'" '+a.axisStyleAttr()+"></td>"},renderIntroHtml:function(){var a=this.view;return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"}},Lb={renderBgIntroHtml:function(){var a=this.view;return'<td class="fc-axis '+a.widgetContentClass+'" '+a.axisStyleAttr()+"><span>"+(a.opt("allDayHtml")||ca(a.opt("allDayText")))+"</span></td>"},renderIntroHtml:function(){var a=this.view;return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"}},Mb=5,Nb=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];return Xa.agenda={"class":Jb,defaults:{allDaySlot:!0,allDayText:"all-day",slotDuration:"00:30:00",minTime:"00:00:00",maxTime:"24:00:00",slotEventOverlap:!0}},Xa.agendaDay={type:"agenda",duration:{days:1}},Xa.agendaWeek={type:"agenda",duration:{weeks:1}},Wa}); \ No newline at end of file
diff --git a/library/fullcalendar/fullcalendar.print.css b/library/fullcalendar/fullcalendar.print.css
index 11b823f74..83d11563b 100644
--- a/library/fullcalendar/fullcalendar.print.css
+++ b/library/fullcalendar/fullcalendar.print.css
@@ -1,5 +1,5 @@
/*!
- * FullCalendar v2.7.3 Print Stylesheet
+ * FullCalendar v2.8.0 Print Stylesheet
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
diff --git a/library/fullcalendar/gcal.js b/library/fullcalendar/gcal.js
index 58b85c195..1d6b91c5b 100644
--- a/library/fullcalendar/gcal.js
+++ b/library/fullcalendar/gcal.js
@@ -1,5 +1,5 @@
/*!
- * FullCalendar v2.7.3 Google Calendar Plugin
+ * FullCalendar v2.8.0 Google Calendar Plugin
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
diff --git a/library/fullcalendar/lang-all.js b/library/fullcalendar/lang-all.js
index 7d7e25192..dc7577063 100644
--- a/library/fullcalendar/lang-all.js
+++ b/library/fullcalendar/lang-all.js
@@ -1,4 +1,4 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:6,doy:12}});return a}(),a.fullCalendar.datepickerLang("ar-ma","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-ma",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})}(),function(){!function(){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=(b.defineLocale||b.lang).call(b,"ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(a){return a.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("ar-sa","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-sa",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ar-tn",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("ar-tn","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-tn",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})}(),function(){!function(){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=function(a){return 0===a?0:1===a?1:2===a?2:a%100>=3&&10>=a%100?3:a%100>=11?4:5},e={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},f=function(a){return function(b,c,f,g){var h=d(b),i=e[a][d(b)];return 2===h&&(i=i[c?0:1]),i.replace(/%d/i,b)}},g=["كانون الثاني يناير","شباط فبراير","آذار مارس","نيسان أبريل","أيار مايو","حزيران يونيو","تموز يوليو","آب أغسطس","أيلول سبتمبر","تشرين الأول أكتوبر","تشرين الثاني نوفمبر","كانون الأول ديسمبر"],h=(b.defineLocale||b.lang).call(b,"ar",{months:g,monthsShort:g,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:f("s"),m:f("m"),mm:f("m"),h:f("h"),hh:f("h"),d:f("d"),dd:f("d"),M:f("M"),MM:f("M"),y:f("y"),yy:f("y")},preparse:function(a){return a.replace(/\u200f/g,"").replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return h}(),a.fullCalendar.datepickerLang("ar","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"bg",{months:"януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),monthsShort:"янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),weekdays:"неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),weekdaysShort:"нед_пон_вто_сря_чет_пет_съб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Днес в] LT",nextDay:"[Утре в] LT",nextWeek:"dddd [в] LT",lastDay:"[Вчера в] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[В изминалата] dddd [в] LT";case 1:case 2:case 4:case 5:return"[В изминалия] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"след %s",past:"преди %s",s:"няколко секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дни",M:"месец",MM:"%d месеца",y:"година",yy:"%d години"},ordinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(a){var b=a%10,c=a%100;return 0===a?a+"-ев":0===c?a+"-ен":c>10&&20>c?a+"-ти":1===b?a+"-ви":2===b?a+"-ри":7===b||8===b?a+"-ми":a+"-ти"},week:{dow:1,doy:7}});return a}(),a.fullCalendar.datepickerLang("bg","bg",{closeText:"затвори",prevText:"&#x3C;назад",nextText:"напред&#x3E;",nextBigText:"&#x3E;&#x3E;",currentText:"днес",monthNames:["Януари","Февруари","Март","Април","Май","Юни","Юли","Август","Септември","Октомври","Ноември","Декември"],monthNamesShort:["Яну","Фев","Мар","Апр","Май","Юни","Юли","Авг","Сеп","Окт","Нов","Дек"],dayNames:["Неделя","Понеделник","Вторник","Сряда","Четвъртък","Петък","Събота"],dayNamesShort:["Нед","Пон","Вто","Сря","Чет","Пет","Съб"],dayNamesMin:["Не","По","Вт","Ср","Че","Пе","Съ"],weekHeader:"Wk",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("bg",{buttonText:{month:"Месец",week:"Седмица",day:"Ден",list:"График"},allDayText:"Цял ден",eventLimitText:function(a){return"+още "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ca",{months:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),monthsShort:"gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd D MMMM YYYY H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(a,b){var c=1===a?"r":2===a?"n":3===a?"r":4===a?"t":"è";return"w"!==b&&"W"!==b||(c="a"),a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("ca","ca",{closeText:"Tanca",prevText:"Anterior",nextText:"Següent",currentText:"Avui",monthNames:["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre"],monthNamesShort:["gen","feb","març","abr","maig","juny","jul","ag","set","oct","nov","des"],dayNames:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],dayNamesShort:["dg","dl","dt","dc","dj","dv","ds"],dayNamesMin:["dg","dl","dt","dc","dj","dv","ds"],weekHeader:"Set",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ca",{buttonText:{month:"Mes",week:"Setmana",day:"Dia",list:"Agenda"},allDayText:"Tot el dia",eventLimitText:"més"})}(),function(){!function(){"use strict";function a(a){return a>1&&5>a&&1!==~~(a/10)}function c(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"pár sekund":"pár sekundami";case"m":return c?"minuta":e?"minutu":"minutou";case"mm":return c||e?f+(a(b)?"minuty":"minut"):f+"minutami";case"h":return c?"hodina":e?"hodinu":"hodinou";case"hh":return c||e?f+(a(b)?"hodiny":"hodin"):f+"hodinami";case"d":return c||e?"den":"dnem";case"dd":return c||e?f+(a(b)?"dny":"dní"):f+"dny";case"M":return c||e?"měsíc":"měsícem";case"MM":return c||e?f+(a(b)?"měsíce":"měsíců"):f+"měsíci";case"y":return c||e?"rok":"rokem";case"yy":return c||e?f+(a(b)?"roky":"let"):f+"lety"}}var d="leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),e="led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"),f=(b.defineLocale||b.lang).call(b,"cs",{months:d,monthsShort:e,monthsParse:function(a,b){var c,d=[];for(c=0;12>c;c++)d[c]=new RegExp("^"+a[c]+"$|^"+b[c]+"$","i");return d}(d,e),shortMonthsParse:function(a){var b,c=[];for(b=0;12>b;b++)c[b]=new RegExp("^"+a[b]+"$","i");return c}(e),longMonthsParse:function(a){var b,c=[];for(b=0;12>b;b++)c[b]=new RegExp("^"+a[b]+"$","i");return c}(d),weekdays:"neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),weekdaysShort:"ne_po_út_st_čt_pá_so".split("_"),weekdaysMin:"ne_po_út_st_čt_pá_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes v] LT",nextDay:"[zítra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v neděli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve středu v] LT";case 4:return"[ve čtvrtek v] LT";case 5:return"[v pátek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[včera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou neděli v] LT";case 1:case 2:return"[minulé] dddd [v] LT";case 3:return"[minulou středu v] LT";case 4:case 5:return"[minulý] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"před %s",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("cs","cs",{closeText:"Zavřít",prevText:"&#x3C;Dříve",nextText:"Později&#x3E;",currentText:"Nyní",monthNames:["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec"],monthNamesShort:["led","úno","bře","dub","kvě","čer","čvc","srp","zář","říj","lis","pro"],dayNames:["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"],dayNamesShort:["ne","po","út","st","čt","pá","so"],dayNamesMin:["ne","po","út","st","čt","pá","so"],weekHeader:"Týd",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("cs",{buttonText:{month:"Měsíc",week:"Týden",day:"Den",list:"Agenda"},allDayText:"Celý den",eventLimitText:function(a){return"+další: "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY HH:mm"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I går kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("da","da",{closeText:"Luk",prevText:"&#x3C;Forrige",nextText:"Næste&#x3E;",currentText:"Idag",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"],dayNames:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],dayNamesShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],dayNamesMin:["Sø","Ma","Ti","On","To","Fr","Lø"],weekHeader:"Uge",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("da",{buttonText:{month:"Måned",week:"Uge",day:"Dag",list:"Agenda"},allDayText:"Hele dagen",eventLimitText:"flere"})}(),function(){!function(){"use strict";function a(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=(b.defineLocale||b.lang).call(b,"de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("de-at","de",{closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("de-at",{buttonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(a){return"+ weitere "+a}})}(),function(){!function(){"use strict";function a(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=(b.defineLocale||b.lang).call(b,"de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("de","de",{closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("de",{buttonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(a){return"+ weitere "+a}})}(),function(){!function(){"use strict";function a(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}var c=(b.defineLocale||b.lang).call(b,"el",{monthsNominativeEl:"Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),monthsGenitiveEl:"Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),months:function(a,b){return/D/.test(b.substring(0,b.indexOf("MMMM")))?this._monthsGenitiveEl[a.month()]:this._monthsNominativeEl[a.month()]},monthsShort:"Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),weekdays:"Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),weekdaysShort:"Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),weekdaysMin:"Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),meridiem:function(a,b,c){return a>11?c?"μμ":"ΜΜ":c?"πμ":"ΠΜ"},isPM:function(a){return"μ"===(a+"").toLowerCase()[0]},meridiemParse:/[ΠΜ]\.?Μ?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[Σήμερα {}] LT",nextDay:"[Αύριο {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[Χθες {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[το προηγούμενο] dddd [{}] LT";default:return"[την προηγούμενη] dddd [{}] LT"}},sameElse:"L"},calendar:function(b,c){var d=this._calendarEl[b],e=c&&c.hours();return a(d)&&(d=d.apply(c)),d.replace("{}",e%12===1?"στη":"στις")},relativeTime:{future:"σε %s",past:"%s πριν",s:"λίγα δευτερόλεπτα",m:"ένα λεπτό",mm:"%d λεπτά",h:"μία ώρα",hh:"%d ώρες",d:"μία μέρα",dd:"%d μέρες",M:"ένας μήνας",MM:"%d μήνες",y:"ένας χρόνος",yy:"%d χρόνια"},ordinalParse:/\d{1,2}η/,ordinal:"%dη",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("el","el",{closeText:"Κλείσιμο",prevText:"Προηγούμενος",nextText:"Επόμενος",currentText:"Σήμερα",monthNames:["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος"],monthNamesShort:["Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ"],dayNames:["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"],dayNamesShort:["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"],dayNamesMin:["Κυ","Δε","Τρ","Τε","Πε","Πα","Σα"],weekHeader:"Εβδ",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("el",{buttonText:{month:"Μήνας",week:"Εβδομάδα",day:"Ημέρα",list:"Ατζέντα"},allDayText:"Ολοήμερο",eventLimitText:"περισσότερα"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-au","en-AU",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",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"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-au")}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}});return a}(),a.fullCalendar.lang("en-ca")}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-gb","en-GB",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",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"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-gb")}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.lang("en-ie")}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-nz","en-NZ",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",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"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-nz")}(),function(){!function(){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),c="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=(b.defineLocale||b.lang).call(b,"es",{
-months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(b,d){return/-MMM-/.test(d)?c[b.month()]:a[b.month()]},monthsParseExact:!0,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("es","es",{closeText:"Cerrar",prevText:"&#x3C;Ant",nextText:"Sig&#x3E;",currentText:"Hoy",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"],dayNames:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],dayNamesShort:["dom","lun","mar","mié","jue","vie","sáb"],dayNamesMin:["D","L","M","X","J","V","S"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("es",{buttonText:{month:"Mes",week:"Semana",day:"Día",list:"Agenda"},allDayHtml:"Todo<br/>el día",eventLimitText:"más"})}(),function(){!function(){"use strict";var a={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},c={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},d=(b.defineLocale||b.lang).call(b,"fa",{months:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysShort:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(a){return/بعد از ظهر/.test(a)},meridiem:function(a,b,c){return 12>a?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چندین ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(a){return a.replace(/[۰-۹]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},ordinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("fa","fa",{closeText:"بستن",prevText:"&#x3C;قبلی",nextText:"بعدی&#x3E;",currentText:"امروز",monthNames:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["يکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"],dayNamesShort:["ی","د","س","چ","پ","ج","ش"],dayNamesMin:["ی","د","س","چ","پ","ج","ش"],weekHeader:"هف",dateFormat:"yy/mm/dd",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fa",{buttonText:{month:"ماه",week:"هفته",day:"روز",list:"برنامه"},allDayText:"تمام روز",eventLimitText:function(a){return"بیش از "+a}})}(),function(){!function(){"use strict";function a(a,b,d,e){var f="";switch(d){case"s":return e?"muutaman sekunnin":"muutama sekunti";case"m":return e?"minuutin":"minuutti";case"mm":f=e?"minuutin":"minuuttia";break;case"h":return e?"tunnin":"tunti";case"hh":f=e?"tunnin":"tuntia";break;case"d":return e?"päivän":"päivä";case"dd":f=e?"päivän":"päivää";break;case"M":return e?"kuukauden":"kuukausi";case"MM":f=e?"kuukauden":"kuukautta";break;case"y":return e?"vuoden":"vuosi";case"yy":f=e?"vuoden":"vuotta"}return f=c(a,e)+" "+f}function c(a,b){return 10>a?b?e[a]:d[a]:a}var d="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),e=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",d[7],d[8],d[9]],f=(b.defineLocale||b.lang).call(b,"fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("fi","fi",{closeText:"Sulje",prevText:"&#xAB;Edellinen",nextText:"Seuraava&#xBB;",currentText:"Tänään",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"],dayNamesShort:["Su","Ma","Ti","Ke","To","Pe","La"],dayNames:["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],dayNamesMin:["Su","Ma","Ti","Ke","To","Pe","La"],weekHeader:"Vk",dateFormat:"d.m.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fi",{buttonText:{month:"Kuukausi",week:"Viikko",day:"Päivä",list:"Tapahtumat"},allDayText:"Koko päivä",eventLimitText:"lisää"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")}});return a}(),a.fullCalendar.datepickerLang("fr-ca","fr-CA",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ca",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr-ch","fr-CH",{closeText:"Fermer",prevText:"&#x3C;Préc",nextText:"Suiv&#x3E;",currentText:"Courant",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sm",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ch",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(a){return a+(1===a?"er":"")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr","fr",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",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."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),weekdaysShort:"א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(a){return 2===a?"שעתיים":a+" שעות"},d:"יום",dd:function(a){return 2===a?"יומיים":a+" ימים"},M:"חודש",MM:function(a){return 2===a?"חודשיים":a+" חודשים"},y:"שנה",yy:function(a){return 2===a?"שנתיים":a%10===0&&10!==a?a+" שנה":a+" שנים"}},meridiemParse:/אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,isPM:function(a){return/^(אחה"צ|אחרי הצהריים|בערב)$/.test(a)},meridiem:function(a,b,c){return 5>a?"לפנות בוקר":10>a?"בבוקר":12>a?c?'לפנה"צ':"לפני הצהריים":18>a?c?'אחה"צ':"אחרי הצהריים":"בערב"}});return a}(),a.fullCalendar.datepickerLang("he","he",{closeText:"סגור",prevText:"&#x3C;הקודם",nextText:"הבא&#x3E;",currentText:"היום",monthNames:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthNamesShort:["ינו","פבר","מרץ","אפר","מאי","יוני","יולי","אוג","ספט","אוק","נוב","דצמ"],dayNames:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת"],dayNamesShort:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],dayNamesMin:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("he",{defaultButtonText:{month:"חודש",week:"שבוע",day:"יום",list:"סדר יום"},weekNumberTitle:"שבוע",allDayText:"כל היום",eventLimitText:"אחר"})}(),function(){!function(){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},d=(b.defineLocale||b.lang).call(b,"hi",{months:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),monthsParseExact:!0,weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(a,b){return 12===a&&(a=0),"रात"===b?4>a?a:a+12:"सुबह"===b?a:"दोपहर"===b?a>=10?a:a+12:"शाम"===b?a+12:void 0},meridiem:function(a,b,c){return 4>a?"रात":10>a?"सुबह":17>a?"दोपहर":20>a?"शाम":"रात"},week:{dow:0,doy:6}});return d}(),a.fullCalendar.datepickerLang("hi","hi",{closeText:"बंद",prevText:"पिछला",nextText:"अगला",currentText:"आज",monthNames:["जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून","जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर"],monthNamesShort:["जन","फर","मार्च","अप्रेल","मई","जून","जूलाई","अग","सित","अक्ट","नव","दि"],dayNames:["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],dayNamesShort:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],dayNamesMin:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],weekHeader:"हफ्ता",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hi",{buttonText:{month:"महीना",week:"सप्ताह",day:"दिन",list:"कार्यसूची"},allDayText:"सभी दिन",eventLimitText:function(a){return"+अधिक "+a}})}(),function(){!function(){"use strict";function a(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}var c=(b.defineLocale||b.lang).call(b,"hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:a,mm:a,h:a,hh:a,d:"dan",dd:a,M:"mjesec",MM:a,y:"godinu",yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("hr","hr",{closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],monthNamesShort:["Sij","Velj","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro"],dayNames:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Tje",dateFormat:"dd.mm.yy.",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hr",{buttonText:{month:"Mjesec",week:"Tjedan",day:"Dan",list:"Raspored"},allDayText:"Cijeli dan",eventLimitText:function(a){return"+ još "+a}})}(),function(){!function(){"use strict";function a(a,b,c,d){var e=a;switch(c){case"s":return d||b?"néhány másodperc":"néhány másodperce";case"m":return"egy"+(d||b?" perc":" perce");case"mm":return e+(d||b?" perc":" perce");case"h":return"egy"+(d||b?" óra":" órája");case"hh":return e+(d||b?" óra":" órája");case"d":return"egy"+(d||b?" nap":" napja");case"dd":return e+(d||b?" nap":" napja");case"M":return"egy"+(d||b?" hónap":" hónapja");case"MM":return e+(d||b?" hónap":" hónapja");case"y":return"egy"+(d||b?" év":" éve");case"yy":return e+(d||b?" év":" éve")}return""}function c(a){return(a?"":"[múlt] ")+"["+d[this.day()]+"] LT[-kor]"}var d="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" "),e=(b.defineLocale||b.lang).call(b,"hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(a){return"u"===a.charAt(1).toLowerCase()},meridiem:function(a,b,c){return 12>a?c===!0?"de":"DE":c===!0?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return c.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return c.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return e}(),a.fullCalendar.datepickerLang("hu","hu",{closeText:"bezár",prevText:"vissza",nextText:"előre",currentText:"ma",monthNames:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],monthNamesShort:["Jan","Feb","Már","Ápr","Máj","Jún","Júl","Aug","Szep","Okt","Nov","Dec"],dayNames:["Vasárnap","Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat"],dayNamesShort:["Vas","Hét","Ked","Sze","Csü","Pén","Szo"],dayNamesMin:["V","H","K","Sze","Cs","P","Szo"],weekHeader:"Hét",dateFormat:"yy.mm.dd.",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""}),a.fullCalendar.lang("hu",{buttonText:{month:"Hónap",week:"Hét",day:"Nap",list:"Napló"},allDayText:"Egész nap",eventLimitText:"további"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(a,b){return 12===a&&(a=0),"pagi"===b?a:"siang"===b?a>=11?a:a+12:"sore"===b||"malam"===b?a+12:void 0},meridiem:function(a,b,c){return 11>a?"pagi":15>a?"siang":19>a?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}});return a}(),a.fullCalendar.datepickerLang("id","id",{closeText:"Tutup",prevText:"&#x3C;mundur",nextText:"maju&#x3E;",currentText:"hari ini",monthNames:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","Nopember","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agus","Sep","Okt","Nop","Des"],dayNames:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],dayNamesShort:["Min","Sen","Sel","Rab","kam","Jum","Sab"],dayNamesMin:["Mg","Sn","Sl","Rb","Km","jm","Sb"],weekHeader:"Mg",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("id",{buttonText:{month:"Bulan",week:"Minggu",day:"Hari",list:"Agenda"},allDayHtml:"Sehari<br/>penuh",eventLimitText:"lebih"})}(),function(){!function(){"use strict";function a(a){return a%100===11?!0:a%10!==1}function c(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"nokkrar sekúndur":"nokkrum sekúndum";case"m":return c?"mínúta":"mínútu";case"mm":return a(b)?f+(c||e?"mínútur":"mínútum"):c?f+"mínúta":f+"mínútu";case"hh":return a(b)?f+(c||e?"klukkustundir":"klukkustundum"):f+"klukkustund";case"d":return c?"dagur":e?"dag":"degi";case"dd":return a(b)?c?f+"dagar":f+(e?"daga":"dögum"):c?f+"dagur":f+(e?"dag":"degi");case"M":return c?"mánuður":e?"mánuð":"mánuði";case"MM":return a(b)?c?f+"mánuðir":f+(e?"mánuði":"mánuðum"):c?f+"mánuður":f+(e?"mánuð":"mánuði");case"y":return c||e?"ár":"ári";case"yy":return a(b)?f+(c||e?"ár":"árum"):f+(c||e?"ár":"ári")}}var d=(b.defineLocale||b.lang).call(b,"is",{months:"janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),monthsShort:"jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),weekdays:"sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),weekdaysShort:"sun_mán_þri_mið_fim_fös_lau".split("_"),weekdaysMin:"Su_Má_Þr_Mi_Fi_Fö_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[í dag kl.] LT",nextDay:"[á morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[í gær kl.] LT",lastWeek:"[síðasta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s síðan",s:c,m:c,mm:c,h:"klukkustund",hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("is","is",{closeText:"Loka",prevText:"&#x3C; Fyrri",nextText:"Næsti &#x3E;",currentText:"Í dag",monthNames:["Janúar","Febrúar","Mars","Apríl","Maí","Júní","Júlí","Ágúst","September","Október","Nóvember","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Maí","Jún","Júl","Ágú","Sep","Okt","Nóv","Des"],dayNames:["Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur"],dayNamesShort:["Sun","Mán","Þri","Mið","Fim","Fös","Lau"],dayNamesMin:["Su","Má","Þr","Mi","Fi","Fö","La"],weekHeader:"Vika",dateFormat:"dd.mm.yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("is",{buttonText:{month:"Mánuður",week:"Vika",day:"Dagur",list:"Dagskrá"},allDayHtml:"Allan<br/>daginn",eventLimitText:"meira"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"Do_Lu_Ma_Me_Gi_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(a){return(/^[0-9].+$/.test(a)?"tra":"in")+" "+a},past:"%s fa",s:"alcuni secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("it","it",{closeText:"Chiudi",prevText:"&#x3C;Prec",nextText:"Succ&#x3E;",currentText:"Oggi",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"],dayNames:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],dayNamesShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],dayNamesMin:["Do","Lu","Ma","Me","Gi","Ve","Sa"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("it",{buttonText:{month:"Mese",week:"Settimana",day:"Giorno",list:"Agenda"},allDayHtml:"Tutto il<br/>giorno",eventLimitText:function(a){return"+altri "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ja",{months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"Ah時m分",LTS:"Ah時m分s秒",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah時m分",LLLL:"YYYY年M月D日Ah時m分 dddd"},meridiemParse:/午前|午後/i,isPM:function(a){return"午後"===a},meridiem:function(a,b,c){return 12>a?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:"[来週]dddd LT",lastDay:"[昨日] LT",lastWeek:"[前週]dddd LT",sameElse:"L"},ordinalParse:/\d{1,2}日/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";default:return a}},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}});return a}(),a.fullCalendar.datepickerLang("ja","ja",{closeText:"閉じる",prevText:"&#x3C;前",nextText:"次&#x3E;",currentText:"今日",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月"],dayNames:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],dayNamesShort:["日","月","火","水","木","金","土"],dayNamesMin:["日","月","火","水","木","金","土"],weekHeader:"週",dateFormat:"yy/mm/dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),a.fullCalendar.lang("ja",{buttonText:{month:"月",week:"週",day:"日",list:"予定リスト"},allDayText:"終日",eventLimitText:function(a){return"他 "+a+" 件"}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ko",{months:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),monthsShort:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),weekdays:"일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),weekdaysShort:"일_월_화_수_목_금_토".split("_"),weekdaysMin:"일_월_화_수_목_금_토".split("_"),longDateFormat:{LT:"A h시 m분",LTS:"A h시 m분 s초",L:"YYYY.MM.DD",LL:"YYYY년 MMMM D일",LLL:"YYYY년 MMMM D일 A h시 m분",LLLL:"YYYY년 MMMM D일 dddd A h시 m분"},calendar:{sameDay:"오늘 LT",nextDay:"내일 LT",nextWeek:"dddd LT",lastDay:"어제 LT",lastWeek:"지난주 dddd LT",sameElse:"L"},relativeTime:{future:"%s 후",past:"%s 전",s:"몇 초",ss:"%d초",m:"일분",mm:"%d분",h:"한 시간",hh:"%d시간",d:"하루",dd:"%d일",M:"한 달",MM:"%d달",y:"일 년",yy:"%d년"},ordinalParse:/\d{1,2}일/,ordinal:"%d일",meridiemParse:/오전|오후/,isPM:function(a){return"오후"===a},meridiem:function(a,b,c){return 12>a?"오전":"오후"}});return a}(),a.fullCalendar.datepickerLang("ko","ko",{closeText:"닫기",prevText:"이전달",nextText:"다음달",currentText:"오늘",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월"],dayNames:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],dayNamesShort:["일","월","화","수","목","금","토"],dayNamesMin:["일","월","화","수","목","금","토"],weekHeader:"Wk",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"년"}),a.fullCalendar.lang("ko",{buttonText:{month:"월",week:"주",day:"일",list:"일정목록"},allDayText:"종일",eventLimitText:"개"})}(),function(){!function(){"use strict";function a(a,b,c,d){return b?"kelios sekundės":d?"kelių sekundžių":"kelias sekundes"}function c(a,b,c,d){return b?e(c)[0]:d?e(c)[1]:e(c)[2]}function d(a){return a%10===0||a>10&&20>a}function e(a){return g[a].split("_")}function f(a,b,f,g){var h=a+" ";return 1===a?h+c(a,b,f[0],g):b?h+(d(a)?e(f)[1]:e(f)[0]):g?h+e(f)[1]:h+(d(a)?e(f)[1]:e(f)[2])}var g={m:"minutė_minutės_minutę",mm:"minutės_minučių_minutes",
-h:"valanda_valandos_valandą",hh:"valandos_valandų_valandas",d:"diena_dienos_dieną",dd:"dienos_dienų_dienas",M:"mėnuo_mėnesio_mėnesį",MM:"mėnesiai_mėnesių_mėnesius",y:"metai_metų_metus",yy:"metai_metų_metus"},h=(b.defineLocale||b.lang).call(b,"lt",{months:{format:"sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis".split("_")},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),weekdaysMin:"S_P_A_T_K_Pn_Š".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[Šiandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Praėjusį] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prieš %s",s:a,m:c,mm:f,h:c,hh:f,d:c,dd:f,M:c,MM:f,y:c,yy:f},ordinalParse:/\d{1,2}-oji/,ordinal:function(a){return a+"-oji"},week:{dow:1,doy:4}});return h}(),a.fullCalendar.datepickerLang("lt","lt",{closeText:"Uždaryti",prevText:"&#x3C;Atgal",nextText:"Pirmyn&#x3E;",currentText:"Šiandien",monthNames:["Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis","Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis"],monthNamesShort:["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rugp","Rugs","Spa","Lap","Gru"],dayNames:["sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis"],dayNamesShort:["sek","pir","ant","tre","ket","pen","šeš"],dayNamesMin:["Se","Pr","An","Tr","Ke","Pe","Še"],weekHeader:"SAV",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""}),a.fullCalendar.lang("lt",{buttonText:{month:"Mėnuo",week:"Savaitė",day:"Diena",list:"Darbotvarkė"},allDayText:"Visą dieną",eventLimitText:"daugiau"})}(),function(){!function(){"use strict";function a(a,b,c){return c?b%10===1&&11!==b?a[2]:a[3]:b%10===1&&11!==b?a[0]:a[1]}function c(b,c,d){return b+" "+a(f[d],b,c)}function d(b,c,d){return a(f[d],b,c)}function e(a,b){return b?"dažas sekundes":"dažām sekundēm"}var f={m:"minūtes_minūtēm_minūte_minūtes".split("_"),mm:"minūtes_minūtēm_minūte_minūtes".split("_"),h:"stundas_stundām_stunda_stundas".split("_"),hh:"stundas_stundām_stunda_stundas".split("_"),d:"dienas_dienām_diena_dienas".split("_"),dd:"dienas_dienām_diena_dienas".split("_"),M:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),MM:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")},g=(b.defineLocale||b.lang).call(b,"lv",{months:"janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),weekdays:"svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[Šodien pulksten] LT",nextDay:"[Rīt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pagājušā] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"pēc %s",past:"pirms %s",s:e,m:d,mm:c,h:d,hh:c,d:d,dd:c,M:d,MM:c,y:d,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return g}(),a.fullCalendar.datepickerLang("lv","lv",{closeText:"Aizvērt",prevText:"Iepr.",nextText:"Nāk.",currentText:"Šodien",monthNames:["Janvāris","Februāris","Marts","Aprīlis","Maijs","Jūnijs","Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris"],monthNamesShort:["Jan","Feb","Mar","Apr","Mai","Jūn","Jūl","Aug","Sep","Okt","Nov","Dec"],dayNames:["svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena"],dayNamesShort:["svt","prm","otr","tre","ctr","pkt","sst"],dayNamesMin:["Sv","Pr","Ot","Tr","Ct","Pk","Ss"],weekHeader:"Ned.",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("lv",{buttonText:{month:"Mēnesis",week:"Nedēļa",day:"Diena",list:"Dienas kārtība"},allDayText:"Visu dienu",eventLimitText:function(a){return"+vēl "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"sø._ma._ti._on._to._fr._lø.".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en måned",MM:"%d måneder",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("nb","nb",{closeText:"Lukk",prevText:"&#xAB;Forrige",nextText:"Neste&#xBB;",currentText:"I dag",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"],dayNamesShort:["søn","man","tir","ons","tor","fre","lør"],dayNames:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],dayNamesMin:["sø","ma","ti","on","to","fr","lø"],weekHeader:"Uke",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("nb",{buttonText:{month:"Måned",week:"Uke",day:"Dag",list:"Agenda"},allDayText:"Hele dagen",eventLimitText:"til"})}(),function(){!function(){"use strict";var a="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),c="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),d=(b.defineLocale||b.lang).call(b,"nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(b,d){return/-MMM-/.test(d)?c[b.month()]:a[b.month()]},monthsParseExact:!0,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(a){return a+(1===a||8===a||a>=20?"ste":"de")},week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("nl","nl",{closeText:"Sluiten",prevText:"←",nextText:"→",currentText:"Vandaag",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"],dayNames:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],dayNamesShort:["zon","maa","din","woe","don","vri","zat"],dayNamesMin:["zo","ma","di","wo","do","vr","za"],weekHeader:"Wk",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("nl",{buttonText:{month:"Maand",week:"Week",day:"Dag",list:"Agenda"},allDayText:"Hele dag",eventLimitText:"extra"})}(),function(){!function(){"use strict";function a(a){return 5>a%10&&a%10>1&&~~(a/10)%10!==1}function c(b,c,d){var e=b+" ";switch(d){case"m":return c?"minuta":"minutę";case"mm":return e+(a(b)?"minuty":"minut");case"h":return c?"godzina":"godzinę";case"hh":return e+(a(b)?"godziny":"godzin");case"MM":return e+(a(b)?"miesiące":"miesięcy");case"yy":return e+(a(b)?"lata":"lat")}}var d="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),e="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"),f=(b.defineLocale||b.lang).call(b,"pl",{months:function(a,b){return""===b?"("+e[a.month()]+"|"+d[a.month()]+")":/D MMMM/.test(b)?e[a.month()]:d[a.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"nie_pon_wt_śr_czw_pt_sb".split("_"),weekdaysMin:"Nd_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:c,mm:c,h:c,hh:c,d:"1 dzień",dd:"%d dni",M:"miesiąc",MM:c,y:"rok",yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("pl","pl",{closeText:"Zamknij",prevText:"&#x3C;Poprzedni",nextText:"Następny&#x3E;",currentText:"Dziś",monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lu","Mar","Kw","Maj","Cze","Lip","Sie","Wrz","Pa","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Nie","Pn","Wt","Śr","Czw","Pt","So"],dayNamesMin:["N","Pn","Wt","Śr","Cz","Pt","So"],weekHeader:"Tydz",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("pl",{buttonText:{month:"Miesiąc",week:"Tydzień",day:"Dzień",list:"Plan dnia"},allDayText:"Cały dzień",eventLimitText:"więcej"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"pt-br",{months:"Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [às] HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atrás",s:"poucos segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº"});return a}(),a.fullCalendar.datepickerLang("pt-br","pt-BR",{closeText:"Fechar",prevText:"&#x3C;Anterior",nextText:"Próximo&#x3E;",currentText:"Hoje",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"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("pt-br",{buttonText:{month:"Mês",week:"Semana",day:"Dia",list:"Compromissos"},allDayText:"dia inteiro",eventLimitText:function(a){return"mais +"+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"pt",{months:"Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("pt","pt",{closeText:"Fechar",prevText:"Anterior",nextText:"Seguinte",currentText:"Hoje",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"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sem",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("pt",{buttonText:{month:"Mês",week:"Semana",day:"Dia",list:"Agenda"},allDayText:"Todo o dia",eventLimitText:"mais"})}(),function(){!function(){"use strict";function a(a,b,c){var d={mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"},e=" ";return(a%100>=20||a>=100&&a%100===0)&&(e=" de "),a+e+d[c]}var c=(b.defineLocale||b.lang).call(b,"ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[mâine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s în urmă",s:"câteva secunde",m:"un minut",mm:a,h:"o oră",hh:a,d:"o zi",dd:a,M:"o lună",MM:a,y:"un an",yy:a},week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("ro","ro",{closeText:"Închide",prevText:"&#xAB; Luna precedentă",nextText:"Luna următoare &#xBB;",currentText:"Azi",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"],dayNames:["Duminică","Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă"],dayNamesShort:["Dum","Lun","Mar","Mie","Joi","Vin","Sâm"],dayNamesMin:["Du","Lu","Ma","Mi","Jo","Vi","Sâ"],weekHeader:"Săpt",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ro",{buttonText:{prev:"precedentă",next:"următoare",month:"Lună",week:"Săptămână",day:"Zi",list:"Agendă"},allDayText:"Toată ziua",eventLimitText:function(a){return"+alte "+a}})}(),function(){!function(){"use strict";function a(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(b,c,d){var e={mm:c?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};return"m"===d?c?"минута":"минуту":b+" "+a(e[d],+b)}var d=[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[йя]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],e=(b.defineLocale||b.lang).call(b,"ru",{months:{format:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_"),standalone:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_")},monthsShort:{format:"янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.".split("_"),standalone:"янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.".split("_")},weekdays:{standalone:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),format:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_"),isFormat:/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/},weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:d,longMonthsParse:d,shortMonthsParse:d,monthsRegex:/^(сентябр[яь]|октябр[яь]|декабр[яь]|феврал[яь]|январ[яь]|апрел[яь]|августа?|ноябр[яь]|сент\.|февр\.|нояб\.|июнь|янв.|июль|дек.|авг.|апр.|марта|мар[.т]|окт.|июн[яь]|июл[яь]|ма[яй])/i,monthsShortRegex:/^(сентябр[яь]|октябр[яь]|декабр[яь]|феврал[яь]|январ[яь]|апрел[яь]|августа?|ноябр[яь]|сент\.|февр\.|нояб\.|июнь|янв.|июль|дек.|авг.|апр.|марта|мар[.т]|окт.|июн[яь]|июл[яь]|ма[яй])/i,monthsStrictRegex:/^(сентябр[яь]|октябр[яь]|декабр[яь]|феврал[яь]|январ[яь]|апрел[яь]|августа?|ноябр[яь]|марта?|июн[яь]|июл[яь]|ма[яй])/i,monthsShortStrictRegex:/^(нояб\.|февр\.|сент\.|июль|янв\.|июн[яь]|мар[.т]|авг\.|апр\.|окт\.|дек\.|ма[яй])/i,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сегодня в] LT",nextDay:"[Завтра в] LT",lastDay:"[Вчера в] LT",nextWeek:function(a){if(a.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В следующее] dddd [в] LT";case 1:case 2:case 4:return"[В следующий] dddd [в] LT";case 3:case 5:case 6:return"[В следующую] dddd [в] LT"}},lastWeek:function(a){if(a.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В прошлое] dddd [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",m:c,mm:c,h:"час",hh:c,d:"день",dd:c,M:"месяц",MM:c,y:"год",yy:c},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(a){return/^(дня|вечера)$/.test(a)},meridiem:function(a,b,c){return 4>a?"ночи":12>a?"утра":17>a?"дня":"вечера"},ordinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":return a+"-й";case"D":return a+"-го";case"w":case"W":return a+"-я";default:return a}},week:{dow:1,doy:7}});return e}(),a.fullCalendar.datepickerLang("ru","ru",{closeText:"Закрыть",prevText:"&#x3C;Пред",nextText:"След&#x3E;",currentText:"Сегодня",monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],dayNamesMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Нед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ru",{buttonText:{month:"Месяц",week:"Неделя",day:"День",list:"Повестка дня"},allDayText:"Весь день",eventLimitText:function(a){return"+ ещё "+a}})}(),function(){!function(){"use strict";function a(a){return a>1&&5>a}function c(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"pár sekúnd":"pár sekundami";case"m":return c?"minúta":e?"minútu":"minútou";case"mm":return c||e?f+(a(b)?"minúty":"minút"):f+"minútami";case"h":return c?"hodina":e?"hodinu":"hodinou";case"hh":return c||e?f+(a(b)?"hodiny":"hodín"):f+"hodinami";case"d":return c||e?"deň":"dňom";case"dd":return c||e?f+(a(b)?"dni":"dní"):f+"dňami";case"M":return c||e?"mesiac":"mesiacom";case"MM":return c||e?f+(a(b)?"mesiace":"mesiacov"):f+"mesiacmi";case"y":return c||e?"rok":"rokom";case"yy":return c||e?f+(a(b)?"roky":"rokov"):f+"rokmi"}}var d="január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),e="jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"),f=(b.defineLocale||b.lang).call(b,"sk",{months:d,monthsShort:e,weekdays:"nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_št_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_št_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nedeľu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo štvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[včera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulú nedeľu o] LT";case 1:case 2:return"[minulý] dddd [o] LT";case 3:return"[minulú stredu o] LT";case 4:case 5:return"[minulý] dddd [o] LT";case 6:return"[minulú sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("sk","sk",{closeText:"Zavrieť",prevText:"&#x3C;Predchádzajúci",nextText:"Nasledujúci&#x3E;",currentText:"Dnes",monthNames:["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december"],monthNamesShort:["Jan","Feb","Mar","Apr","Máj","Jún","Júl","Aug","Sep","Okt","Nov","Dec"],dayNames:["nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota"],dayNamesShort:["Ned","Pon","Uto","Str","Štv","Pia","Sob"],dayNamesMin:["Ne","Po","Ut","St","Št","Pia","So"],weekHeader:"Ty",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sk",{buttonText:{month:"Mesiac",week:"Týždeň",day:"Deň",list:"Rozvrh"},allDayText:"Celý deň",eventLimitText:function(a){return"+ďalšie: "+a}})}(),function(){!function(){"use strict";function a(a,b,c,d){var e=a+" ";switch(c){case"s":return b||d?"nekaj sekund":"nekaj sekundami";case"m":return b?"ena minuta":"eno minuto";case"mm":return e+=1===a?b?"minuta":"minuto":2===a?b||d?"minuti":"minutama":5>a?b||d?"minute":"minutami":b||d?"minut":"minutami";case"h":return b?"ena ura":"eno uro";case"hh":return e+=1===a?b?"ura":"uro":2===a?b||d?"uri":"urama":5>a?b||d?"ure":"urami":b||d?"ur":"urami";case"d":return b||d?"en dan":"enim dnem";case"dd":return e+=1===a?b||d?"dan":"dnem":2===a?b||d?"dni":"dnevoma":b||d?"dni":"dnevi";case"M":return b||d?"en mesec":"enim mesecem";case"MM":return e+=1===a?b||d?"mesec":"mesecem":2===a?b||d?"meseca":"mesecema":5>a?b||d?"mesece":"meseci":b||d?"mesecev":"meseci";case"y":return b||d?"eno leto":"enim letom";case"yy":return e+=1===a?b||d?"leto":"letom":2===a?b||d?"leti":"letoma":5>a?b||d?"leta":"leti":b||d?"let":"leti"}}var c=(b.defineLocale||b.lang).call(b,"sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._čet._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_če_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[včeraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prejšnjo] [nedeljo] [ob] LT";case 3:return"[prejšnjo] [sredo] [ob] LT";case 6:return"[prejšnjo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prejšnji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"čez %s",past:"pred %s",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("sl","sl",{closeText:"Zapri",prevText:"&#x3C;Prejšnji",nextText:"Naslednji&#x3E;",currentText:"Trenutni",monthNames:["Januar","Februar","Marec","April","Maj","Junij","Julij","Avgust","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Avg","Sep","Okt","Nov","Dec"],dayNames:["Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota"],dayNamesShort:["Ned","Pon","Tor","Sre","Čet","Pet","Sob"],dayNamesMin:["Ne","Po","To","Sr","Če","Pe","So"],weekHeader:"Teden",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sl",{buttonText:{month:"Mesec",week:"Teden",day:"Dan",list:"Dnevni red"},allDayText:"Ves dan",eventLimitText:"več"})}(),function(){!function(){"use strict";var a={words:{m:["један минут","једне минуте"],mm:["минут","минуте","минута"],h:["један сат","једног сата"],hh:["сат","сата","сати"],dd:["дан","дана","дана"],MM:["месец","месеца","месеци"],yy:["година","године","година"]},correctGrammaticalCase:function(a,b){return 1===a?b[0]:a>=2&&4>=a?b[1]:b[2]},translate:function(b,c,d){var e=a.words[d];return 1===d.length?c?e[0]:e[1]:b+" "+a.correctGrammaticalCase(b,e)}},c=(b.defineLocale||b.lang).call(b,"sr-cyrl",{months:"јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар".split("_"),monthsShort:"јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.".split("_"),monthsParseExact:!0,weekdays:"недеља_понедељак_уторак_среда_четвртак_петак_субота".split("_"),weekdaysShort:"нед._пон._уто._сре._чет._пет._суб.".split("_"),weekdaysMin:"не_по_ут_ср_че_пе_су".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[данас у] LT",nextDay:"[сутра у] LT",nextWeek:function(){switch(this.day()){case 0:return"[у] [недељу] [у] LT";case 3:return"[у] [среду] [у] LT";case 6:return"[у] [суботу] [у] LT";case 1:case 2:case 4:case 5:return"[у] dddd [у] LT"}},lastDay:"[јуче у] LT",lastWeek:function(){var a=["[прошле] [недеље] [у] LT","[прошлог] [понедељка] [у] LT","[прошлог] [уторка] [у] LT","[прошле] [среде] [у] LT","[прошлог] [четвртка] [у] LT","[прошлог] [петка] [у] LT","[прошле] [суботе] [у] LT"];return a[this.day()]},sameElse:"L"},relativeTime:{future:"за %s",past:"пре %s",s:"неколико секунди",m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:"дан",dd:a.translate,M:"месец",MM:a.translate,y:"годину",yy:a.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("sr-cyrl","sr",{closeText:"Затвори",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Данас",monthNames:["Јануар","Фебруар","Март","Април","Мај","Јун","Јул","Август","Септембар","Октобар","Новембар","Децембар"],monthNamesShort:["Јан","Феб","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Нов","Дец"],dayNames:["Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота"],dayNamesShort:["Нед","Пон","Уто","Сре","Чет","Пет","Суб"],dayNamesMin:["Не","По","Ут","Ср","Че","Пе","Су"],weekHeader:"Сед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sr-cyrl",{buttonText:{month:"Месец",week:"Недеља",day:"Дан",list:"Планер"},allDayText:"Цео дан",eventLimitText:function(a){return"+ још "+a}})}(),function(){!function(){"use strict";var a={words:{m:["jedan minut","jedne minute"],mm:["minut","minute","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mesec","meseca","meseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(a,b){return 1===a?b[0]:a>=2&&4>=a?b[1]:b[2]},translate:function(b,c,d){var e=a.words[d];return 1===d.length?c?e[0]:e[1]:b+" "+a.correctGrammaticalCase(b,e)}},c=(b.defineLocale||b.lang).call(b,"sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var a=["[prošle] [nedelje] [u] LT","[prošlog] [ponedeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return a[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:"dan",dd:a.translate,M:"mesec",MM:a.translate,y:"godinu",yy:a.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("sr","sr",{closeText:"Затвори",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Данас",monthNames:["Јануар","Фебруар","Март","Април","Мај","Јун","Јул","Август","Септембар","Октобар","Новембар","Децембар"],monthNamesShort:["Јан","Феб","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Нов","Дец"],dayNames:["Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота"],dayNamesShort:["Нед","Пон","Уто","Сре","Чет","Пет","Суб"],dayNamesMin:["Не","По","Ут","Ср","Че","Пе","Су"],weekHeader:"Сед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sr",{buttonText:{month:"Месец",week:"Недеља",day:"Дан",list:"Планер"},allDayText:"Цео дан",eventLimitText:function(a){return"+ још "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),
-monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"[På] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}(e|a)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"e":1===b?"a":2===b?"a":"e";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("sv","sv",{closeText:"Stäng",prevText:"&#xAB;Förra",nextText:"Nästa&#xBB;",currentText:"Idag",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"],dayNamesShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],dayNames:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],dayNamesMin:["Sö","Må","Ti","On","To","Fr","Lö"],weekHeader:"Ve",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sv",{buttonText:{month:"Månad",week:"Vecka",day:"Dag",list:"Program"},allDayText:"Heldag",eventLimitText:"till"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),monthsParseExact:!0,weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H นาฬิกา m นาที",LTS:"H นาฬิกา m นาที s วินาที",L:"YYYY/MM/DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา H นาฬิกา m นาที",LLLL:"วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(a){return"หลังเที่ยง"===a},meridiem:function(a,b,c){return 12>a?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}});return a}(),a.fullCalendar.datepickerLang("th","th",{closeText:"ปิด",prevText:"&#xAB;&#xA0;ย้อน",nextText:"ถัดไป&#xA0;&#xBB;",currentText:"วันนี้",monthNames:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthNamesShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],dayNames:["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"],dayNamesShort:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],dayNamesMin:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("th",{buttonText:{month:"เดือน",week:"สัปดาห์",day:"วัน",list:"แผนงาน"},allDayText:"ตลอดวัน",eventLimitText:"เพิ่มเติม"})}(),function(){!function(){"use strict";var a={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"},c=(b.defineLocale||b.lang).call(b,"tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[haftaya] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen hafta] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinalParse:/\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,ordinal:function(b){if(0===b)return b+"'ıncı";var c=b%10,d=b%100-c,e=b>=100?100:null;return b+(a[c]||a[d]||a[e])},week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("tr","tr",{closeText:"kapat",prevText:"&#x3C;geri",nextText:"ileri&#x3e",currentText:"bugün",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"],dayNames:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],dayNamesShort:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],dayNamesMin:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],weekHeader:"Hf",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("tr",{buttonText:{next:"ileri",month:"Ay",week:"Hafta",day:"Gün",list:"Ajanda"},allDayText:"Tüm gün",eventLimitText:"daha fazla"})}(),function(){!function(){"use strict";function a(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(b,c,d){var e={mm:c?"хвилина_хвилини_хвилин":"хвилину_хвилини_хвилин",hh:c?"година_години_годин":"годину_години_годин",dd:"день_дні_днів",MM:"місяць_місяці_місяців",yy:"рік_роки_років"};return"m"===d?c?"хвилина":"хвилину":"h"===d?c?"година":"годину":b+" "+a(e[d],+b)}function d(a,b){var c={nominative:"неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота".split("_"),accusative:"неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу".split("_"),genitive:"неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи".split("_")},d=/(\[[ВвУу]\]) ?dddd/.test(b)?"accusative":/\[?(?:минулої|наступної)? ?\] ?dddd/.test(b)?"genitive":"nominative";return c[d][a.day()]}function e(a){return function(){return a+"о"+(11===this.hours()?"б":"")+"] LT"}}var f=(b.defineLocale||b.lang).call(b,"uk",{months:{format:"січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня".split("_"),standalone:"січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень".split("_")},monthsShort:"січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),weekdays:d,weekdaysShort:"нд_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY р.",LLL:"D MMMM YYYY р., HH:mm",LLLL:"dddd, D MMMM YYYY р., HH:mm"},calendar:{sameDay:e("[Сьогодні "),nextDay:e("[Завтра "),lastDay:e("[Вчора "),nextWeek:e("[У] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return e("[Минулої] dddd [").call(this);case 1:case 2:case 4:return e("[Минулого] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"за %s",past:"%s тому",s:"декілька секунд",m:c,mm:c,h:"годину",hh:c,d:"день",dd:c,M:"місяць",MM:c,y:"рік",yy:c},meridiemParse:/ночі|ранку|дня|вечора/,isPM:function(a){return/^(дня|вечора)$/.test(a)},meridiem:function(a,b,c){return 4>a?"ночі":12>a?"ранку":17>a?"дня":"вечора"},ordinalParse:/\d{1,2}-(й|го)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":case"w":case"W":return a+"-й";case"D":return a+"-го";default:return a}},week:{dow:1,doy:7}});return f}(),a.fullCalendar.datepickerLang("uk","uk",{closeText:"Закрити",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Сьогодні",monthNames:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthNamesShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],dayNames:["неділя","понеділок","вівторок","середа","четвер","п’ятниця","субота"],dayNamesShort:["нед","пнд","вів","срд","чтв","птн","сбт"],dayNamesMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Тиж",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("uk",{buttonText:{month:"Місяць",week:"Тиждень",day:"День",list:"Порядок денний"},allDayText:"Увесь день",eventLimitText:function(a){return"+ще "+a+"..."}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"vi",{months:"tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),monthsShort:"Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),monthsParseExact:!0,weekdays:"chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(a){return/^ch$/i.test(a)},meridiem:function(a,b,c){return 12>a?c?"sa":"SA":c?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [năm] YYYY",LLL:"D MMMM [năm] YYYY HH:mm",LLLL:"dddd, D MMMM [năm] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[Hôm nay lúc] LT",nextDay:"[Ngày mai lúc] LT",nextWeek:"dddd [tuần tới lúc] LT",lastDay:"[Hôm qua lúc] LT",lastWeek:"dddd [tuần rồi lúc] LT",sameElse:"L"},relativeTime:{future:"%s tới",past:"%s trước",s:"vài giây",m:"một phút",mm:"%d phút",h:"một giờ",hh:"%d giờ",d:"một ngày",dd:"%d ngày",M:"một tháng",MM:"%d tháng",y:"một năm",yy:"%d năm"},ordinalParse:/\d{1,2}/,ordinal:function(a){return a},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("vi","vi",{closeText:"Đóng",prevText:"&#x3C;Trước",nextText:"Tiếp&#x3E;",currentText:"Hôm nay",monthNames:["Tháng Một","Tháng Hai","Tháng Ba","Tháng Tư","Tháng Năm","Tháng Sáu","Tháng Bảy","Tháng Tám","Tháng Chín","Tháng Mười","Tháng Mười Một","Tháng Mười Hai"],monthNamesShort:["Tháng 1","Tháng 2","Tháng 3","Tháng 4","Tháng 5","Tháng 6","Tháng 7","Tháng 8","Tháng 9","Tháng 10","Tháng 11","Tháng 12"],dayNames:["Chủ Nhật","Thứ Hai","Thứ Ba","Thứ Tư","Thứ Năm","Thứ Sáu","Thứ Bảy"],dayNamesShort:["CN","T2","T3","T4","T5","T6","T7"],dayNamesMin:["CN","T2","T3","T4","T5","T6","T7"],weekHeader:"Tu",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("vi",{buttonText:{month:"Tháng",week:"Tuần",day:"Ngày",list:"Lịch biểu"},allDayText:"Cả ngày",eventLimitText:function(a){return"+ thêm "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm分",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah点mm分",LLLL:"YYYY年MMMD日ddddAh点mm分",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah点mm分",llll:"YYYY年MMMD日ddddAh点mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"下午"===b||"晚上"===b?a+12:a>=11?a:a+12},meridiem:function(a,b,c){var d=100*a+b;return 600>d?"凌晨":900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var a,c;return a=b().startOf("week"),c=this.diff(a,"days")>=7?"[下]":"[本]",0===this.minutes()?c+"dddAh点整":c+"dddAh点mm"},lastWeek:function(){var a,c;return a=b().startOf("week"),c=this.unix()<a.unix()?"[上]":"[本]",0===this.minutes()?c+"dddAh点整":c+"dddAh点mm"},sameElse:"LL"},ordinalParse:/\d{1,2}(日|月|周)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"周";default:return a}},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("zh-cn","zh-CN",{closeText:"关闭",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),a.fullCalendar.lang("zh-cn",{buttonText:{month:"月",week:"周",day:"日",list:"日程"},allDayText:"全天",eventLimitText:function(a){return"另外 "+a+" 个"}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah點mm分",LTS:"Ah點m分s秒",L:"YYYY年MMMD日",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah點mm分",LLLL:"YYYY年MMMD日ddddAh點mm分",l:"YYYY年MMMD日",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah點mm分",llll:"YYYY年MMMD日ddddAh點mm分"},meridiemParse:/早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"早上"===b||"上午"===b?a:"中午"===b?a>=11?a:a+12:"下午"===b||"晚上"===b?a+12:void 0},meridiem:function(a,b,c){var d=100*a+b;return 900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"週";default:return a}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1分鐘",mm:"%d分鐘",h:"1小時",hh:"%d小時",d:"1天",dd:"%d天",M:"1個月",MM:"%d個月",y:"1年",yy:"%d年"}});return a}(),a.fullCalendar.datepickerLang("zh-tw","zh-TW",{closeText:"關閉",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy/mm/dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),a.fullCalendar.lang("zh-tw",{buttonText:{month:"月",week:"週",day:"天",list:"待辦事項"},allDayText:"全天",eventLimitText:"更多"})}(),(b.locale||b.lang).call(b,"en"),a.fullCalendar.lang("en"),a.datepicker&&a.datepicker.setDefaults(a.datepicker.regional[""])}); \ No newline at end of file
+months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(b,d){return/-MMM-/.test(d)?c[b.month()]:a[b.month()]},monthsParseExact:!0,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("es","es",{closeText:"Cerrar",prevText:"&#x3C;Ant",nextText:"Sig&#x3E;",currentText:"Hoy",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"],dayNames:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],dayNamesShort:["dom","lun","mar","mié","jue","vie","sáb"],dayNamesMin:["D","L","M","X","J","V","S"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("es",{buttonText:{month:"Mes",week:"Semana",day:"Día",list:"Agenda"},allDayHtml:"Todo<br/>el día",eventLimitText:"más"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),monthsParseExact:!0,weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] HH:mm",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] HH:mm",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] HH:mm",llll:"ddd, YYYY[ko] MMM D[a] HH:mm"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return a}(),a.fullCalendar.datepickerLang("eu","eu",{closeText:"Egina",prevText:"&#x3C;Aur",nextText:"Hur&#x3E;",currentText:"Gaur",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."],dayNames:["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"],dayNamesShort:["ig.","al.","ar.","az.","og.","ol.","lr."],dayNamesMin:["ig","al","ar","az","og","ol","lr"],weekHeader:"As",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("eu",{buttonText:{month:"Hilabetea",week:"Astea",day:"Eguna",list:"Agenda"},allDayHtml:"Egun<br/>osoa",eventLimitText:"gehiago"})}(),function(){!function(){"use strict";var a={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},c={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},d=(b.defineLocale||b.lang).call(b,"fa",{months:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysShort:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(a){return/بعد از ظهر/.test(a)},meridiem:function(a,b,c){return 12>a?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چندین ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(a){return a.replace(/[۰-۹]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},ordinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("fa","fa",{closeText:"بستن",prevText:"&#x3C;قبلی",nextText:"بعدی&#x3E;",currentText:"امروز",monthNames:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["يکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"],dayNamesShort:["ی","د","س","چ","پ","ج","ش"],dayNamesMin:["ی","د","س","چ","پ","ج","ش"],weekHeader:"هف",dateFormat:"yy/mm/dd",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fa",{buttonText:{month:"ماه",week:"هفته",day:"روز",list:"برنامه"},allDayText:"تمام روز",eventLimitText:function(a){return"بیش از "+a}})}(),function(){!function(){"use strict";function a(a,b,d,e){var f="";switch(d){case"s":return e?"muutaman sekunnin":"muutama sekunti";case"m":return e?"minuutin":"minuutti";case"mm":f=e?"minuutin":"minuuttia";break;case"h":return e?"tunnin":"tunti";case"hh":f=e?"tunnin":"tuntia";break;case"d":return e?"päivän":"päivä";case"dd":f=e?"päivän":"päivää";break;case"M":return e?"kuukauden":"kuukausi";case"MM":f=e?"kuukauden":"kuukautta";break;case"y":return e?"vuoden":"vuosi";case"yy":f=e?"vuoden":"vuotta"}return f=c(a,e)+" "+f}function c(a,b){return 10>a?b?e[a]:d[a]:a}var d="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),e=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",d[7],d[8],d[9]],f=(b.defineLocale||b.lang).call(b,"fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("fi","fi",{closeText:"Sulje",prevText:"&#xAB;Edellinen",nextText:"Seuraava&#xBB;",currentText:"Tänään",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"],dayNamesShort:["Su","Ma","Ti","Ke","To","Pe","La"],dayNames:["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],dayNamesMin:["Su","Ma","Ti","Ke","To","Pe","La"],weekHeader:"Vk",dateFormat:"d.m.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fi",{buttonText:{month:"Kuukausi",week:"Viikko",day:"Päivä",list:"Tapahtumat"},allDayText:"Koko päivä",eventLimitText:"lisää"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")}});return a}(),a.fullCalendar.datepickerLang("fr-ca","fr-CA",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ca",{buttonText:{year:"Année",month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr-ch","fr-CH",{closeText:"Fermer",prevText:"&#x3C;Préc",nextText:"Suiv&#x3E;",currentText:"Courant",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sm",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ch",{buttonText:{year:"Année",month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(a){return a+(1===a?"er":"")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr","fr",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",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."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr",{buttonText:{year:"Année",month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"gl",{months:"Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"),monthsShort:"Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"),monthsParseExact:!0,weekdays:"Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"),weekdaysShort:"Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"),weekdaysMin:"Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd D MMMM YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(1!==this.hours()?"ás":"á")+"] LT"},nextDay:function(){return"[mañá "+(1!==this.hours()?"ás":"á")+"] LT"},nextWeek:function(){return"dddd ["+(1!==this.hours()?"ás":"a")+"] LT"},lastDay:function(){return"[onte "+(1!==this.hours()?"á":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(1!==this.hours()?"ás":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(a){return"uns segundos"===a?"nuns segundos":"en "+a},past:"hai %s",s:"uns segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:7}});return a}(),a.fullCalendar.datepickerLang("gl","gl",{closeText:"Pechar",prevText:"&#x3C;Ant",nextText:"Seg&#x3E;",currentText:"Hoxe",monthNames:["Xaneiro","Febreiro","Marzo","Abril","Maio","Xuño","Xullo","Agosto","Setembro","Outubro","Novembro","Decembro"],monthNamesShort:["Xan","Feb","Mar","Abr","Mai","Xuñ","Xul","Ago","Set","Out","Nov","Dec"],dayNames:["Domingo","Luns","Martes","Mércores","Xoves","Venres","Sábado"],dayNamesShort:["Dom","Lun","Mar","Mér","Xov","Ven","Sáb"],dayNamesMin:["Do","Lu","Ma","Mé","Xo","Ve","Sá"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("gl",{buttonText:{month:"Mes",week:"Semana",day:"Día",list:"Axenda"},allDayHtml:"Todo<br/>o día",eventLimitText:"máis"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),weekdaysShort:"א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(a){return 2===a?"שעתיים":a+" שעות"},d:"יום",dd:function(a){return 2===a?"יומיים":a+" ימים"},M:"חודש",MM:function(a){return 2===a?"חודשיים":a+" חודשים"},y:"שנה",yy:function(a){return 2===a?"שנתיים":a%10===0&&10!==a?a+" שנה":a+" שנים"}},meridiemParse:/אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,isPM:function(a){return/^(אחה"צ|אחרי הצהריים|בערב)$/.test(a)},meridiem:function(a,b,c){return 5>a?"לפנות בוקר":10>a?"בבוקר":12>a?c?'לפנה"צ':"לפני הצהריים":18>a?c?'אחה"צ':"אחרי הצהריים":"בערב"}});return a}(),a.fullCalendar.datepickerLang("he","he",{closeText:"סגור",prevText:"&#x3C;הקודם",nextText:"הבא&#x3E;",currentText:"היום",monthNames:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthNamesShort:["ינו","פבר","מרץ","אפר","מאי","יוני","יולי","אוג","ספט","אוק","נוב","דצמ"],dayNames:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת"],dayNamesShort:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],dayNamesMin:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("he",{defaultButtonText:{month:"חודש",week:"שבוע",day:"יום",list:"סדר יום"},weekNumberTitle:"שבוע",allDayText:"כל היום",eventLimitText:"אחר"})}(),function(){!function(){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},d=(b.defineLocale||b.lang).call(b,"hi",{months:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),monthsParseExact:!0,weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(a,b){return 12===a&&(a=0),"रात"===b?4>a?a:a+12:"सुबह"===b?a:"दोपहर"===b?a>=10?a:a+12:"शाम"===b?a+12:void 0},meridiem:function(a,b,c){return 4>a?"रात":10>a?"सुबह":17>a?"दोपहर":20>a?"शाम":"रात"},week:{dow:0,doy:6}});return d}(),a.fullCalendar.datepickerLang("hi","hi",{closeText:"बंद",prevText:"पिछला",nextText:"अगला",currentText:"आज",monthNames:["जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून","जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर"],monthNamesShort:["जन","फर","मार्च","अप्रेल","मई","जून","जूलाई","अग","सित","अक्ट","नव","दि"],dayNames:["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],dayNamesShort:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],dayNamesMin:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],weekHeader:"हफ्ता",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hi",{buttonText:{month:"महीना",week:"सप्ताह",day:"दिन",list:"कार्यसूची"},allDayText:"सभी दिन",eventLimitText:function(a){return"+अधिक "+a}})}(),function(){!function(){"use strict";function a(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}var c=(b.defineLocale||b.lang).call(b,"hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:a,mm:a,h:a,hh:a,d:"dan",dd:a,M:"mjesec",MM:a,y:"godinu",yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("hr","hr",{closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],monthNamesShort:["Sij","Velj","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro"],dayNames:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Tje",dateFormat:"dd.mm.yy.",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hr",{buttonText:{month:"Mjesec",week:"Tjedan",day:"Dan",list:"Raspored"},allDayText:"Cijeli dan",eventLimitText:function(a){return"+ još "+a}})}(),function(){!function(){"use strict";function a(a,b,c,d){var e=a;switch(c){case"s":return d||b?"néhány másodperc":"néhány másodperce";case"m":return"egy"+(d||b?" perc":" perce");case"mm":return e+(d||b?" perc":" perce");case"h":return"egy"+(d||b?" óra":" órája");case"hh":return e+(d||b?" óra":" órája");case"d":return"egy"+(d||b?" nap":" napja");case"dd":return e+(d||b?" nap":" napja");case"M":return"egy"+(d||b?" hónap":" hónapja");case"MM":return e+(d||b?" hónap":" hónapja");case"y":return"egy"+(d||b?" év":" éve");case"yy":return e+(d||b?" év":" éve")}return""}function c(a){return(a?"":"[múlt] ")+"["+d[this.day()]+"] LT[-kor]"}var d="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" "),e=(b.defineLocale||b.lang).call(b,"hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(a){return"u"===a.charAt(1).toLowerCase()},meridiem:function(a,b,c){return 12>a?c===!0?"de":"DE":c===!0?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return c.call(this,!0)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return c.call(this,!1)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return e}(),a.fullCalendar.datepickerLang("hu","hu",{closeText:"bezár",prevText:"vissza",nextText:"előre",currentText:"ma",monthNames:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],monthNamesShort:["Jan","Feb","Már","Ápr","Máj","Jún","Júl","Aug","Szep","Okt","Nov","Dec"],dayNames:["Vasárnap","Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat"],dayNamesShort:["Vas","Hét","Ked","Sze","Csü","Pén","Szo"],dayNamesMin:["V","H","K","Sze","Cs","P","Szo"],weekHeader:"Hét",dateFormat:"yy.mm.dd.",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""}),a.fullCalendar.lang("hu",{buttonText:{month:"Hónap",week:"Hét",day:"Nap",list:"Napló"},allDayText:"Egész nap",eventLimitText:"további"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(a,b){return 12===a&&(a=0),"pagi"===b?a:"siang"===b?a>=11?a:a+12:"sore"===b||"malam"===b?a+12:void 0},meridiem:function(a,b,c){return 11>a?"pagi":15>a?"siang":19>a?"sore":"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}});return a}(),a.fullCalendar.datepickerLang("id","id",{closeText:"Tutup",prevText:"&#x3C;mundur",nextText:"maju&#x3E;",currentText:"hari ini",monthNames:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","Nopember","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agus","Sep","Okt","Nop","Des"],dayNames:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],dayNamesShort:["Min","Sen","Sel","Rab","kam","Jum","Sab"],dayNamesMin:["Mg","Sn","Sl","Rb","Km","jm","Sb"],weekHeader:"Mg",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("id",{buttonText:{month:"Bulan",week:"Minggu",day:"Hari",list:"Agenda"},allDayHtml:"Sehari<br/>penuh",eventLimitText:"lebih"})}(),function(){!function(){"use strict";function a(a){return a%100===11?!0:a%10!==1}function c(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"nokkrar sekúndur":"nokkrum sekúndum";case"m":return c?"mínúta":"mínútu";case"mm":return a(b)?f+(c||e?"mínútur":"mínútum"):c?f+"mínúta":f+"mínútu";case"hh":return a(b)?f+(c||e?"klukkustundir":"klukkustundum"):f+"klukkustund";case"d":return c?"dagur":e?"dag":"degi";case"dd":return a(b)?c?f+"dagar":f+(e?"daga":"dögum"):c?f+"dagur":f+(e?"dag":"degi");case"M":return c?"mánuður":e?"mánuð":"mánuði";case"MM":return a(b)?c?f+"mánuðir":f+(e?"mánuði":"mánuðum"):c?f+"mánuður":f+(e?"mánuð":"mánuði");case"y":return c||e?"ár":"ári";case"yy":return a(b)?f+(c||e?"ár":"árum"):f+(c||e?"ár":"ári")}}var d=(b.defineLocale||b.lang).call(b,"is",{months:"janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),monthsShort:"jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),weekdays:"sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),weekdaysShort:"sun_mán_þri_mið_fim_fös_lau".split("_"),weekdaysMin:"Su_Má_Þr_Mi_Fi_Fö_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[í dag kl.] LT",nextDay:"[á morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[í gær kl.] LT",lastWeek:"[síðasta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s síðan",s:c,m:c,mm:c,h:"klukkustund",hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("is","is",{closeText:"Loka",prevText:"&#x3C; Fyrri",nextText:"Næsti &#x3E;",currentText:"Í dag",monthNames:["Janúar","Febrúar","Mars","Apríl","Maí","Júní","Júlí","Ágúst","September","Október","Nóvember","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Maí","Jún","Júl","Ágú","Sep","Okt","Nóv","Des"],dayNames:["Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur"],dayNamesShort:["Sun","Mán","Þri","Mið","Fim","Fös","Lau"],dayNamesMin:["Su","Má","Þr","Mi","Fi","Fö","La"],weekHeader:"Vika",dateFormat:"dd.mm.yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("is",{buttonText:{month:"Mánuður",week:"Vika",day:"Dagur",list:"Dagskrá"},allDayHtml:"Allan<br/>daginn",eventLimitText:"meira"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),weekdaysShort:"Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),weekdaysMin:"Do_Lu_Ma_Me_Gi_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(a){return(/^[0-9].+$/.test(a)?"tra":"in")+" "+a},past:"%s fa",s:"alcuni secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("it","it",{closeText:"Chiudi",prevText:"&#x3C;Prec",nextText:"Succ&#x3E;",currentText:"Oggi",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"],dayNames:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],dayNamesShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],dayNamesMin:["Do","Lu","Ma","Me","Gi","Ve","Sa"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("it",{buttonText:{month:"Mese",week:"Settimana",day:"Giorno",list:"Agenda"},allDayHtml:"Tutto il<br/>giorno",eventLimitText:function(a){return"+altri "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ja",{months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"Ah時m分",LTS:"Ah時m分s秒",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah時m分",LLLL:"YYYY年M月D日Ah時m分 dddd"},meridiemParse:/午前|午後/i,isPM:function(a){return"午後"===a},meridiem:function(a,b,c){return 12>a?"午前":"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:"[来週]dddd LT",lastDay:"[昨日] LT",lastWeek:"[前週]dddd LT",sameElse:"L"},ordinalParse:/\d{1,2}日/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";default:return a}},relativeTime:{future:"%s後",past:"%s前",s:"数秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}});return a}(),a.fullCalendar.datepickerLang("ja","ja",{closeText:"閉じる",prevText:"&#x3C;前",nextText:"次&#x3E;",currentText:"今日",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月"],dayNames:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],dayNamesShort:["日","月","火","水","木","金","土"],dayNamesMin:["日","月","火","水","木","金","土"],weekHeader:"週",dateFormat:"yy/mm/dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),a.fullCalendar.lang("ja",{buttonText:{month:"月",week:"週",day:"日",list:"予定リスト"},allDayText:"終日",eventLimitText:function(a){return"他 "+a+" 件"}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ko",{months:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),monthsShort:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),weekdays:"일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),weekdaysShort:"일_월_화_수_목_금_토".split("_"),weekdaysMin:"일_월_화_수_목_금_토".split("_"),longDateFormat:{LT:"A h시 m분",LTS:"A h시 m분 s초",L:"YYYY.MM.DD",LL:"YYYY년 MMMM D일",LLL:"YYYY년 MMMM D일 A h시 m분",LLLL:"YYYY년 MMMM D일 dddd A h시 m분"},calendar:{sameDay:"오늘 LT",nextDay:"내일 LT",nextWeek:"dddd LT",lastDay:"어제 LT",lastWeek:"지난주 dddd LT",sameElse:"L"},relativeTime:{future:"%s 후",past:"%s 전",s:"몇 초",ss:"%d초",m:"일분",mm:"%d분",h:"한 시간",hh:"%d시간",d:"하루",dd:"%d일",M:"한 달",MM:"%d달",y:"일 년",yy:"%d년"},ordinalParse:/\d{1,2}일/,ordinal:"%d일",meridiemParse:/오전|오후/,isPM:function(a){return"오후"===a},meridiem:function(a,b,c){return 12>a?"오전":"오후"}});return a}(),a.fullCalendar.datepickerLang("ko","ko",{closeText:"닫기",prevText:"이전달",nextText:"다음달",currentText:"오늘",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월"],dayNames:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],dayNamesShort:["일","월","화","수","목","금","토"],dayNamesMin:["일","월","화","수","목","금","토"],weekHeader:"Wk",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"년"}),a.fullCalendar.lang("ko",{buttonText:{month:"월",week:"주",day:"일",list:"일정목록"},allDayText:"종일",eventLimitText:"개"})}(),function(){!function(){"use strict";function a(a,b,c,d){var e={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return b?e[c][0]:e[c][1]}function c(a){var b=a.substr(0,a.indexOf(" "));return e(b)?"a "+a:"an "+a}function d(a){var b=a.substr(0,a.indexOf(" "));return e(b)?"viru "+a:"virun "+a}function e(a){if(a=parseInt(a,10),isNaN(a))return!1;if(0>a)return!0;if(10>a)return a>=4&&7>=a;if(100>a){var b=a%10,c=a/10;return e(0===b?c:b)}if(1e4>a){for(;a>=10;)a/=10;return e(a)}return a/=1e3,e(a)}var f=(b.defineLocale||b.lang).call(b,"lb",{months:"Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mé_Dë_Më_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gëschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:c,past:d,s:"e puer Sekonnen",m:a,mm:"%d Minutten",h:a,hh:"%d Stonnen",d:a,dd:"%d Deeg",M:a,MM:"%d Méint",y:a,yy:"%d Joer"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("lb","lb",{closeText:"Fäerdeg",prevText:"Zréck",nextText:"Weider",currentText:"Haut",monthNames:["Januar","Februar","Mäerz","Abrëll","Mee","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mäe","Abr","Mee","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonndeg","Méindeg","Dënschdeg","Mëttwoch","Donneschdeg","Freideg","Samschdeg"],dayNamesShort:["Son","Méi","Dën","Mët","Don","Fre","Sam"],dayNamesMin:["So","Mé","Dë","Më","Do","Fr","Sa"],weekHeader:"W",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("lb",{buttonText:{month:"Mount",week:"Woch",day:"Dag",list:"Terminiwwersiicht"},allDayText:"Ganzen Dag",eventLimitText:"méi"})}(),function(){!function(){"use strict";function a(a,b,c,d){return b?"kelios sekundės":d?"kelių sekundžių":"kelias sekundes"}function c(a,b,c,d){return b?e(c)[0]:d?e(c)[1]:e(c)[2]}function d(a){return a%10===0||a>10&&20>a}function e(a){return g[a].split("_")}function f(a,b,f,g){var h=a+" ";return 1===a?h+c(a,b,f[0],g):b?h+(d(a)?e(f)[1]:e(f)[0]):g?h+e(f)[1]:h+(d(a)?e(f)[1]:e(f)[2])}var g={m:"minutė_minutės_minutę",mm:"minutės_minučių_minutes",h:"valanda_valandos_valandą",hh:"valandos_valandų_valandas",d:"diena_dienos_dieną",dd:"dienos_dienų_dienas",M:"mėnuo_mėnesio_mėnesį",MM:"mėnesiai_mėnesių_mėnesius",y:"metai_metų_metus",yy:"metai_metų_metus"},h=(b.defineLocale||b.lang).call(b,"lt",{months:{format:"sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis".split("_")},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),weekdaysMin:"S_P_A_T_K_Pn_Š".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[Šiandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Praėjusį] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prieš %s",s:a,m:c,mm:f,h:c,hh:f,d:c,dd:f,M:c,MM:f,y:c,yy:f},ordinalParse:/\d{1,2}-oji/,ordinal:function(a){return a+"-oji"},week:{dow:1,doy:4}});return h}(),a.fullCalendar.datepickerLang("lt","lt",{closeText:"Uždaryti",prevText:"&#x3C;Atgal",nextText:"Pirmyn&#x3E;",currentText:"Šiandien",monthNames:["Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis","Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis"],monthNamesShort:["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rugp","Rugs","Spa","Lap","Gru"],dayNames:["sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis"],dayNamesShort:["sek","pir","ant","tre","ket","pen","šeš"],dayNamesMin:["Se","Pr","An","Tr","Ke","Pe","Še"],weekHeader:"SAV",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""}),a.fullCalendar.lang("lt",{buttonText:{month:"Mėnuo",week:"Savaitė",day:"Diena",list:"Darbotvarkė"},allDayText:"Visą dieną",eventLimitText:"daugiau"})}(),function(){!function(){"use strict";function a(a,b,c){return c?b%10===1&&11!==b?a[2]:a[3]:b%10===1&&11!==b?a[0]:a[1]}function c(b,c,d){return b+" "+a(f[d],b,c)}function d(b,c,d){return a(f[d],b,c)}function e(a,b){return b?"dažas sekundes":"dažām sekundēm"}var f={m:"minūtes_minūtēm_minūte_minūtes".split("_"),mm:"minūtes_minūtēm_minūte_minūtes".split("_"),h:"stundas_stundām_stunda_stundas".split("_"),hh:"stundas_stundām_stunda_stundas".split("_"),d:"dienas_dienām_diena_dienas".split("_"),dd:"dienas_dienām_diena_dienas".split("_"),M:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),MM:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")},g=(b.defineLocale||b.lang).call(b,"lv",{months:"janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),weekdays:"svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[Šodien pulksten] LT",nextDay:"[Rīt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pagājušā] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"pēc %s",past:"pirms %s",s:e,m:d,mm:c,h:d,hh:c,d:d,dd:c,M:d,MM:c,y:d,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return g}(),a.fullCalendar.datepickerLang("lv","lv",{closeText:"Aizvērt",prevText:"Iepr.",nextText:"Nāk.",currentText:"Šodien",monthNames:["Janvāris","Februāris","Marts","Aprīlis","Maijs","Jūnijs","Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris"],monthNamesShort:["Jan","Feb","Mar","Apr","Mai","Jūn","Jūl","Aug","Sep","Okt","Nov","Dec"],dayNames:["svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena"],dayNamesShort:["svt","prm","otr","tre","ctr","pkt","sst"],dayNamesMin:["Sv","Pr","Ot","Tr","Ct","Pk","Ss"],weekHeader:"Ned.",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("lv",{buttonText:{month:"Mēnesis",week:"Nedēļa",day:"Diena",list:"Dienas kārtība"},allDayText:"Visu dienu",eventLimitText:function(a){return"+vēl "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:!0,weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"sø._ma._ti._on._to._fr._lø.".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",M:"en måned",MM:"%d måneder",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("nb","nb",{closeText:"Lukk",prevText:"&#xAB;Forrige",nextText:"Neste&#xBB;",currentText:"I dag",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"],dayNamesShort:["søn","man","tir","ons","tor","fre","lør"],dayNames:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],dayNamesMin:["sø","ma","ti","on","to","fr","lø"],weekHeader:"Uke",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("nb",{buttonText:{month:"Måned",week:"Uke",day:"Dag",list:"Agenda"},allDayText:"Hele dagen",eventLimitText:"til"})}(),function(){!function(){"use strict";var a="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),c="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),d=(b.defineLocale||b.lang).call(b,"nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(b,d){return/-MMM-/.test(d)?c[b.month()]:a[b.month()]},monthsParseExact:!0,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"Zo_Ma_Di_Wo_Do_Vr_Za".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(a){return a+(1===a||8===a||a>=20?"ste":"de")},week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("nl","nl",{closeText:"Sluiten",prevText:"←",nextText:"→",currentText:"Vandaag",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"],dayNames:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],dayNamesShort:["zon","maa","din","woe","don","vri","zat"],dayNamesMin:["zo","ma","di","wo","do","vr","za"],weekHeader:"Wk",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("nl",{buttonText:{month:"Maand",week:"Week",day:"Dag",list:"Agenda"},allDayText:"Hele dag",eventLimitText:"extra"})}(),function(){!function(){"use strict";function a(a){return 5>a%10&&a%10>1&&~~(a/10)%10!==1}function c(b,c,d){var e=b+" ";switch(d){case"m":return c?"minuta":"minutę";case"mm":return e+(a(b)?"minuty":"minut");case"h":return c?"godzina":"godzinę";case"hh":return e+(a(b)?"godziny":"godzin");case"MM":return e+(a(b)?"miesiące":"miesięcy");case"yy":return e+(a(b)?"lata":"lat")}}var d="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),e="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"),f=(b.defineLocale||b.lang).call(b,"pl",{months:function(a,b){return""===b?"("+e[a.month()]+"|"+d[a.month()]+")":/D MMMM/.test(b)?e[a.month()]:d[a.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"nie_pon_wt_śr_czw_pt_sb".split("_"),weekdaysMin:"Nd_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:"[W] dddd [o] LT",lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",m:c,mm:c,h:c,hh:c,d:"1 dzień",dd:"%d dni",M:"miesiąc",MM:c,y:"rok",yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("pl","pl",{closeText:"Zamknij",prevText:"&#x3C;Poprzedni",nextText:"Następny&#x3E;",currentText:"Dziś",monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lu","Mar","Kw","Maj","Cze","Lip","Sie","Wrz","Pa","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Nie","Pn","Wt","Śr","Czw","Pt","So"],dayNamesMin:["N","Pn","Wt","Śr","Cz","Pt","So"],weekHeader:"Tydz",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("pl",{buttonText:{month:"Miesiąc",week:"Tydzień",day:"Dzień",list:"Plan dnia"},allDayText:"Cały dzień",eventLimitText:"więcej"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"pt-br",{months:"Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [às] HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"%s atrás",s:"poucos segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº"});return a}(),a.fullCalendar.datepickerLang("pt-br","pt-BR",{closeText:"Fechar",prevText:"&#x3C;Anterior",nextText:"Próximo&#x3E;",currentText:"Hoje",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"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("pt-br",{buttonText:{month:"Mês",week:"Semana",day:"Dia",list:"Compromissos"},allDayText:"dia inteiro",eventLimitText:function(a){return"mais +"+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"pt",{months:"Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingo_Segunda-Feira_Terça-Feira_Quarta-Feira_Quinta-Feira_Sexta-Feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return 0===this.day()||6===this.day()?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("pt","pt",{closeText:"Fechar",prevText:"Anterior",nextText:"Seguinte",currentText:"Hoje",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"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sem",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("pt",{buttonText:{month:"Mês",week:"Semana",day:"Dia",list:"Agenda"},allDayText:"Todo o dia",eventLimitText:"mais"})}(),function(){!function(){"use strict";function a(a,b,c){var d={mm:"minute",hh:"ore",dd:"zile",MM:"luni",yy:"ani"},e=" ";return(a%100>=20||a>=100&&a%100===0)&&(e=" de "),a+e+d[c]}var c=(b.defineLocale||b.lang).call(b,"ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[mâine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s în urmă",s:"câteva secunde",m:"un minut",mm:a,h:"o oră",hh:a,d:"o zi",dd:a,M:"o lună",MM:a,y:"un an",yy:a},week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("ro","ro",{closeText:"Închide",prevText:"&#xAB; Luna precedentă",nextText:"Luna următoare &#xBB;",currentText:"Azi",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"],dayNames:["Duminică","Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă"],dayNamesShort:["Dum","Lun","Mar","Mie","Joi","Vin","Sâm"],dayNamesMin:["Du","Lu","Ma","Mi","Jo","Vi","Sâ"],weekHeader:"Săpt",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ro",{buttonText:{prev:"precedentă",next:"următoare",month:"Lună",week:"Săptămână",day:"Zi",list:"Agendă"},allDayText:"Toată ziua",eventLimitText:function(a){return"+alte "+a}})}(),function(){!function(){"use strict";function a(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(b,c,d){var e={mm:c?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};return"m"===d?c?"минута":"минуту":b+" "+a(e[d],+b)}var d=[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[йя]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],e=(b.defineLocale||b.lang).call(b,"ru",{months:{format:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_"),standalone:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_")},monthsShort:{format:"янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.".split("_"),standalone:"янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.".split("_")},weekdays:{standalone:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),format:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_"),isFormat:/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/},weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:d,longMonthsParse:d,shortMonthsParse:d,monthsRegex:/^(сентябр[яь]|октябр[яь]|декабр[яь]|феврал[яь]|январ[яь]|апрел[яь]|августа?|ноябр[яь]|сент\.|февр\.|нояб\.|июнь|янв.|июль|дек.|авг.|апр.|марта|мар[.т]|окт.|июн[яь]|июл[яь]|ма[яй])/i,monthsShortRegex:/^(сентябр[яь]|октябр[яь]|декабр[яь]|феврал[яь]|январ[яь]|апрел[яь]|августа?|ноябр[яь]|сент\.|февр\.|нояб\.|июнь|янв.|июль|дек.|авг.|апр.|марта|мар[.т]|окт.|июн[яь]|июл[яь]|ма[яй])/i,monthsStrictRegex:/^(сентябр[яь]|октябр[яь]|декабр[яь]|феврал[яь]|январ[яь]|апрел[яь]|августа?|ноябр[яь]|марта?|июн[яь]|июл[яь]|ма[яй])/i,monthsShortStrictRegex:/^(нояб\.|февр\.|сент\.|июль|янв\.|июн[яь]|мар[.т]|авг\.|апр\.|окт\.|дек\.|ма[яй])/i,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сегодня в] LT",nextDay:"[Завтра в] LT",lastDay:"[Вчера в] LT",nextWeek:function(a){if(a.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В следующее] dddd [в] LT";case 1:case 2:case 4:return"[В следующий] dddd [в] LT";case 3:case 5:case 6:return"[В следующую] dddd [в] LT"}},lastWeek:function(a){if(a.week()===this.week())return 2===this.day()?"[Во] dddd [в] LT":"[В] dddd [в] LT";switch(this.day()){case 0:return"[В прошлое] dddd [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",m:c,mm:c,h:"час",hh:c,d:"день",dd:c,M:"месяц",MM:c,y:"год",yy:c},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(a){return/^(дня|вечера)$/.test(a)},meridiem:function(a,b,c){return 4>a?"ночи":12>a?"утра":17>a?"дня":"вечера"},ordinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":return a+"-й";case"D":return a+"-го";case"w":case"W":return a+"-я";default:return a}},week:{dow:1,doy:7}});return e}(),a.fullCalendar.datepickerLang("ru","ru",{closeText:"Закрыть",prevText:"&#x3C;Пред",nextText:"След&#x3E;",currentText:"Сегодня",monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],dayNamesMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Нед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ru",{buttonText:{month:"Месяц",week:"Неделя",day:"День",list:"Повестка дня"},allDayText:"Весь день",eventLimitText:function(a){return"+ ещё "+a}})}(),function(){!function(){"use strict";function a(a){return a>1&&5>a}function c(b,c,d,e){var f=b+" ";switch(d){case"s":return c||e?"pár sekúnd":"pár sekundami";case"m":return c?"minúta":e?"minútu":"minútou";case"mm":return c||e?f+(a(b)?"minúty":"minút"):f+"minútami";case"h":return c?"hodina":e?"hodinu":"hodinou";case"hh":return c||e?f+(a(b)?"hodiny":"hodín"):f+"hodinami";case"d":return c||e?"deň":"dňom";case"dd":return c||e?f+(a(b)?"dni":"dní"):f+"dňami";case"M":return c||e?"mesiac":"mesiacom";case"MM":return c||e?f+(a(b)?"mesiace":"mesiacov"):f+"mesiacmi";case"y":return c||e?"rok":"rokom";case"yy":return c||e?f+(a(b)?"roky":"rokov"):f+"rokmi"}}var d="január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),e="jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"),f=(b.defineLocale||b.lang).call(b,"sk",{months:d,monthsShort:e,weekdays:"nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_št_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_št_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nedeľu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo štvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[včera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulú nedeľu o] LT";case 1:case 2:return"[minulý] dddd [o] LT";case 3:return"[minulú stredu o] LT";case 4:case 5:return"[minulý] dddd [o] LT";case 6:return"[minulú sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f}(),a.fullCalendar.datepickerLang("sk","sk",{closeText:"Zavrieť",prevText:"&#x3C;Predchádzajúci",nextText:"Nasledujúci&#x3E;",currentText:"Dnes",monthNames:["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december"],monthNamesShort:["Jan","Feb","Mar","Apr","Máj","Jún","Júl","Aug","Sep","Okt","Nov","Dec"],dayNames:["nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota"],dayNamesShort:["Ned","Pon","Uto","Str","Štv","Pia","Sob"],dayNamesMin:["Ne","Po","Ut","St","Št","Pia","So"],weekHeader:"Ty",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sk",{buttonText:{month:"Mesiac",week:"Týždeň",day:"Deň",list:"Rozvrh"},allDayText:"Celý deň",eventLimitText:function(a){return"+ďalšie: "+a}})}(),function(){!function(){"use strict";function a(a,b,c,d){var e=a+" ";switch(c){case"s":return b||d?"nekaj sekund":"nekaj sekundami";case"m":return b?"ena minuta":"eno minuto";case"mm":return e+=1===a?b?"minuta":"minuto":2===a?b||d?"minuti":"minutama":5>a?b||d?"minute":"minutami":b||d?"minut":"minutami";case"h":return b?"ena ura":"eno uro";case"hh":return e+=1===a?b?"ura":"uro":2===a?b||d?"uri":"urama":5>a?b||d?"ure":"urami":b||d?"ur":"urami";case"d":return b||d?"en dan":"enim dnem";case"dd":return e+=1===a?b||d?"dan":"dnem":2===a?b||d?"dni":"dnevoma":b||d?"dni":"dnevi";case"M":return b||d?"en mesec":"enim mesecem";case"MM":return e+=1===a?b||d?"mesec":"mesecem":2===a?b||d?"meseca":"mesecema":5>a?b||d?"mesece":"meseci":b||d?"mesecev":"meseci";case"y":return b||d?"eno leto":"enim letom";case"yy":return e+=1===a?b||d?"leto":"letom":2===a?b||d?"leti":"letoma":5>a?b||d?"leta":"leti":b||d?"let":"leti"}}var c=(b.defineLocale||b.lang).call(b,"sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._čet._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_če_pe_so".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[včeraj ob] LT",lastWeek:function(){
+switch(this.day()){case 0:return"[prejšnjo] [nedeljo] [ob] LT";case 3:return"[prejšnjo] [sredo] [ob] LT";case 6:return"[prejšnjo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prejšnji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"čez %s",past:"pred %s",s:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("sl","sl",{closeText:"Zapri",prevText:"&#x3C;Prejšnji",nextText:"Naslednji&#x3E;",currentText:"Trenutni",monthNames:["Januar","Februar","Marec","April","Maj","Junij","Julij","Avgust","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Avg","Sep","Okt","Nov","Dec"],dayNames:["Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota"],dayNamesShort:["Ned","Pon","Tor","Sre","Čet","Pet","Sob"],dayNamesMin:["Ne","Po","To","Sr","Če","Pe","So"],weekHeader:"Teden",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sl",{buttonText:{month:"Mesec",week:"Teden",day:"Dan",list:"Dnevni red"},allDayText:"Ves dan",eventLimitText:"več"})}(),function(){!function(){"use strict";var a={words:{m:["један минут","једне минуте"],mm:["минут","минуте","минута"],h:["један сат","једног сата"],hh:["сат","сата","сати"],dd:["дан","дана","дана"],MM:["месец","месеца","месеци"],yy:["година","године","година"]},correctGrammaticalCase:function(a,b){return 1===a?b[0]:a>=2&&4>=a?b[1]:b[2]},translate:function(b,c,d){var e=a.words[d];return 1===d.length?c?e[0]:e[1]:b+" "+a.correctGrammaticalCase(b,e)}},c=(b.defineLocale||b.lang).call(b,"sr-cyrl",{months:"јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар".split("_"),monthsShort:"јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.".split("_"),monthsParseExact:!0,weekdays:"недеља_понедељак_уторак_среда_четвртак_петак_субота".split("_"),weekdaysShort:"нед._пон._уто._сре._чет._пет._суб.".split("_"),weekdaysMin:"не_по_ут_ср_че_пе_су".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[данас у] LT",nextDay:"[сутра у] LT",nextWeek:function(){switch(this.day()){case 0:return"[у] [недељу] [у] LT";case 3:return"[у] [среду] [у] LT";case 6:return"[у] [суботу] [у] LT";case 1:case 2:case 4:case 5:return"[у] dddd [у] LT"}},lastDay:"[јуче у] LT",lastWeek:function(){var a=["[прошле] [недеље] [у] LT","[прошлог] [понедељка] [у] LT","[прошлог] [уторка] [у] LT","[прошле] [среде] [у] LT","[прошлог] [четвртка] [у] LT","[прошлог] [петка] [у] LT","[прошле] [суботе] [у] LT"];return a[this.day()]},sameElse:"L"},relativeTime:{future:"за %s",past:"пре %s",s:"неколико секунди",m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:"дан",dd:a.translate,M:"месец",MM:a.translate,y:"годину",yy:a.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("sr-cyrl","sr",{closeText:"Затвори",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Данас",monthNames:["Јануар","Фебруар","Март","Април","Мај","Јун","Јул","Август","Септембар","Октобар","Новембар","Децембар"],monthNamesShort:["Јан","Феб","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Нов","Дец"],dayNames:["Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота"],dayNamesShort:["Нед","Пон","Уто","Сре","Чет","Пет","Суб"],dayNamesMin:["Не","По","Ут","Ср","Че","Пе","Су"],weekHeader:"Сед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sr-cyrl",{buttonText:{month:"Месец",week:"Недеља",day:"Дан",list:"Планер"},allDayText:"Цео дан",eventLimitText:function(a){return"+ још "+a}})}(),function(){!function(){"use strict";var a={words:{m:["jedan minut","jedne minute"],mm:["minut","minute","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mesec","meseca","meseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(a,b){return 1===a?b[0]:a>=2&&4>=a?b[1]:b[2]},translate:function(b,c,d){var e=a.words[d];return 1===d.length?c?e[0]:e[1]:b+" "+a.correctGrammaticalCase(b,e)}},c=(b.defineLocale||b.lang).call(b,"sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var a=["[prošle] [nedelje] [u] LT","[prošlog] [ponedeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return a[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",m:a.translate,mm:a.translate,h:a.translate,hh:a.translate,d:"dan",dd:a.translate,M:"mesec",MM:a.translate,y:"godinu",yy:a.translate},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("sr","sr",{closeText:"Затвори",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Данас",monthNames:["Јануар","Фебруар","Март","Април","Мај","Јун","Јул","Август","Септембар","Октобар","Новембар","Децембар"],monthNamesShort:["Јан","Феб","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Нов","Дец"],dayNames:["Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота"],dayNamesShort:["Нед","Пон","Уто","Сре","Чет","Пет","Суб"],dayNamesMin:["Не","По","Ут","Ср","Че","Пе","Су"],weekHeader:"Сед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sr",{buttonText:{month:"Месец",week:"Недеља",day:"Дан",list:"Планер"},allDayText:"Цео дан",eventLimitText:function(a){return"+ још "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"[På] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},ordinalParse:/\d{1,2}(e|a)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"e":1===b?"a":2===b?"a":"e";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("sv","sv",{closeText:"Stäng",prevText:"&#xAB;Förra",nextText:"Nästa&#xBB;",currentText:"Idag",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"],dayNamesShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],dayNames:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],dayNamesMin:["Sö","Må","Ti","On","To","Fr","Lö"],weekHeader:"Ve",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("sv",{buttonText:{month:"Månad",week:"Vecka",day:"Dag",list:"Program"},allDayText:"Heldag",eventLimitText:"till"})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),monthsParseExact:!0,weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H นาฬิกา m นาที",LTS:"H นาฬิกา m นาที s วินาที",L:"YYYY/MM/DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา H นาฬิกา m นาที",LLLL:"วันddddที่ D MMMM YYYY เวลา H นาฬิกา m นาที"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(a){return"หลังเที่ยง"===a},meridiem:function(a,b,c){return 12>a?"ก่อนเที่ยง":"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}});return a}(),a.fullCalendar.datepickerLang("th","th",{closeText:"ปิด",prevText:"&#xAB;&#xA0;ย้อน",nextText:"ถัดไป&#xA0;&#xBB;",currentText:"วันนี้",monthNames:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthNamesShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],dayNames:["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"],dayNamesShort:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],dayNamesMin:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("th",{buttonText:{month:"เดือน",week:"สัปดาห์",day:"วัน",list:"แผนงาน"},allDayText:"ตลอดวัน",eventLimitText:"เพิ่มเติม"})}(),function(){!function(){"use strict";var a={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"},c=(b.defineLocale||b.lang).call(b,"tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[haftaya] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen hafta] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinalParse:/\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,ordinal:function(b){if(0===b)return b+"'ıncı";var c=b%10,d=b%100-c,e=b>=100?100:null;return b+(a[c]||a[d]||a[e])},week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("tr","tr",{closeText:"kapat",prevText:"&#x3C;geri",nextText:"ileri&#x3e",currentText:"bugün",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"],dayNames:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],dayNamesShort:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],dayNamesMin:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],weekHeader:"Hf",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("tr",{buttonText:{next:"ileri",month:"Ay",week:"Hafta",day:"Gün",list:"Ajanda"},allDayText:"Tüm gün",eventLimitText:"daha fazla"})}(),function(){!function(){"use strict";function a(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?c[1]:c[2]}function c(b,c,d){var e={mm:c?"хвилина_хвилини_хвилин":"хвилину_хвилини_хвилин",hh:c?"година_години_годин":"годину_години_годин",dd:"день_дні_днів",MM:"місяць_місяці_місяців",yy:"рік_роки_років"};return"m"===d?c?"хвилина":"хвилину":"h"===d?c?"година":"годину":b+" "+a(e[d],+b)}function d(a,b){var c={nominative:"неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота".split("_"),accusative:"неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу".split("_"),genitive:"неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи".split("_")},d=/(\[[ВвУу]\]) ?dddd/.test(b)?"accusative":/\[?(?:минулої|наступної)? ?\] ?dddd/.test(b)?"genitive":"nominative";return c[d][a.day()]}function e(a){return function(){return a+"о"+(11===this.hours()?"б":"")+"] LT"}}var f=(b.defineLocale||b.lang).call(b,"uk",{months:{format:"січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня".split("_"),standalone:"січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень".split("_")},monthsShort:"січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),weekdays:d,weekdaysShort:"нд_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY р.",LLL:"D MMMM YYYY р., HH:mm",LLLL:"dddd, D MMMM YYYY р., HH:mm"},calendar:{sameDay:e("[Сьогодні "),nextDay:e("[Завтра "),lastDay:e("[Вчора "),nextWeek:e("[У] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return e("[Минулої] dddd [").call(this);case 1:case 2:case 4:return e("[Минулого] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"за %s",past:"%s тому",s:"декілька секунд",m:c,mm:c,h:"годину",hh:c,d:"день",dd:c,M:"місяць",MM:c,y:"рік",yy:c},meridiemParse:/ночі|ранку|дня|вечора/,isPM:function(a){return/^(дня|вечора)$/.test(a)},meridiem:function(a,b,c){return 4>a?"ночі":12>a?"ранку":17>a?"дня":"вечора"},ordinalParse:/\d{1,2}-(й|го)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":case"w":case"W":return a+"-й";case"D":return a+"-го";default:return a}},week:{dow:1,doy:7}});return f}(),a.fullCalendar.datepickerLang("uk","uk",{closeText:"Закрити",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Сьогодні",monthNames:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthNamesShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],dayNames:["неділя","понеділок","вівторок","середа","четвер","п’ятниця","субота"],dayNamesShort:["нед","пнд","вів","срд","чтв","птн","сбт"],dayNamesMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Тиж",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("uk",{buttonText:{month:"Місяць",week:"Тиждень",day:"День",list:"Порядок денний"},allDayText:"Увесь день",eventLimitText:function(a){return"+ще "+a+"..."}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"vi",{months:"tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),monthsShort:"Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),monthsParseExact:!0,weekdays:"chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:!0,meridiemParse:/sa|ch/i,isPM:function(a){return/^ch$/i.test(a)},meridiem:function(a,b,c){return 12>a?c?"sa":"SA":c?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [năm] YYYY",LLL:"D MMMM [năm] YYYY HH:mm",LLLL:"dddd, D MMMM [năm] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[Hôm nay lúc] LT",nextDay:"[Ngày mai lúc] LT",nextWeek:"dddd [tuần tới lúc] LT",lastDay:"[Hôm qua lúc] LT",lastWeek:"dddd [tuần rồi lúc] LT",sameElse:"L"},relativeTime:{future:"%s tới",past:"%s trước",s:"vài giây",m:"một phút",mm:"%d phút",h:"một giờ",hh:"%d giờ",d:"một ngày",dd:"%d ngày",M:"một tháng",MM:"%d tháng",y:"một năm",yy:"%d năm"},ordinalParse:/\d{1,2}/,ordinal:function(a){return a},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("vi","vi",{closeText:"Đóng",prevText:"&#x3C;Trước",nextText:"Tiếp&#x3E;",currentText:"Hôm nay",monthNames:["Tháng Một","Tháng Hai","Tháng Ba","Tháng Tư","Tháng Năm","Tháng Sáu","Tháng Bảy","Tháng Tám","Tháng Chín","Tháng Mười","Tháng Mười Một","Tháng Mười Hai"],monthNamesShort:["Tháng 1","Tháng 2","Tháng 3","Tháng 4","Tháng 5","Tháng 6","Tháng 7","Tháng 8","Tháng 9","Tháng 10","Tháng 11","Tháng 12"],dayNames:["Chủ Nhật","Thứ Hai","Thứ Ba","Thứ Tư","Thứ Năm","Thứ Sáu","Thứ Bảy"],dayNamesShort:["CN","T2","T3","T4","T5","T6","T7"],dayNamesMin:["CN","T2","T3","T4","T5","T6","T7"],weekHeader:"Tu",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("vi",{buttonText:{month:"Tháng",week:"Tuần",day:"Ngày",list:"Lịch biểu"},allDayText:"Cả ngày",eventLimitText:function(a){return"+ thêm "+a}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm分",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah点mm分",LLLL:"YYYY年MMMD日ddddAh点mm分",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah点mm分",llll:"YYYY年MMMD日ddddAh点mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"下午"===b||"晚上"===b?a+12:a>=11?a:a+12},meridiem:function(a,b,c){var d=100*a+b;return 600>d?"凌晨":900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var a,c;return a=b().startOf("week"),c=this.diff(a,"days")>=7?"[下]":"[本]",0===this.minutes()?c+"dddAh点整":c+"dddAh点mm"},lastWeek:function(){var a,c;return a=b().startOf("week"),c=this.unix()<a.unix()?"[上]":"[本]",0===this.minutes()?c+"dddAh点整":c+"dddAh点mm"},sameElse:"LL"},ordinalParse:/\d{1,2}(日|月|周)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"周";default:return a}},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("zh-cn","zh-CN",{closeText:"关闭",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),a.fullCalendar.lang("zh-cn",{buttonText:{month:"月",week:"周",day:"日",list:"日程"},allDayText:"全天",eventLimitText:function(a){return"另外 "+a+" 个"}})}(),function(){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah點mm分",LTS:"Ah點m分s秒",L:"YYYY年MMMD日",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah點mm分",LLLL:"YYYY年MMMD日ddddAh點mm分",l:"YYYY年MMMD日",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah點mm分",llll:"YYYY年MMMD日ddddAh點mm分"},meridiemParse:/早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"早上"===b||"上午"===b?a:"中午"===b?a>=11?a:a+12:"下午"===b||"晚上"===b?a+12:void 0},meridiem:function(a,b,c){var d=100*a+b;return 900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"週";default:return a}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1分鐘",mm:"%d分鐘",h:"1小時",hh:"%d小時",d:"1天",dd:"%d天",M:"1個月",MM:"%d個月",y:"1年",yy:"%d年"}});return a}(),a.fullCalendar.datepickerLang("zh-tw","zh-TW",{closeText:"關閉",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy/mm/dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"}),a.fullCalendar.lang("zh-tw",{buttonText:{month:"月",week:"週",day:"天",list:"待辦事項"},allDayText:"全天",eventLimitText:"更多"})}(),(b.locale||b.lang).call(b,"en"),a.fullCalendar.lang("en"),a.datepicker&&a.datepicker.setDefaults(a.datepicker.regional[""])}); \ No newline at end of file
diff --git a/library/moment/CHANGELOG.md b/library/moment/CHANGELOG.md
index cc0e7f571..433fa857e 100644
--- a/library/moment/CHANGELOG.md
+++ b/library/moment/CHANGELOG.md
@@ -1,6 +1,27 @@
Changelog
=========
+### 2.13.0 [See full changelog](https://gist.github.com/ichernev/0132fcf5b61f7fc140b0bb0090480d49)
+
+## Enhancements:
+* [#2982](https://github.com/moment/moment/pull/2982) Add 'date' as alias to 'day' for startOf() and endOf().
+* [#2955](https://github.com/moment/moment/pull/2955) Add parsing negative components in durations when ISO 8601
+* [#2991](https://github.com/moment/moment/pull/2991) isBetween support for both open and closed intervals
+* [#3105](https://github.com/moment/moment/pull/3105) Add localeSorted argument to weekday listers
+* [#3102](https://github.com/moment/moment/pull/3102) Add k and kk formatting tokens
+
+## Bugfixes
+* [#3109](https://github.com/moment/moment/pull/3109) Fix [#1756](https://github.com/moment/moment/issues/1756) Resolved thread-safe issue on server side.
+* [#3078](https://github.com/moment/moment/pull/3078) Fix parsing for months/weekdays with weird characters
+* [#3098](https://github.com/moment/moment/pull/3098) Use Z suffix when in UTC mode ([#3020](https://github.com/moment/moment/issues/3020))
+* [#2995](https://github.com/moment/moment/pull/2995) Fix floating point rounding errors in durations
+* [#3059](https://github.com/moment/moment/pull/3059) fix bug where diff returns -0 in month-related diffs
+* [#3045](https://github.com/moment/moment/pull/3045) Fix mistaking any input for 'a' token
+* [#2877](https://github.com/moment/moment/pull/2877) Use explicit .valueOf() calls instead of coercion
+* [#3036](https://github.com/moment/moment/pull/3036) Year setter should keep time when DST changes
+
+Plus 3 new locales and locale fixes.
+
### 2.12.0 [See full changelog](https://gist.github.com/ichernev/6e5bfdf8d6522fc4ac73)
## Enhancements:
diff --git a/library/moment/README.md b/library/moment/README.md
index 6193e5eb8..c45e9d624 100644
--- a/library/moment/README.md
+++ b/library/moment/README.md
@@ -5,7 +5,7 @@
A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
-## [Documentation](http://momentjs.com/docs/)
+**[Documentation](http://momentjs.com/docs/)**
## Port to ECMAScript 6 (version 2.10.0)
diff --git a/library/moment/moment.js b/library/moment/moment.js
index b5f0b3644..ed94e44a1 100644
--- a/library/moment/moment.js
+++ b/library/moment/moment.js
@@ -1,5 +1,5 @@
//! moment.js
-//! version : 2.12.0
+//! version : 2.13.0
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
@@ -76,7 +76,9 @@
invalidMonth : null,
invalidFormat : false,
userInvalidated : false,
- iso : false
+ iso : false,
+ parsedDateParts : [],
+ meridiem : null
};
}
@@ -87,9 +89,30 @@
return m._pf;
}
+ var some;
+ if (Array.prototype.some) {
+ some = Array.prototype.some;
+ } else {
+ some = function (fun) {
+ var t = Object(this);
+ var len = t.length >>> 0;
+
+ for (var i = 0; i < len; i++) {
+ if (i in t && fun.call(this, t[i], i, t)) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+ }
+
function valid__isValid(m) {
if (m._isValid == null) {
var flags = getParsingFlags(m);
+ var parsedParts = some.call(flags.parsedDateParts, function (i) {
+ return i != null;
+ });
m._isValid = !isNaN(m._d.getTime()) &&
flags.overflow < 0 &&
!flags.empty &&
@@ -97,7 +120,8 @@
!flags.invalidWeekday &&
!flags.nullInput &&
!flags.invalidFormat &&
- !flags.userInvalidated;
+ !flags.userInvalidated &&
+ (!flags.meridiem || (flags.meridiem && parsedParts));
if (m._strict) {
m._isValid = m._isValid &&
@@ -240,6 +264,9 @@
var firstTime = true;
return extend(function () {
+ if (utils_hooks__hooks.deprecationHandler != null) {
+ utils_hooks__hooks.deprecationHandler(null, msg);
+ }
if (firstTime) {
warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack);
firstTime = false;
@@ -251,6 +278,9 @@
var deprecations = {};
function deprecateSimple(name, msg) {
+ if (utils_hooks__hooks.deprecationHandler != null) {
+ utils_hooks__hooks.deprecationHandler(name, msg);
+ }
if (!deprecations[name]) {
warn(msg);
deprecations[name] = true;
@@ -258,6 +288,7 @@
}
utils_hooks__hooks.suppressDeprecationWarnings = false;
+ utils_hooks__hooks.deprecationHandler = null;
function isFunction(input) {
return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
@@ -307,6 +338,22 @@
}
}
+ var keys;
+
+ if (Object.keys) {
+ keys = Object.keys;
+ } else {
+ keys = function (obj) {
+ var i, res = [];
+ for (i in obj) {
+ if (hasOwnProp(obj, i)) {
+ res.push(i);
+ }
+ }
+ return res;
+ };
+ }
+
// internal storage for locale config files
var locales = {};
var globalLocale;
@@ -461,7 +508,7 @@
}
function locale_locales__listLocales() {
- return Object.keys(locales);
+ return keys(locales);
}
var aliases = {};
@@ -540,7 +587,7 @@
Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
}
- var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
+ var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;
var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;
@@ -593,7 +640,7 @@
}
return function (mom) {
- var output = '';
+ var output = '', i;
for (i = 0; i < length; i++) {
output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
}
@@ -722,6 +769,23 @@
var WEEK = 7;
var WEEKDAY = 8;
+ var indexOf;
+
+ if (Array.prototype.indexOf) {
+ indexOf = Array.prototype.indexOf;
+ } else {
+ indexOf = function (o) {
+ // I know
+ var i;
+ for (i = 0; i < this.length; ++i) {
+ if (this[i] === o) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ }
+
function daysInMonth(year, month) {
return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
}
@@ -784,15 +848,63 @@
this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
}
+ function units_month__handleStrictParse(monthName, format, strict) {
+ var i, ii, mom, llc = monthName.toLocaleLowerCase();
+ if (!this._monthsParse) {
+ // this is not used
+ this._monthsParse = [];
+ this._longMonthsParse = [];
+ this._shortMonthsParse = [];
+ for (i = 0; i < 12; ++i) {
+ mom = create_utc__createUTC([2000, i]);
+ this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
+ this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
+ }
+ }
+
+ if (strict) {
+ if (format === 'MMM') {
+ ii = indexOf.call(this._shortMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._longMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ } else {
+ if (format === 'MMM') {
+ ii = indexOf.call(this._shortMonthsParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._longMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._longMonthsParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._shortMonthsParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ }
+ }
+
function localeMonthsParse (monthName, format, strict) {
var i, mom, regex;
+ if (this._monthsParseExact) {
+ return units_month__handleStrictParse.call(this, monthName, format, strict);
+ }
+
if (!this._monthsParse) {
this._monthsParse = [];
this._longMonthsParse = [];
this._shortMonthsParse = [];
}
+ // TODO: add sorting
+ // Sorting makes sure if one month (or abbr) is a prefix of another
+ // see sorting in computeMonthsParse
for (i = 0; i < 12; i++) {
// make the regex if we don't have it already
mom = create_utc__createUTC([2000, i]);
@@ -918,8 +1030,8 @@
this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
this._monthsShortRegex = this._monthsRegex;
- this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')$', 'i');
- this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')$', 'i');
+ this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
+ this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
}
function checkOverflow (m) {
@@ -1146,7 +1258,7 @@
// MOMENTS
- var getSetYear = makeGetSet('FullYear', false);
+ var getSetYear = makeGetSet('FullYear', true);
function getIsLeapYear () {
return isLeapYear(this.year());
@@ -1415,6 +1527,9 @@
config._a[HOUR] > 0) {
getParsingFlags(config).bigHour = undefined;
}
+
+ getParsingFlags(config).parsedDateParts = config._a.slice(0);
+ getParsingFlags(config).meridiem = config._meridiem;
// handle meridiem
config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);
@@ -1555,7 +1670,7 @@
if (input === undefined) {
config._d = new Date(utils_hooks__hooks.now());
} else if (isDate(input)) {
- config._d = new Date(+input);
+ config._d = new Date(input.valueOf());
} else if (typeof input === 'string') {
configFromString(config);
} else if (isArray(input)) {
@@ -1675,7 +1790,7 @@
this._milliseconds = +milliseconds +
seconds * 1e3 + // 1000
minutes * 6e4 + // 1000 * 60
- hours * 36e5; // 1000 * 60 * 60
+ hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
// Because of dateAddRemove treats 24 hours as different from a
// day when working around DST, we need to store them separately
this._days = +days +
@@ -1745,9 +1860,9 @@
var res, diff;
if (model._isUTC) {
res = model.clone();
- diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);
+ diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf();
// Use low-level api, because this fn is low-level api.
- res._d.setTime(+res._d + diff);
+ res._d.setTime(res._d.valueOf() + diff);
utils_hooks__hooks.updateOffset(res, false);
return res;
} else {
@@ -1908,7 +2023,7 @@
// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
// and further modified to allow for strings containing both week and day
- var isoRegex = /^(-)?P(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)W)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?$/;
+ var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
function create__createDuration (input, key) {
var duration = input,
@@ -2052,7 +2167,7 @@
updateOffset = updateOffset == null ? true : updateOffset;
if (milliseconds) {
- mom._d.setTime(+mom._d + milliseconds * isAdding);
+ mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
}
if (days) {
get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);
@@ -2097,9 +2212,9 @@
}
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
if (units === 'millisecond') {
- return +this > +localInput;
+ return this.valueOf() > localInput.valueOf();
} else {
- return +localInput < +this.clone().startOf(units);
+ return localInput.valueOf() < this.clone().startOf(units).valueOf();
}
}
@@ -2110,14 +2225,16 @@
}
units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
if (units === 'millisecond') {
- return +this < +localInput;
+ return this.valueOf() < localInput.valueOf();
} else {
- return +this.clone().endOf(units) < +localInput;
+ return this.clone().endOf(units).valueOf() < localInput.valueOf();
}
}
- function isBetween (from, to, units) {
- return this.isAfter(from, units) && this.isBefore(to, units);
+ function isBetween (from, to, units, inclusivity) {
+ inclusivity = inclusivity || '()';
+ return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
+ (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
}
function isSame (input, units) {
@@ -2128,10 +2245,10 @@
}
units = normalizeUnits(units || 'millisecond');
if (units === 'millisecond') {
- return +this === +localInput;
+ return this.valueOf() === localInput.valueOf();
} else {
- inputMs = +localInput;
- return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));
+ inputMs = localInput.valueOf();
+ return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
}
}
@@ -2198,10 +2315,12 @@
adjust = (b - anchor) / (anchor2 - anchor);
}
- return -(wholeMonthDiff + adjust);
+ //check for negative zero, return zero if negative zero
+ return -(wholeMonthDiff + adjust) || 0;
}
utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
+ utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';
function toString () {
return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
@@ -2222,7 +2341,10 @@
}
function format (inputString) {
- var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);
+ if (!inputString) {
+ inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat;
+ }
+ var output = formatMoment(this, inputString);
return this.localeData().postformat(output);
}
@@ -2301,6 +2423,7 @@
case 'week':
case 'isoWeek':
case 'day':
+ case 'date':
this.hours(0);
/* falls through */
case 'hour':
@@ -2334,19 +2457,25 @@
if (units === undefined || units === 'millisecond') {
return this;
}
+
+ // 'date' is an alias for 'day', so it should be considered as such.
+ if (units === 'date') {
+ units = 'day';
+ }
+
return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
}
function to_type__valueOf () {
- return +this._d - ((this._offset || 0) * 60000);
+ return this._d.valueOf() - ((this._offset || 0) * 60000);
}
function unix () {
- return Math.floor(+this / 1000);
+ return Math.floor(this.valueOf() / 1000);
}
function toDate () {
- return this._offset ? new Date(+this) : this._d;
+ return this._offset ? new Date(this.valueOf()) : this._d;
}
function toArray () {
@@ -2615,9 +2744,15 @@
addRegexToken('d', match1to2);
addRegexToken('e', match1to2);
addRegexToken('E', match1to2);
- addRegexToken('dd', matchWord);
- addRegexToken('ddd', matchWord);
- addRegexToken('dddd', matchWord);
+ addRegexToken('dd', function (isStrict, locale) {
+ return locale.weekdaysMinRegex(isStrict);
+ });
+ addRegexToken('ddd', function (isStrict, locale) {
+ return locale.weekdaysShortRegex(isStrict);
+ });
+ addRegexToken('dddd', function (isStrict, locale) {
+ return locale.weekdaysRegex(isStrict);
+ });
addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
var weekday = config._locale.weekdaysParse(input, token, config._strict);
@@ -2670,9 +2805,77 @@
return this._weekdaysMin[m.day()];
}
+ function day_of_week__handleStrictParse(weekdayName, format, strict) {
+ var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
+ if (!this._weekdaysParse) {
+ this._weekdaysParse = [];
+ this._shortWeekdaysParse = [];
+ this._minWeekdaysParse = [];
+
+ for (i = 0; i < 7; ++i) {
+ mom = create_utc__createUTC([2000, 1]).day(i);
+ this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
+ this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
+ this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
+ }
+ }
+
+ if (strict) {
+ if (format === 'dddd') {
+ ii = indexOf.call(this._weekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else if (format === 'ddd') {
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ } else {
+ if (format === 'dddd') {
+ ii = indexOf.call(this._weekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else if (format === 'ddd') {
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._weekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ } else {
+ ii = indexOf.call(this._minWeekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._weekdaysParse, llc);
+ if (ii !== -1) {
+ return ii;
+ }
+ ii = indexOf.call(this._shortWeekdaysParse, llc);
+ return ii !== -1 ? ii : null;
+ }
+ }
+ }
+
function localeWeekdaysParse (weekdayName, format, strict) {
var i, mom, regex;
+ if (this._weekdaysParseExact) {
+ return day_of_week__handleStrictParse.call(this, weekdayName, format, strict);
+ }
+
if (!this._weekdaysParse) {
this._weekdaysParse = [];
this._minWeekdaysParse = [];
@@ -2683,7 +2886,7 @@
for (i = 0; i < 7; i++) {
// make the regex if we don't have it already
- mom = local__createLocal([2000, 1]).day(i);
+ mom = create_utc__createUTC([2000, 1]).day(i);
if (strict && !this._fullWeekdaysParse[i]) {
this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i');
this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i');
@@ -2739,6 +2942,99 @@
return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
}
+ var defaultWeekdaysRegex = matchWord;
+ function weekdaysRegex (isStrict) {
+ if (this._weekdaysParseExact) {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ computeWeekdaysParse.call(this);
+ }
+ if (isStrict) {
+ return this._weekdaysStrictRegex;
+ } else {
+ return this._weekdaysRegex;
+ }
+ } else {
+ return this._weekdaysStrictRegex && isStrict ?
+ this._weekdaysStrictRegex : this._weekdaysRegex;
+ }
+ }
+
+ var defaultWeekdaysShortRegex = matchWord;
+ function weekdaysShortRegex (isStrict) {
+ if (this._weekdaysParseExact) {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ computeWeekdaysParse.call(this);
+ }
+ if (isStrict) {
+ return this._weekdaysShortStrictRegex;
+ } else {
+ return this._weekdaysShortRegex;
+ }
+ } else {
+ return this._weekdaysShortStrictRegex && isStrict ?
+ this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
+ }
+ }
+
+ var defaultWeekdaysMinRegex = matchWord;
+ function weekdaysMinRegex (isStrict) {
+ if (this._weekdaysParseExact) {
+ if (!hasOwnProp(this, '_weekdaysRegex')) {
+ computeWeekdaysParse.call(this);
+ }
+ if (isStrict) {
+ return this._weekdaysMinStrictRegex;
+ } else {
+ return this._weekdaysMinRegex;
+ }
+ } else {
+ return this._weekdaysMinStrictRegex && isStrict ?
+ this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
+ }
+ }
+
+
+ function computeWeekdaysParse () {
+ function cmpLenRev(a, b) {
+ return b.length - a.length;
+ }
+
+ var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
+ i, mom, minp, shortp, longp;
+ for (i = 0; i < 7; i++) {
+ // make the regex if we don't have it already
+ mom = create_utc__createUTC([2000, 1]).day(i);
+ minp = this.weekdaysMin(mom, '');
+ shortp = this.weekdaysShort(mom, '');
+ longp = this.weekdays(mom, '');
+ minPieces.push(minp);
+ shortPieces.push(shortp);
+ longPieces.push(longp);
+ mixedPieces.push(minp);
+ mixedPieces.push(shortp);
+ mixedPieces.push(longp);
+ }
+ // Sorting makes sure if one weekday (or abbr) is a prefix of another it
+ // will match the longer piece.
+ minPieces.sort(cmpLenRev);
+ shortPieces.sort(cmpLenRev);
+ longPieces.sort(cmpLenRev);
+ mixedPieces.sort(cmpLenRev);
+ for (i = 0; i < 7; i++) {
+ shortPieces[i] = regexEscape(shortPieces[i]);
+ longPieces[i] = regexEscape(longPieces[i]);
+ mixedPieces[i] = regexEscape(mixedPieces[i]);
+ }
+
+ this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
+ this._weekdaysShortRegex = this._weekdaysRegex;
+ this._weekdaysMinRegex = this._weekdaysRegex;
+
+ this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
+ this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
+ this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
+ }
+
// FORMATTING
addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
@@ -2770,8 +3066,13 @@
return this.hours() % 12 || 12;
}
+ function kFormat() {
+ return this.hours() || 24;
+ }
+
addFormatToken('H', ['HH', 2], 0, 'hour');
addFormatToken('h', ['hh', 2], 0, hFormat);
+ addFormatToken('k', ['kk', 2], 0, kFormat);
addFormatToken('hmm', 0, 0, function () {
return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
@@ -3232,6 +3533,13 @@
prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;
prototype__proto.weekdaysParse = localeWeekdaysParse;
+ prototype__proto._weekdaysRegex = defaultWeekdaysRegex;
+ prototype__proto.weekdaysRegex = weekdaysRegex;
+ prototype__proto._weekdaysShortRegex = defaultWeekdaysShortRegex;
+ prototype__proto.weekdaysShortRegex = weekdaysShortRegex;
+ prototype__proto._weekdaysMinRegex = defaultWeekdaysMinRegex;
+ prototype__proto.weekdaysMinRegex = weekdaysMinRegex;
+
// Hours
prototype__proto.isPM = localeIsPM;
prototype__proto._meridiemParse = defaultLocaleMeridiemParse;
@@ -3243,7 +3551,7 @@
return locale[field](utc, format);
}
- function list (format, index, field, count, setter) {
+ function listMonthsImpl (format, index, field) {
if (typeof format === 'number') {
index = format;
format = undefined;
@@ -3252,35 +3560,79 @@
format = format || '';
if (index != null) {
- return lists__get(format, index, field, setter);
+ return lists__get(format, index, field, 'month');
}
var i;
var out = [];
- for (i = 0; i < count; i++) {
- out[i] = lists__get(format, i, field, setter);
+ for (i = 0; i < 12; i++) {
+ out[i] = lists__get(format, i, field, 'month');
+ }
+ return out;
+ }
+
+ // ()
+ // (5)
+ // (fmt, 5)
+ // (fmt)
+ // (true)
+ // (true, 5)
+ // (true, fmt, 5)
+ // (true, fmt)
+ function listWeekdaysImpl (localeSorted, format, index, field) {
+ if (typeof localeSorted === 'boolean') {
+ if (typeof format === 'number') {
+ index = format;
+ format = undefined;
+ }
+
+ format = format || '';
+ } else {
+ format = localeSorted;
+ index = format;
+ localeSorted = false;
+
+ if (typeof format === 'number') {
+ index = format;
+ format = undefined;
+ }
+
+ format = format || '';
+ }
+
+ var locale = locale_locales__getLocale(),
+ shift = localeSorted ? locale._week.dow : 0;
+
+ if (index != null) {
+ return lists__get(format, (index + shift) % 7, field, 'day');
+ }
+
+ var i;
+ var out = [];
+ for (i = 0; i < 7; i++) {
+ out[i] = lists__get(format, (i + shift) % 7, field, 'day');
}
return out;
}
function lists__listMonths (format, index) {
- return list(format, index, 'months', 12, 'month');
+ return listMonthsImpl(format, index, 'months');
}
function lists__listMonthsShort (format, index) {
- return list(format, index, 'monthsShort', 12, 'month');
+ return listMonthsImpl(format, index, 'monthsShort');
}
- function lists__listWeekdays (format, index) {
- return list(format, index, 'weekdays', 7, 'day');
+ function lists__listWeekdays (localeSorted, format, index) {
+ return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
}
- function lists__listWeekdaysShort (format, index) {
- return list(format, index, 'weekdaysShort', 7, 'day');
+ function lists__listWeekdaysShort (localeSorted, format, index) {
+ return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
}
- function lists__listWeekdaysMin (format, index) {
- return list(format, index, 'weekdaysMin', 7, 'day');
+ function lists__listWeekdaysMin (localeSorted, format, index) {
+ return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
}
locale_locales__getSetGlobalLocale('en', {
@@ -3651,7 +4003,7 @@
// Side effect imports
- utils_hooks__hooks.version = '2.12.0';
+ utils_hooks__hooks.version = '2.13.0';
setHookCallback(local__createLocal);
diff --git a/library/moment/moment.min.js b/library/moment/moment.min.js
index ba38995bd..d301ddbbe 100644
--- a/library/moment/moment.min.js
+++ b/library/moment/moment.min.js
@@ -1,7 +1,7 @@
//! moment.js
-//! version : 2.12.0
+//! version : 2.13.0
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
//! license : MIT
//! momentjs.com
-!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return Zc.apply(null,arguments)}function b(a){Zc=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function f(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function g(a,b){for(var c in b)f(b,c)&&(a[c]=b[c]);return f(b,"toString")&&(a.toString=b.toString),f(b,"valueOf")&&(a.valueOf=b.valueOf),a}function h(a,b,c,d){return Ia(a,b,c,d,!0).utc()}function i(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function j(a){return null==a._pf&&(a._pf=i()),a._pf}function k(a){if(null==a._isValid){var b=j(a);a._isValid=!(isNaN(a._d.getTime())||!(b.overflow<0)||b.empty||b.invalidMonth||b.invalidWeekday||b.nullInput||b.invalidFormat||b.userInvalidated),a._strict&&(a._isValid=a._isValid&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour)}return a._isValid}function l(a){var b=h(NaN);return null!=a?g(j(b),a):j(b).userInvalidated=!0,b}function m(a){return void 0===a}function n(a,b){var c,d,e;if(m(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),m(b._i)||(a._i=b._i),m(b._f)||(a._f=b._f),m(b._l)||(a._l=b._l),m(b._strict)||(a._strict=b._strict),m(b._tzm)||(a._tzm=b._tzm),m(b._isUTC)||(a._isUTC=b._isUTC),m(b._offset)||(a._offset=b._offset),m(b._pf)||(a._pf=j(b)),m(b._locale)||(a._locale=b._locale),$c.length>0)for(c in $c)d=$c[c],e=b[d],m(e)||(a[d]=e);return a}function o(b){n(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),_c===!1&&(_c=!0,a.updateOffset(this),_c=!1)}function p(a){return a instanceof o||null!=a&&null!=a._isAMomentObject}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=q(b)),c}function s(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&r(a[d])!==r(b[d]))&&g++;return g+f}function t(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function u(a,b){var c=!0;return g(function(){return c&&(t(a+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),c=!1),b.apply(this,arguments)},b)}function v(a,b){ad[a]||(t(b),ad[a]=!0)}function w(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function x(a){return"[object Object]"===Object.prototype.toString.call(a)}function y(a){var b,c;for(c in a)b=a[c],w(b)?this[c]=b:this["_"+c]=b;this._config=a,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function z(a,b){var c,d=g({},a);for(c in b)f(b,c)&&(x(a[c])&&x(b[c])?(d[c]={},g(d[c],a[c]),g(d[c],b[c])):null!=b[c]?d[c]=b[c]:delete d[c]);return d}function A(a){null!=a&&this.set(a)}function B(a){return a?a.toLowerCase().replace("_","-"):a}function C(a){for(var b,c,d,e,f=0;f<a.length;){for(e=B(a[f]).split("-"),b=e.length,c=B(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=D(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&s(e,c,!0)>=b-1)break;b--}f++}return null}function D(a){var b=null;if(!cd[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=bd._abbr,require("./locale/"+a),E(b)}catch(c){}return cd[a]}function E(a,b){var c;return a&&(c=m(b)?H(a):F(a,b),c&&(bd=c)),bd._abbr}function F(a,b){return null!==b?(b.abbr=a,null!=cd[a]?(v("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale"),b=z(cd[a]._config,b)):null!=b.parentLocale&&(null!=cd[b.parentLocale]?b=z(cd[b.parentLocale]._config,b):v("parentLocaleUndefined","specified parentLocale is not defined yet")),cd[a]=new A(b),E(a),cd[a]):(delete cd[a],null)}function G(a,b){if(null!=b){var c;null!=cd[a]&&(b=z(cd[a]._config,b)),c=new A(b),c.parentLocale=cd[a],cd[a]=c,E(a)}else null!=cd[a]&&(null!=cd[a].parentLocale?cd[a]=cd[a].parentLocale:null!=cd[a]&&delete cd[a]);return cd[a]}function H(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return bd;if(!c(a)){if(b=D(a))return b;a=[a]}return C(a)}function I(){return Object.keys(cd)}function J(a,b){var c=a.toLowerCase();dd[c]=dd[c+"s"]=dd[b]=a}function K(a){return"string"==typeof a?dd[a]||dd[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)f(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(b,c){return function(d){return null!=d?(O(this,b,d),a.updateOffset(this,c),this):N(this,b)}}function N(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function O(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function P(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=K(a),w(this[a]))return this[a](b);return this}function Q(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function R(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(hd[a]=e),b&&(hd[b[0]]=function(){return Q(e.apply(this,arguments),b[1],b[2])}),c&&(hd[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function S(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function T(a){var b,c,d=a.match(ed);for(b=0,c=d.length;c>b;b++)hd[d[b]]?d[b]=hd[d[b]]:d[b]=S(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function U(a,b){return a.isValid()?(b=V(b,a.localeData()),gd[b]=gd[b]||T(b),gd[b](a)):a.localeData().invalidDate()}function V(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(fd.lastIndex=0;d>=0&&fd.test(a);)a=a.replace(fd,c),fd.lastIndex=0,d-=1;return a}function W(a,b,c){zd[a]=w(b)?b:function(a,d){return a&&c?c:b}}function X(a,b){return f(zd,a)?zd[a](b._strict,b._locale):new RegExp(Y(a))}function Y(a){return Z(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function Z(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function $(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=r(a)}),c=0;c<a.length;c++)Ad[a[c]]=d}function _(a,b){$(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function aa(a,b,c){null!=b&&f(Ad,a)&&Ad[a](b,c._a,c,a)}function ba(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function ca(a,b){return c(this._months)?this._months[a.month()]:this._months[Kd.test(b)?"format":"standalone"][a.month()]}function da(a,b){return c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[Kd.test(b)?"format":"standalone"][a.month()]}function ea(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function fa(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=r(b);else if(b=a.localeData().monthsParse(b),"number"!=typeof b)return a;return c=Math.min(a.date(),ba(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ga(b){return null!=b?(fa(this,b),a.updateOffset(this,!0),this):N(this,"Month")}function ha(){return ba(this.year(),this.month())}function ia(a){return this._monthsParseExact?(f(this,"_monthsRegex")||ka.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex}function ja(a){return this._monthsParseExact?(f(this,"_monthsRegex")||ka.call(this),a?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex}function ka(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=h([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=Z(d[b]),e[b]=Z(e[b]),f[b]=Z(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")$","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")$","i")}function la(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[Cd]<0||c[Cd]>11?Cd:c[Dd]<1||c[Dd]>ba(c[Bd],c[Cd])?Dd:c[Ed]<0||c[Ed]>24||24===c[Ed]&&(0!==c[Fd]||0!==c[Gd]||0!==c[Hd])?Ed:c[Fd]<0||c[Fd]>59?Fd:c[Gd]<0||c[Gd]>59?Gd:c[Hd]<0||c[Hd]>999?Hd:-1,j(a)._overflowDayOfYear&&(Bd>b||b>Dd)&&(b=Dd),j(a)._overflowWeeks&&-1===b&&(b=Id),j(a)._overflowWeekday&&-1===b&&(b=Jd),j(a).overflow=b),a}function ma(a){var b,c,d,e,f,g,h=a._i,i=Pd.exec(h)||Qd.exec(h);if(i){for(j(a).iso=!0,b=0,c=Sd.length;c>b;b++)if(Sd[b][1].exec(i[1])){e=Sd[b][0],d=Sd[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Td.length;c>b;b++)if(Td[b][1].exec(i[3])){f=(i[2]||" ")+Td[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!Rd.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),Ba(a)}else a._isValid=!1}function na(b){var c=Ud.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(ma(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function oa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function pa(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function qa(a){return ra(a)?366:365}function ra(a){return a%4===0&&a%100!==0||a%400===0}function sa(){return ra(this.year())}function ta(a,b,c){var d=7+b-c,e=(7+pa(a,0,d).getUTCDay()-b)%7;return-e+d-1}function ua(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ta(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=qa(f)+j):j>qa(a)?(f=a+1,g=j-qa(a)):(f=a,g=j),{year:f,dayOfYear:g}}function va(a,b,c){var d,e,f=ta(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+wa(e,b,c)):g>wa(a.year(),b,c)?(d=g-wa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function wa(a,b,c){var d=ta(a,b,c),e=ta(a+1,b,c);return(qa(a)-d+e)/7}function xa(a,b,c){return null!=a?a:null!=b?b:c}function ya(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function za(a){var b,c,d,e,f=[];if(!a._d){for(d=ya(a),a._w&&null==a._a[Dd]&&null==a._a[Cd]&&Aa(a),a._dayOfYear&&(e=xa(a._a[Bd],d[Bd]),a._dayOfYear>qa(e)&&(j(a)._overflowDayOfYear=!0),c=pa(e,0,a._dayOfYear),a._a[Cd]=c.getUTCMonth(),a._a[Dd]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[Ed]&&0===a._a[Fd]&&0===a._a[Gd]&&0===a._a[Hd]&&(a._nextDay=!0,a._a[Ed]=0),a._d=(a._useUTC?pa:oa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Ed]=24)}}function Aa(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=xa(b.GG,a._a[Bd],va(Ja(),1,4).year),d=xa(b.W,1),e=xa(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=xa(b.gg,a._a[Bd],va(Ja(),f,g).year),d=xa(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>wa(c,f,g)?j(a)._overflowWeeks=!0:null!=i?j(a)._overflowWeekday=!0:(h=ua(c,d,e,f,g),a._a[Bd]=h.year,a._dayOfYear=h.dayOfYear)}function Ba(b){if(b._f===a.ISO_8601)return void ma(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=V(b._f,b._locale).match(ed)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(X(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),hd[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),aa(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[Ed]<=12&&b._a[Ed]>0&&(j(b).bigHour=void 0),b._a[Ed]=Ca(b._locale,b._a[Ed],b._meridiem),za(b),la(b)}function Ca(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function Da(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=n({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],Ba(b),k(b)&&(f+=j(b).charsLeftOver,f+=10*j(b).unusedTokens.length,j(b).score=f,(null==d||d>f)&&(d=f,c=b));g(a,c||b)}function Ea(a){if(!a._d){var b=L(a._i);a._a=e([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),za(a)}}function Fa(a){var b=new o(la(Ga(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Ga(a){var b=a._i,e=a._f;return a._locale=a._locale||H(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),p(b)?new o(la(b)):(c(e)?Da(a):e?Ba(a):d(b)?a._d=b:Ha(a),k(a)||(a._d=null),a))}function Ha(b){var f=b._i;void 0===f?b._d=new Date(a.now()):d(f)?b._d=new Date(+f):"string"==typeof f?na(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),za(b)):"object"==typeof f?Ea(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Ia(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,Fa(f)}function Ja(a,b,c,d){return Ia(a,b,c,d,!1)}function Ka(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Ja();for(d=b[0],e=1;e<b.length;++e)(!b[e].isValid()||b[e][a](d))&&(d=b[e]);return d}function La(){var a=[].slice.call(arguments,0);return Ka("isBefore",a)}function Ma(){var a=[].slice.call(arguments,0);return Ka("isAfter",a)}function Na(a){var b=L(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=H(),this._bubble()}function Oa(a){return a instanceof Na}function Pa(a,b){R(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+Q(~~(a/60),2)+b+Q(~~a%60,2)})}function Qa(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(Zd)||["-",0,0],f=+(60*e[1])+r(e[2]);return"+"===e[0]?f:-f}function Ra(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(p(b)||d(b)?+b:+Ja(b))-+e,e._d.setTime(+e._d+f),a.updateOffset(e,!1),e):Ja(b).local()}function Sa(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Ta(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=Qa(wd,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Sa(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?ib(this,cb(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Sa(this):null!=b?this:NaN}function Ua(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Va(a){return this.utcOffset(0,a)}function Wa(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Sa(this),"m")),this}function Xa(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Qa(vd,this._i)),this}function Ya(a){return this.isValid()?(a=a?Ja(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function Za(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function $a(){if(!m(this._isDSTShifted))return this._isDSTShifted;var a={};if(n(a,this),a=Ga(a),a._a){var b=a._isUTC?h(a._a):Ja(a._a);this._isDSTShifted=this.isValid()&&s(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function _a(){return this.isValid()?!this._isUTC:!1}function ab(){return this.isValid()?this._isUTC:!1}function bb(){return this.isValid()?this._isUTC&&0===this._offset:!1}function cb(a,b){var c,d,e,g=a,h=null;return Oa(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=$d.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:r(h[Dd])*c,h:r(h[Ed])*c,m:r(h[Fd])*c,s:r(h[Gd])*c,ms:r(h[Hd])*c}):(h=_d.exec(a))?(c="-"===h[1]?-1:1,g={y:db(h[2],c),M:db(h[3],c),w:db(h[4],c),d:db(h[5],c),h:db(h[6],c),m:db(h[7],c),s:db(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=fb(Ja(g.from),Ja(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Na(g),Oa(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function db(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function eb(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function fb(a,b){var c;return a.isValid()&&b.isValid()?(b=Ra(b,a),a.isBefore(b)?c=eb(a,b):(c=eb(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function gb(a){return 0>a?-1*Math.round(-1*a):Math.round(a)}function hb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(v(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=cb(c,d),ib(this,e,a),this}}function ib(b,c,d,e){var f=c._milliseconds,g=gb(c._days),h=gb(c._months);b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(+b._d+f*d),g&&O(b,"Date",N(b,"Date")+g*d),h&&fa(b,N(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function jb(a,b){var c=a||Ja(),d=Ra(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse",g=b&&(w(b[f])?b[f]():b[f]);return this.format(g||this.localeData().calendar(f,this,Ja(c)))}function kb(){return new o(this)}function lb(a,b){var c=p(a)?a:Ja(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?+this>+c:+c<+this.clone().startOf(b)):!1}function mb(a,b){var c=p(a)?a:Ja(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?+c>+this:+this.clone().endOf(b)<+c):!1}function nb(a,b,c){return this.isAfter(a,c)&&this.isBefore(b,c)}function ob(a,b){var c,d=p(a)?a:Ja(a);return this.isValid()&&d.isValid()?(b=K(b||"millisecond"),"millisecond"===b?+this===+d:(c=+d,+this.clone().startOf(b)<=c&&c<=+this.clone().endOf(b))):!1}function pb(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function qb(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function rb(a,b,c){var d,e,f,g;return this.isValid()?(d=Ra(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=K(b),"year"===b||"month"===b||"quarter"===b?(g=sb(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:q(g)):NaN):NaN}function sb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function tb(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ub(){var a=this.clone().utc();return 0<a.year()&&a.year()<=9999?w(Date.prototype.toISOString)?this.toDate().toISOString():U(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):U(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function vb(b){var c=U(this,b||a.defaultFormat);return this.localeData().postformat(c)}function wb(a,b){return this.isValid()&&(p(a)&&a.isValid()||Ja(a).isValid())?cb({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function xb(a){return this.from(Ja(),a)}function yb(a,b){return this.isValid()&&(p(a)&&a.isValid()||Ja(a).isValid())?cb({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function zb(a){return this.to(Ja(),a)}function Ab(a){var b;return void 0===a?this._locale._abbr:(b=H(a),null!=b&&(this._locale=b),this)}function Bb(){return this._locale}function Cb(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function Db(a){return a=K(a),void 0===a||"millisecond"===a?this:this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms")}function Eb(){return+this._d-6e4*(this._offset||0)}function Fb(){return Math.floor(+this/1e3)}function Gb(){return this._offset?new Date(+this):this._d}function Hb(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function Ib(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function Jb(){return this.isValid()?this.toISOString():null}function Kb(){return k(this)}function Lb(){return g({},j(this))}function Mb(){return j(this).overflow}function Nb(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Ob(a,b){R(0,[a,a.length],0,b)}function Pb(a){return Tb.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Qb(a){return Tb.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Rb(){return wa(this.year(),1,4)}function Sb(){var a=this.localeData()._week;return wa(this.year(),a.dow,a.doy)}function Tb(a,b,c,d,e){var f;return null==a?va(this,d,e).year:(f=wa(a,d,e),b>f&&(b=f),Ub.call(this,a,b,c,d,e))}function Ub(a,b,c,d,e){var f=ua(a,b,c,d,e),g=pa(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Vb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Wb(a){return va(a,this._week.dow,this._week.doy).week}function Xb(){return this._week.dow}function Yb(){return this._week.doy}function Zb(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function $b(a){var b=va(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function _b(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function ac(a,b){return c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]}function bc(a){return this._weekdaysShort[a.day()]}function cc(a){return this._weekdaysMin[a.day()]}function dc(a,b,c){var d,e,f;for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=Ja([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function ec(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=_b(a,this.localeData()),this.add(a-b,"d")):b}function fc(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function gc(a){return this.isValid()?null==a?this.day()||7:this.day(this.day()%7?a:a-7):null!=a?this:NaN}function hc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function ic(){return this.hours()%12||12}function jc(a,b){R(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function kc(a,b){return b._meridiemParse}function lc(a){return"p"===(a+"").toLowerCase().charAt(0)}function mc(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function nc(a,b){b[Hd]=r(1e3*("0."+a))}function oc(){return this._isUTC?"UTC":""}function pc(){return this._isUTC?"Coordinated Universal Time":""}function qc(a){return Ja(1e3*a)}function rc(){return Ja.apply(null,arguments).parseZone()}function sc(a,b,c){var d=this._calendar[a];return w(d)?d.call(b,c):d}function tc(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function uc(){return this._invalidDate}function vc(a){return this._ordinal.replace("%d",a)}function wc(a){return a}function xc(a,b,c,d){var e=this._relativeTime[c];return w(e)?e(a,b,c,d):e.replace(/%d/i,a)}function yc(a,b){var c=this._relativeTime[a>0?"future":"past"];return w(c)?c(b):c.replace(/%s/i,b)}function zc(a,b,c,d){var e=H(),f=h().set(d,b);return e[c](f,a)}function Ac(a,b,c,d,e){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return zc(a,b,c,e);var f,g=[];for(f=0;d>f;f++)g[f]=zc(a,f,c,e);return g}function Bc(a,b){return Ac(a,b,"months",12,"month")}function Cc(a,b){return Ac(a,b,"monthsShort",12,"month")}function Dc(a,b){return Ac(a,b,"weekdays",7,"day")}function Ec(a,b){return Ac(a,b,"weekdaysShort",7,"day")}function Fc(a,b){return Ac(a,b,"weekdaysMin",7,"day")}function Gc(){var a=this._data;return this._milliseconds=xe(this._milliseconds),this._days=xe(this._days),this._months=xe(this._months),a.milliseconds=xe(a.milliseconds),a.seconds=xe(a.seconds),a.minutes=xe(a.minutes),a.hours=xe(a.hours),a.months=xe(a.months),a.years=xe(a.years),this}function Hc(a,b,c,d){var e=cb(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Ic(a,b){return Hc(this,a,b,1)}function Jc(a,b){return Hc(this,a,b,-1)}function Kc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Lc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Kc(Nc(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=q(f/1e3),i.seconds=a%60,b=q(a/60),i.minutes=b%60,c=q(b/60),i.hours=c%24,g+=q(c/24),e=q(Mc(g)),h+=e,g-=Kc(Nc(e)),d=q(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function Mc(a){return 4800*a/146097}function Nc(a){return 146097*a/4800}function Oc(a){var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+Mc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(Nc(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function Pc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*r(this._months/12)}function Qc(a){return function(){return this.as(a)}}function Rc(a){return a=K(a),this[a+"s"]()}function Sc(a){return function(){return this._data[a]}}function Tc(){return q(this.days()/7)}function Uc(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Vc(a,b,c){var d=cb(a).abs(),e=Ne(d.as("s")),f=Ne(d.as("m")),g=Ne(d.as("h")),h=Ne(d.as("d")),i=Ne(d.as("M")),j=Ne(d.as("y")),k=e<Oe.s&&["s",e]||1>=f&&["m"]||f<Oe.m&&["mm",f]||1>=g&&["h"]||g<Oe.h&&["hh",g]||1>=h&&["d"]||h<Oe.d&&["dd",h]||1>=i&&["M"]||i<Oe.M&&["MM",i]||1>=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,Uc.apply(null,k)}function Wc(a,b){return void 0===Oe[a]?!1:void 0===b?Oe[a]:(Oe[a]=b,!0)}function Xc(a){var b=this.localeData(),c=Vc(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function Yc(){var a,b,c,d=Pe(this._milliseconds)/1e3,e=Pe(this._days),f=Pe(this._months);a=q(d/60),b=q(a/60),d%=60,a%=60,c=q(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var Zc,$c=a.momentProperties=[],_c=!1,ad={};a.suppressDeprecationWarnings=!1;var bd,cd={},dd={},ed=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,fd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,gd={},hd={},id=/\d/,jd=/\d\d/,kd=/\d{3}/,ld=/\d{4}/,md=/[+-]?\d{6}/,nd=/\d\d?/,od=/\d\d\d\d?/,pd=/\d\d\d\d\d\d?/,qd=/\d{1,3}/,rd=/\d{1,4}/,sd=/[+-]?\d{1,6}/,td=/\d+/,ud=/[+-]?\d+/,vd=/Z|[+-]\d\d:?\d\d/gi,wd=/Z|[+-]\d\d(?::?\d\d)?/gi,xd=/[+-]?\d+(\.\d{1,3})?/,yd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,zd={},Ad={},Bd=0,Cd=1,Dd=2,Ed=3,Fd=4,Gd=5,Hd=6,Id=7,Jd=8;R("M",["MM",2],"Mo",function(){return this.month()+1}),R("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),R("MMMM",0,0,function(a){return this.localeData().months(this,a)}),J("month","M"),W("M",nd),W("MM",nd,jd),W("MMM",function(a,b){return b.monthsShortRegex(a)}),W("MMMM",function(a,b){return b.monthsRegex(a)}),$(["M","MM"],function(a,b){b[Cd]=r(a)-1}),$(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[Cd]=e:j(c).invalidMonth=a});var Kd=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Ld="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Md="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Nd=yd,Od=yd,Pd=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Qd=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Rd=/Z|[+-]\d\d(?::?\d\d)?/,Sd=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Td=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Ud=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=u("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),R("Y",0,0,function(){var a=this.year();return 9999>=a?""+a:"+"+a}),R(0,["YY",2],0,function(){return this.year()%100}),R(0,["YYYY",4],0,"year"),R(0,["YYYYY",5],0,"year"),R(0,["YYYYYY",6,!0],0,"year"),J("year","y"),W("Y",ud),W("YY",nd,jd),W("YYYY",rd,ld),W("YYYYY",sd,md),W("YYYYYY",sd,md),$(["YYYYY","YYYYYY"],Bd),$("YYYY",function(b,c){c[Bd]=2===b.length?a.parseTwoDigitYear(b):r(b);
-}),$("YY",function(b,c){c[Bd]=a.parseTwoDigitYear(b)}),$("Y",function(a,b){b[Bd]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return r(a)+(r(a)>68?1900:2e3)};var Vd=M("FullYear",!1);a.ISO_8601=function(){};var Wd=u("moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Ja.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:l()}),Xd=u("moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Ja.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:l()}),Yd=function(){return Date.now?Date.now():+new Date};Pa("Z",":"),Pa("ZZ",""),W("Z",wd),W("ZZ",wd),$(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Qa(wd,a)});var Zd=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var $d=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,_d=/^(-)?P(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)W)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?$/;cb.fn=Na.prototype;var ae=hb(1,"add"),be=hb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var ce=u("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});R(0,["gg",2],0,function(){return this.weekYear()%100}),R(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Ob("gggg","weekYear"),Ob("ggggg","weekYear"),Ob("GGGG","isoWeekYear"),Ob("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),W("G",ud),W("g",ud),W("GG",nd,jd),W("gg",nd,jd),W("GGGG",rd,ld),W("gggg",rd,ld),W("GGGGG",sd,md),W("ggggg",sd,md),_(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=r(a)}),_(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),R("Q",0,"Qo","quarter"),J("quarter","Q"),W("Q",id),$("Q",function(a,b){b[Cd]=3*(r(a)-1)}),R("w",["ww",2],"wo","week"),R("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),W("w",nd),W("ww",nd,jd),W("W",nd),W("WW",nd,jd),_(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=r(a)});var de={dow:0,doy:6};R("D",["DD",2],"Do","date"),J("date","D"),W("D",nd),W("DD",nd,jd),W("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),$(["D","DD"],Dd),$("Do",function(a,b){b[Dd]=r(a.match(nd)[0],10)});var ee=M("Date",!0);R("d",0,"do","day"),R("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),R("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),R("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),R("e",0,0,"weekday"),R("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),W("d",nd),W("e",nd),W("E",nd),W("dd",yd),W("ddd",yd),W("dddd",yd),_(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:j(c).invalidWeekday=a}),_(["d","e","E"],function(a,b,c,d){b[d]=r(a)});var fe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ge="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),he="Su_Mo_Tu_We_Th_Fr_Sa".split("_");R("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),W("DDD",qd),W("DDDD",kd),$(["DDD","DDDD"],function(a,b,c){c._dayOfYear=r(a)}),R("H",["HH",2],0,"hour"),R("h",["hh",2],0,ic),R("hmm",0,0,function(){return""+ic.apply(this)+Q(this.minutes(),2)}),R("hmmss",0,0,function(){return""+ic.apply(this)+Q(this.minutes(),2)+Q(this.seconds(),2)}),R("Hmm",0,0,function(){return""+this.hours()+Q(this.minutes(),2)}),R("Hmmss",0,0,function(){return""+this.hours()+Q(this.minutes(),2)+Q(this.seconds(),2)}),jc("a",!0),jc("A",!1),J("hour","h"),W("a",kc),W("A",kc),W("H",nd),W("h",nd),W("HH",nd,jd),W("hh",nd,jd),W("hmm",od),W("hmmss",pd),W("Hmm",od),W("Hmmss",pd),$(["H","HH"],Ed),$(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),$(["h","hh"],function(a,b,c){b[Ed]=r(a),j(c).bigHour=!0}),$("hmm",function(a,b,c){var d=a.length-2;b[Ed]=r(a.substr(0,d)),b[Fd]=r(a.substr(d)),j(c).bigHour=!0}),$("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Ed]=r(a.substr(0,d)),b[Fd]=r(a.substr(d,2)),b[Gd]=r(a.substr(e)),j(c).bigHour=!0}),$("Hmm",function(a,b,c){var d=a.length-2;b[Ed]=r(a.substr(0,d)),b[Fd]=r(a.substr(d))}),$("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Ed]=r(a.substr(0,d)),b[Fd]=r(a.substr(d,2)),b[Gd]=r(a.substr(e))});var ie=/[ap]\.?m?\.?/i,je=M("Hours",!0);R("m",["mm",2],0,"minute"),J("minute","m"),W("m",nd),W("mm",nd,jd),$(["m","mm"],Fd);var ke=M("Minutes",!1);R("s",["ss",2],0,"second"),J("second","s"),W("s",nd),W("ss",nd,jd),$(["s","ss"],Gd);var le=M("Seconds",!1);R("S",0,0,function(){return~~(this.millisecond()/100)}),R(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),R(0,["SSS",3],0,"millisecond"),R(0,["SSSS",4],0,function(){return 10*this.millisecond()}),R(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),R(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),R(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),R(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),R(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),W("S",qd,id),W("SS",qd,jd),W("SSS",qd,kd);var me;for(me="SSSS";me.length<=9;me+="S")W(me,td);for(me="S";me.length<=9;me+="S")$(me,nc);var ne=M("Milliseconds",!1);R("z",0,0,"zoneAbbr"),R("zz",0,0,"zoneName");var oe=o.prototype;oe.add=ae,oe.calendar=jb,oe.clone=kb,oe.diff=rb,oe.endOf=Db,oe.format=vb,oe.from=wb,oe.fromNow=xb,oe.to=yb,oe.toNow=zb,oe.get=P,oe.invalidAt=Mb,oe.isAfter=lb,oe.isBefore=mb,oe.isBetween=nb,oe.isSame=ob,oe.isSameOrAfter=pb,oe.isSameOrBefore=qb,oe.isValid=Kb,oe.lang=ce,oe.locale=Ab,oe.localeData=Bb,oe.max=Xd,oe.min=Wd,oe.parsingFlags=Lb,oe.set=P,oe.startOf=Cb,oe.subtract=be,oe.toArray=Hb,oe.toObject=Ib,oe.toDate=Gb,oe.toISOString=ub,oe.toJSON=Jb,oe.toString=tb,oe.unix=Fb,oe.valueOf=Eb,oe.creationData=Nb,oe.year=Vd,oe.isLeapYear=sa,oe.weekYear=Pb,oe.isoWeekYear=Qb,oe.quarter=oe.quarters=Vb,oe.month=ga,oe.daysInMonth=ha,oe.week=oe.weeks=Zb,oe.isoWeek=oe.isoWeeks=$b,oe.weeksInYear=Sb,oe.isoWeeksInYear=Rb,oe.date=ee,oe.day=oe.days=ec,oe.weekday=fc,oe.isoWeekday=gc,oe.dayOfYear=hc,oe.hour=oe.hours=je,oe.minute=oe.minutes=ke,oe.second=oe.seconds=le,oe.millisecond=oe.milliseconds=ne,oe.utcOffset=Ta,oe.utc=Va,oe.local=Wa,oe.parseZone=Xa,oe.hasAlignedHourOffset=Ya,oe.isDST=Za,oe.isDSTShifted=$a,oe.isLocal=_a,oe.isUtcOffset=ab,oe.isUtc=bb,oe.isUTC=bb,oe.zoneAbbr=oc,oe.zoneName=pc,oe.dates=u("dates accessor is deprecated. Use date instead.",ee),oe.months=u("months accessor is deprecated. Use month instead",ga),oe.years=u("years accessor is deprecated. Use year instead",Vd),oe.zone=u("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Ua);var pe=oe,qe={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},re={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},se="Invalid date",te="%d",ue=/\d{1,2}/,ve={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},we=A.prototype;we._calendar=qe,we.calendar=sc,we._longDateFormat=re,we.longDateFormat=tc,we._invalidDate=se,we.invalidDate=uc,we._ordinal=te,we.ordinal=vc,we._ordinalParse=ue,we.preparse=wc,we.postformat=wc,we._relativeTime=ve,we.relativeTime=xc,we.pastFuture=yc,we.set=y,we.months=ca,we._months=Ld,we.monthsShort=da,we._monthsShort=Md,we.monthsParse=ea,we._monthsRegex=Od,we.monthsRegex=ja,we._monthsShortRegex=Nd,we.monthsShortRegex=ia,we.week=Wb,we._week=de,we.firstDayOfYear=Yb,we.firstDayOfWeek=Xb,we.weekdays=ac,we._weekdays=fe,we.weekdaysMin=cc,we._weekdaysMin=he,we.weekdaysShort=bc,we._weekdaysShort=ge,we.weekdaysParse=dc,we.isPM=lc,we._meridiemParse=ie,we.meridiem=mc,E("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===r(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=u("moment.lang is deprecated. Use moment.locale instead.",E),a.langData=u("moment.langData is deprecated. Use moment.localeData instead.",H);var xe=Math.abs,ye=Qc("ms"),ze=Qc("s"),Ae=Qc("m"),Be=Qc("h"),Ce=Qc("d"),De=Qc("w"),Ee=Qc("M"),Fe=Qc("y"),Ge=Sc("milliseconds"),He=Sc("seconds"),Ie=Sc("minutes"),Je=Sc("hours"),Ke=Sc("days"),Le=Sc("months"),Me=Sc("years"),Ne=Math.round,Oe={s:45,m:45,h:22,d:26,M:11},Pe=Math.abs,Qe=Na.prototype;Qe.abs=Gc,Qe.add=Ic,Qe.subtract=Jc,Qe.as=Oc,Qe.asMilliseconds=ye,Qe.asSeconds=ze,Qe.asMinutes=Ae,Qe.asHours=Be,Qe.asDays=Ce,Qe.asWeeks=De,Qe.asMonths=Ee,Qe.asYears=Fe,Qe.valueOf=Pc,Qe._bubble=Lc,Qe.get=Rc,Qe.milliseconds=Ge,Qe.seconds=He,Qe.minutes=Ie,Qe.hours=Je,Qe.days=Ke,Qe.weeks=Tc,Qe.months=Le,Qe.years=Me,Qe.humanize=Xc,Qe.toISOString=Yc,Qe.toString=Yc,Qe.toJSON=Yc,Qe.locale=Ab,Qe.localeData=Bb,Qe.toIsoString=u("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Yc),Qe.lang=ce,R("X",0,0,"unix"),R("x",0,0,"valueOf"),W("x",ud),W("X",xd),$("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),$("x",function(a,b,c){c._d=new Date(r(a))}),a.version="2.12.0",b(Ja),a.fn=pe,a.min=La,a.max=Ma,a.now=Yd,a.utc=h,a.unix=qc,a.months=Bc,a.isDate=d,a.locale=E,a.invalid=l,a.duration=cb,a.isMoment=p,a.weekdays=Dc,a.parseZone=rc,a.localeData=H,a.isDuration=Oa,a.monthsShort=Cc,a.weekdaysMin=Fc,a.defineLocale=F,a.updateLocale=G,a.locales=I,a.weekdaysShort=Ec,a.normalizeUnits=K,a.relativeTimeThreshold=Wc,a.prototype=pe;var Re=a;return Re}); \ No newline at end of file
+!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return fd.apply(null,arguments)}function b(a){fd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function f(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function g(a,b){for(var c in b)f(b,c)&&(a[c]=b[c]);return f(b,"toString")&&(a.toString=b.toString),f(b,"valueOf")&&(a.valueOf=b.valueOf),a}function h(a,b,c,d){return Ja(a,b,c,d,!0).utc()}function i(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null}}function j(a){return null==a._pf&&(a._pf=i()),a._pf}function k(a){if(null==a._isValid){var b=j(a),c=gd.call(b.parsedDateParts,function(a){return null!=a});a._isValid=!isNaN(a._d.getTime())&&b.overflow<0&&!b.empty&&!b.invalidMonth&&!b.invalidWeekday&&!b.nullInput&&!b.invalidFormat&&!b.userInvalidated&&(!b.meridiem||b.meridiem&&c),a._strict&&(a._isValid=a._isValid&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour)}return a._isValid}function l(a){var b=h(NaN);return null!=a?g(j(b),a):j(b).userInvalidated=!0,b}function m(a){return void 0===a}function n(a,b){var c,d,e;if(m(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),m(b._i)||(a._i=b._i),m(b._f)||(a._f=b._f),m(b._l)||(a._l=b._l),m(b._strict)||(a._strict=b._strict),m(b._tzm)||(a._tzm=b._tzm),m(b._isUTC)||(a._isUTC=b._isUTC),m(b._offset)||(a._offset=b._offset),m(b._pf)||(a._pf=j(b)),m(b._locale)||(a._locale=b._locale),hd.length>0)for(c in hd)d=hd[c],e=b[d],m(e)||(a[d]=e);return a}function o(b){n(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),id===!1&&(id=!0,a.updateOffset(this),id=!1)}function p(a){return a instanceof o||null!=a&&null!=a._isAMomentObject}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=q(b)),c}function s(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&r(a[d])!==r(b[d]))&&g++;return g+f}function t(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function u(b,c){var d=!0;return g(function(){return null!=a.deprecationHandler&&a.deprecationHandler(null,b),d&&(t(b+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),d=!1),c.apply(this,arguments)},c)}function v(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),jd[b]||(t(c),jd[b]=!0)}function w(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function x(a){return"[object Object]"===Object.prototype.toString.call(a)}function y(a){var b,c;for(c in a)b=a[c],w(b)?this[c]=b:this["_"+c]=b;this._config=a,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function z(a,b){var c,d=g({},a);for(c in b)f(b,c)&&(x(a[c])&&x(b[c])?(d[c]={},g(d[c],a[c]),g(d[c],b[c])):null!=b[c]?d[c]=b[c]:delete d[c]);return d}function A(a){null!=a&&this.set(a)}function B(a){return a?a.toLowerCase().replace("_","-"):a}function C(a){for(var b,c,d,e,f=0;f<a.length;){for(e=B(a[f]).split("-"),b=e.length,c=B(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=D(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&s(e,c,!0)>=b-1)break;b--}f++}return null}function D(a){var b=null;if(!nd[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=ld._abbr,require("./locale/"+a),E(b)}catch(c){}return nd[a]}function E(a,b){var c;return a&&(c=m(b)?H(a):F(a,b),c&&(ld=c)),ld._abbr}function F(a,b){return null!==b?(b.abbr=a,null!=nd[a]?(v("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale"),b=z(nd[a]._config,b)):null!=b.parentLocale&&(null!=nd[b.parentLocale]?b=z(nd[b.parentLocale]._config,b):v("parentLocaleUndefined","specified parentLocale is not defined yet")),nd[a]=new A(b),E(a),nd[a]):(delete nd[a],null)}function G(a,b){if(null!=b){var c;null!=nd[a]&&(b=z(nd[a]._config,b)),c=new A(b),c.parentLocale=nd[a],nd[a]=c,E(a)}else null!=nd[a]&&(null!=nd[a].parentLocale?nd[a]=nd[a].parentLocale:null!=nd[a]&&delete nd[a]);return nd[a]}function H(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return ld;if(!c(a)){if(b=D(a))return b;a=[a]}return C(a)}function I(){return kd(nd)}function J(a,b){var c=a.toLowerCase();od[c]=od[c+"s"]=od[b]=a}function K(a){return"string"==typeof a?od[a]||od[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)f(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(b,c){return function(d){return null!=d?(O(this,b,d),a.updateOffset(this,c),this):N(this,b)}}function N(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function O(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function P(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=K(a),w(this[a]))return this[a](b);return this}function Q(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function R(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(sd[a]=e),b&&(sd[b[0]]=function(){return Q(e.apply(this,arguments),b[1],b[2])}),c&&(sd[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function S(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function T(a){var b,c,d=a.match(pd);for(b=0,c=d.length;c>b;b++)sd[d[b]]?d[b]=sd[d[b]]:d[b]=S(d[b]);return function(b){var e,f="";for(e=0;c>e;e++)f+=d[e]instanceof Function?d[e].call(b,a):d[e];return f}}function U(a,b){return a.isValid()?(b=V(b,a.localeData()),rd[b]=rd[b]||T(b),rd[b](a)):a.localeData().invalidDate()}function V(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(qd.lastIndex=0;d>=0&&qd.test(a);)a=a.replace(qd,c),qd.lastIndex=0,d-=1;return a}function W(a,b,c){Kd[a]=w(b)?b:function(a,d){return a&&c?c:b}}function X(a,b){return f(Kd,a)?Kd[a](b._strict,b._locale):new RegExp(Y(a))}function Y(a){return Z(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function Z(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function $(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=r(a)}),c=0;c<a.length;c++)Ld[a[c]]=d}function _(a,b){$(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function aa(a,b,c){null!=b&&f(Ld,a)&&Ld[a](b,c._a,c,a)}function ba(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function ca(a,b){return c(this._months)?this._months[a.month()]:this._months[Vd.test(b)?"format":"standalone"][a.month()]}function da(a,b){return c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[Vd.test(b)?"format":"standalone"][a.month()]}function ea(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],d=0;12>d;++d)f=h([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=md.call(this._shortMonthsParse,g),-1!==e?e:null):(e=md.call(this._longMonthsParse,g),-1!==e?e:null):"MMM"===b?(e=md.call(this._shortMonthsParse,g),-1!==e?e:(e=md.call(this._longMonthsParse,g),-1!==e?e:null)):(e=md.call(this._longMonthsParse,g),-1!==e?e:(e=md.call(this._shortMonthsParse,g),-1!==e?e:null))}function fa(a,b,c){var d,e,f;if(this._monthsParseExact)return ea.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function ga(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=r(b);else if(b=a.localeData().monthsParse(b),"number"!=typeof b)return a;return c=Math.min(a.date(),ba(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ha(b){return null!=b?(ga(this,b),a.updateOffset(this,!0),this):N(this,"Month")}function ia(){return ba(this.year(),this.month())}function ja(a){return this._monthsParseExact?(f(this,"_monthsRegex")||la.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex}function ka(a){return this._monthsParseExact?(f(this,"_monthsRegex")||la.call(this),a?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex}function la(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=h([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=Z(d[b]),e[b]=Z(e[b]),f[b]=Z(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function ma(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[Nd]<0||c[Nd]>11?Nd:c[Od]<1||c[Od]>ba(c[Md],c[Nd])?Od:c[Pd]<0||c[Pd]>24||24===c[Pd]&&(0!==c[Qd]||0!==c[Rd]||0!==c[Sd])?Pd:c[Qd]<0||c[Qd]>59?Qd:c[Rd]<0||c[Rd]>59?Rd:c[Sd]<0||c[Sd]>999?Sd:-1,j(a)._overflowDayOfYear&&(Md>b||b>Od)&&(b=Od),j(a)._overflowWeeks&&-1===b&&(b=Td),j(a)._overflowWeekday&&-1===b&&(b=Ud),j(a).overflow=b),a}function na(a){var b,c,d,e,f,g,h=a._i,i=$d.exec(h)||_d.exec(h);if(i){for(j(a).iso=!0,b=0,c=be.length;c>b;b++)if(be[b][1].exec(i[1])){e=be[b][0],d=be[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=ce.length;c>b;b++)if(ce[b][1].exec(i[3])){f=(i[2]||" ")+ce[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!ae.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),Ca(a)}else a._isValid=!1}function oa(b){var c=de.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(na(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function pa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function qa(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ra(a){return sa(a)?366:365}function sa(a){return a%4===0&&a%100!==0||a%400===0}function ta(){return sa(this.year())}function ua(a,b,c){var d=7+b-c,e=(7+qa(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=ra(f)+j):j>ra(a)?(f=a+1,g=j-ra(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(ra(a)-d+e)/7}function ya(a,b,c){return null!=a?a:null!=b?b:c}function za(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function Aa(a){var b,c,d,e,f=[];if(!a._d){for(d=za(a),a._w&&null==a._a[Od]&&null==a._a[Nd]&&Ba(a),a._dayOfYear&&(e=ya(a._a[Md],d[Md]),a._dayOfYear>ra(e)&&(j(a)._overflowDayOfYear=!0),c=qa(e,0,a._dayOfYear),a._a[Nd]=c.getUTCMonth(),a._a[Od]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[Pd]&&0===a._a[Qd]&&0===a._a[Rd]&&0===a._a[Sd]&&(a._nextDay=!0,a._a[Pd]=0),a._d=(a._useUTC?qa:pa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Pd]=24)}}function Ba(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=ya(b.GG,a._a[Md],wa(Ka(),1,4).year),d=ya(b.W,1),e=ya(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=ya(b.gg,a._a[Md],wa(Ka(),f,g).year),d=ya(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>xa(c,f,g)?j(a)._overflowWeeks=!0:null!=i?j(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[Md]=h.year,a._dayOfYear=h.dayOfYear)}function Ca(b){if(b._f===a.ISO_8601)return void na(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=V(b._f,b._locale).match(pd)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(X(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),sd[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),aa(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[Pd]<=12&&b._a[Pd]>0&&(j(b).bigHour=void 0),j(b).parsedDateParts=b._a.slice(0),j(b).meridiem=b._meridiem,b._a[Pd]=Da(b._locale,b._a[Pd],b._meridiem),Aa(b),ma(b)}function Da(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function Ea(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=n({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],Ca(b),k(b)&&(f+=j(b).charsLeftOver,f+=10*j(b).unusedTokens.length,j(b).score=f,(null==d||d>f)&&(d=f,c=b));g(a,c||b)}function Fa(a){if(!a._d){var b=L(a._i);a._a=e([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),Aa(a)}}function Ga(a){var b=new o(ma(Ha(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Ha(a){var b=a._i,e=a._f;return a._locale=a._locale||H(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),p(b)?new o(ma(b)):(c(e)?Ea(a):e?Ca(a):d(b)?a._d=b:Ia(a),k(a)||(a._d=null),a))}function Ia(b){var f=b._i;void 0===f?b._d=new Date(a.now()):d(f)?b._d=new Date(f.valueOf()):"string"==typeof f?oa(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),Aa(b)):"object"==typeof f?Fa(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Ja(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,Ga(f)}function Ka(a,b,c,d){return Ja(a,b,c,d,!1)}function La(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Ka();for(d=b[0],e=1;e<b.length;++e)(!b[e].isValid()||b[e][a](d))&&(d=b[e]);return d}function Ma(){var a=[].slice.call(arguments,0);return La("isBefore",a)}function Na(){var a=[].slice.call(arguments,0);return La("isAfter",a)}function Oa(a){var b=L(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+1e3*h*60*60,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=H(),this._bubble()}function Pa(a){return a instanceof Oa}function Qa(a,b){R(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+Q(~~(a/60),2)+b+Q(~~a%60,2)})}function Ra(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(ie)||["-",0,0],f=+(60*e[1])+r(e[2]);return"+"===e[0]?f:-f}function Sa(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(p(b)||d(b)?b.valueOf():Ka(b).valueOf())-e.valueOf(),e._d.setTime(e._d.valueOf()+f),a.updateOffset(e,!1),e):Ka(b).local()}function Ta(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Ua(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=Ra(Hd,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Ta(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?jb(this,db(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Ta(this):null!=b?this:NaN}function Va(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Wa(a){return this.utcOffset(0,a)}function Xa(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Ta(this),"m")),this}function Ya(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Ra(Gd,this._i)),this}function Za(a){return this.isValid()?(a=a?Ka(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function $a(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function _a(){if(!m(this._isDSTShifted))return this._isDSTShifted;var a={};if(n(a,this),a=Ha(a),a._a){var b=a._isUTC?h(a._a):Ka(a._a);this._isDSTShifted=this.isValid()&&s(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function ab(){return this.isValid()?!this._isUTC:!1}function bb(){return this.isValid()?this._isUTC:!1}function cb(){return this.isValid()?this._isUTC&&0===this._offset:!1}function db(a,b){var c,d,e,g=a,h=null;return Pa(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=je.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:r(h[Od])*c,h:r(h[Pd])*c,m:r(h[Qd])*c,s:r(h[Rd])*c,ms:r(h[Sd])*c}):(h=ke.exec(a))?(c="-"===h[1]?-1:1,g={y:eb(h[2],c),M:eb(h[3],c),w:eb(h[4],c),d:eb(h[5],c),h:eb(h[6],c),m:eb(h[7],c),s:eb(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=gb(Ka(g.from),Ka(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Oa(g),Pa(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function eb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function fb(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function gb(a,b){var c;return a.isValid()&&b.isValid()?(b=Sa(b,a),a.isBefore(b)?c=fb(a,b):(c=fb(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function hb(a){return 0>a?-1*Math.round(-1*a):Math.round(a)}function ib(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(v(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=db(c,d),jb(this,e,a),this}}function jb(b,c,d,e){var f=c._milliseconds,g=hb(c._days),h=hb(c._months);b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&O(b,"Date",N(b,"Date")+g*d),h&&ga(b,N(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function kb(a,b){var c=a||Ka(),d=Sa(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse",g=b&&(w(b[f])?b[f]():b[f]);return this.format(g||this.localeData().calendar(f,this,Ka(c)))}function lb(){return new o(this)}function mb(a,b){var c=p(a)?a:Ka(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()<this.clone().startOf(b).valueOf()):!1}function nb(a,b){var c=p(a)?a:Ka(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?this.valueOf()<c.valueOf():this.clone().endOf(b).valueOf()<c.valueOf()):!1}function ob(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}function pb(a,b){var c,d=p(a)?a:Ka(a);return this.isValid()&&d.isValid()?(b=K(b||"millisecond"),"millisecond"===b?this.valueOf()===d.valueOf():(c=d.valueOf(),this.clone().startOf(b).valueOf()<=c&&c<=this.clone().endOf(b).valueOf())):!1}function qb(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function rb(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function sb(a,b,c){var d,e,f,g;return this.isValid()?(d=Sa(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=K(b),"year"===b||"month"===b||"quarter"===b?(g=tb(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:q(g)):NaN):NaN}function tb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function ub(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function vb(){var a=this.clone().utc();return 0<a.year()&&a.year()<=9999?w(Date.prototype.toISOString)?this.toDate().toISOString():U(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):U(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function wb(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=U(this,b);return this.localeData().postformat(c)}function xb(a,b){return this.isValid()&&(p(a)&&a.isValid()||Ka(a).isValid())?db({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function yb(a){return this.from(Ka(),a)}function zb(a,b){return this.isValid()&&(p(a)&&a.isValid()||Ka(a).isValid())?db({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function Ab(a){return this.to(Ka(),a)}function Bb(a){var b;return void 0===a?this._locale._abbr:(b=H(a),null!=b&&(this._locale=b),this)}function Cb(){return this._locale}function Db(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function Eb(a){return a=K(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function Fb(){return this._d.valueOf()-6e4*(this._offset||0)}function Gb(){return Math.floor(this.valueOf()/1e3)}function Hb(){return this._offset?new Date(this.valueOf()):this._d}function Ib(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function Jb(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function Kb(){return this.isValid()?this.toISOString():null}function Lb(){return k(this)}function Mb(){return g({},j(this))}function Nb(){return j(this).overflow}function Ob(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Pb(a,b){R(0,[a,a.length],0,b)}function Qb(a){return Ub.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Rb(a){return Ub.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Sb(){return xa(this.year(),1,4)}function Tb(){var a=this.localeData()._week;return xa(this.year(),a.dow,a.doy)}function Ub(a,b,c,d,e){var f;return null==a?wa(this,d,e).year:(f=xa(a,d,e),b>f&&(b=f),Vb.call(this,a,b,c,d,e))}function Vb(a,b,c,d,e){var f=va(a,b,c,d,e),g=qa(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Wb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Xb(a){return wa(a,this._week.dow,this._week.doy).week}function Yb(){return this._week.dow}function Zb(){return this._week.doy}function $b(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function _b(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function ac(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function bc(a,b){return c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]}function cc(a){return this._weekdaysShort[a.day()]}function dc(a){return this._weekdaysMin[a.day()]}function ec(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;7>d;++d)f=h([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=md.call(this._weekdaysParse,g),-1!==e?e:null):"ddd"===b?(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:null):(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null):"dddd"===b?(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null))):"ddd"===b?(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null))):(e=md.call(this._minWeekdaysParse,g),-1!==e?e:(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:null)))}function fc(a,b,c){var d,e,f;if(this._weekdaysParseExact)return ec.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=h([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function gc(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=ac(a,this.localeData()),this.add(a-b,"d")):b}function hc(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function ic(a){return this.isValid()?null==a?this.day()||7:this.day(this.day()%7?a:a-7):null!=a?this:NaN}function jc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex}function kc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}function lc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}function mc(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],i=[],j=[],k=[];for(b=0;7>b;b++)c=h([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),i.push(e),j.push(f),k.push(d),k.push(e),k.push(f);for(g.sort(a),i.sort(a),j.sort(a),k.sort(a),b=0;7>b;b++)i[b]=Z(i[b]),j[b]=Z(j[b]),k[b]=Z(k[b]);this._weekdaysRegex=new RegExp("^("+k.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function nc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function oc(){return this.hours()%12||12}function pc(){return this.hours()||24}function qc(a,b){R(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function rc(a,b){return b._meridiemParse}function sc(a){return"p"===(a+"").toLowerCase().charAt(0)}function tc(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function uc(a,b){b[Sd]=r(1e3*("0."+a))}function vc(){return this._isUTC?"UTC":""}function wc(){return this._isUTC?"Coordinated Universal Time":""}function xc(a){return Ka(1e3*a)}function yc(){return Ka.apply(null,arguments).parseZone()}function zc(a,b,c){var d=this._calendar[a];return w(d)?d.call(b,c):d}function Ac(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function Bc(){return this._invalidDate}function Cc(a){return this._ordinal.replace("%d",a)}function Dc(a){return a}function Ec(a,b,c,d){var e=this._relativeTime[c];return w(e)?e(a,b,c,d):e.replace(/%d/i,a)}function Fc(a,b){var c=this._relativeTime[a>0?"future":"past"];return w(c)?c(b):c.replace(/%s/i,b)}function Gc(a,b,c,d){var e=H(),f=h().set(d,b);return e[c](f,a)}function Hc(a,b,c){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return Gc(a,b,c,"month");var d,e=[];for(d=0;12>d;d++)e[d]=Gc(a,d,c,"month");return e}function Ic(a,b,c,d){"boolean"==typeof a?("number"==typeof b&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,"number"==typeof b&&(c=b,b=void 0),b=b||"");var e=H(),f=a?e._week.dow:0;if(null!=c)return Gc(b,(c+f)%7,d,"day");var g,h=[];for(g=0;7>g;g++)h[g]=Gc(b,(g+f)%7,d,"day");return h}function Jc(a,b){return Hc(a,b,"months")}function Kc(a,b){return Hc(a,b,"monthsShort")}function Lc(a,b,c){return Ic(a,b,c,"weekdays")}function Mc(a,b,c){return Ic(a,b,c,"weekdaysShort")}function Nc(a,b,c){return Ic(a,b,c,"weekdaysMin")}function Oc(){var a=this._data;return this._milliseconds=Le(this._milliseconds),this._days=Le(this._days),this._months=Le(this._months),a.milliseconds=Le(a.milliseconds),a.seconds=Le(a.seconds),a.minutes=Le(a.minutes),a.hours=Le(a.hours),a.months=Le(a.months),a.years=Le(a.years),this}function Pc(a,b,c,d){var e=db(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Qc(a,b){return Pc(this,a,b,1)}function Rc(a,b){return Pc(this,a,b,-1)}function Sc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Tc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Sc(Vc(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=q(f/1e3),i.seconds=a%60,b=q(a/60),i.minutes=b%60,c=q(b/60),i.hours=c%24,g+=q(c/24),e=q(Uc(g)),h+=e,g-=Sc(Vc(e)),d=q(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function Uc(a){return 4800*a/146097}function Vc(a){return 146097*a/4800}function Wc(a){var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+Uc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(Vc(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function Xc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*r(this._months/12)}function Yc(a){return function(){return this.as(a)}}function Zc(a){
+return a=K(a),this[a+"s"]()}function $c(a){return function(){return this._data[a]}}function _c(){return q(this.days()/7)}function ad(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function bd(a,b,c){var d=db(a).abs(),e=_e(d.as("s")),f=_e(d.as("m")),g=_e(d.as("h")),h=_e(d.as("d")),i=_e(d.as("M")),j=_e(d.as("y")),k=e<af.s&&["s",e]||1>=f&&["m"]||f<af.m&&["mm",f]||1>=g&&["h"]||g<af.h&&["hh",g]||1>=h&&["d"]||h<af.d&&["dd",h]||1>=i&&["M"]||i<af.M&&["MM",i]||1>=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,ad.apply(null,k)}function cd(a,b){return void 0===af[a]?!1:void 0===b?af[a]:(af[a]=b,!0)}function dd(a){var b=this.localeData(),c=bd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function ed(){var a,b,c,d=bf(this._milliseconds)/1e3,e=bf(this._days),f=bf(this._months);a=q(d/60),b=q(a/60),d%=60,a%=60,c=q(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var fd,gd;gd=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;c>d;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var hd=a.momentProperties=[],id=!1,jd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var kd;kd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)f(a,b)&&c.push(b);return c};var ld,md,nd={},od={},pd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,qd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,rd={},sd={},td=/\d/,ud=/\d\d/,vd=/\d{3}/,wd=/\d{4}/,xd=/[+-]?\d{6}/,yd=/\d\d?/,zd=/\d\d\d\d?/,Ad=/\d\d\d\d\d\d?/,Bd=/\d{1,3}/,Cd=/\d{1,4}/,Dd=/[+-]?\d{1,6}/,Ed=/\d+/,Fd=/[+-]?\d+/,Gd=/Z|[+-]\d\d:?\d\d/gi,Hd=/Z|[+-]\d\d(?::?\d\d)?/gi,Id=/[+-]?\d+(\.\d{1,3})?/,Jd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Kd={},Ld={},Md=0,Nd=1,Od=2,Pd=3,Qd=4,Rd=5,Sd=6,Td=7,Ud=8;md=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b<this.length;++b)if(this[b]===a)return b;return-1},R("M",["MM",2],"Mo",function(){return this.month()+1}),R("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),R("MMMM",0,0,function(a){return this.localeData().months(this,a)}),J("month","M"),W("M",yd),W("MM",yd,ud),W("MMM",function(a,b){return b.monthsShortRegex(a)}),W("MMMM",function(a,b){return b.monthsRegex(a)}),$(["M","MM"],function(a,b){b[Nd]=r(a)-1}),$(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[Nd]=e:j(c).invalidMonth=a});var Vd=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Wd="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Xd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Yd=Jd,Zd=Jd,$d=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,_d=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ae=/Z|[+-]\d\d(?::?\d\d)?/,be=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ce=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],de=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=u("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),R("Y",0,0,function(){var a=this.year();return 9999>=a?""+a:"+"+a}),R(0,["YY",2],0,function(){return this.year()%100}),R(0,["YYYY",4],0,"year"),R(0,["YYYYY",5],0,"year"),R(0,["YYYYYY",6,!0],0,"year"),J("year","y"),W("Y",Fd),W("YY",yd,ud),W("YYYY",Cd,wd),W("YYYYY",Dd,xd),W("YYYYYY",Dd,xd),$(["YYYYY","YYYYYY"],Md),$("YYYY",function(b,c){c[Md]=2===b.length?a.parseTwoDigitYear(b):r(b)}),$("YY",function(b,c){c[Md]=a.parseTwoDigitYear(b)}),$("Y",function(a,b){b[Md]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return r(a)+(r(a)>68?1900:2e3)};var ee=M("FullYear",!0);a.ISO_8601=function(){};var fe=u("moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Ka.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:l()}),ge=u("moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Ka.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:l()}),he=function(){return Date.now?Date.now():+new Date};Qa("Z",":"),Qa("ZZ",""),W("Z",Hd),W("ZZ",Hd),$(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Ra(Hd,a)});var ie=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var je=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,ke=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;db.fn=Oa.prototype;var le=ib(1,"add"),me=ib(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ne=u("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});R(0,["gg",2],0,function(){return this.weekYear()%100}),R(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Pb("gggg","weekYear"),Pb("ggggg","weekYear"),Pb("GGGG","isoWeekYear"),Pb("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),W("G",Fd),W("g",Fd),W("GG",yd,ud),W("gg",yd,ud),W("GGGG",Cd,wd),W("gggg",Cd,wd),W("GGGGG",Dd,xd),W("ggggg",Dd,xd),_(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=r(a)}),_(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),R("Q",0,"Qo","quarter"),J("quarter","Q"),W("Q",td),$("Q",function(a,b){b[Nd]=3*(r(a)-1)}),R("w",["ww",2],"wo","week"),R("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),W("w",yd),W("ww",yd,ud),W("W",yd),W("WW",yd,ud),_(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=r(a)});var oe={dow:0,doy:6};R("D",["DD",2],"Do","date"),J("date","D"),W("D",yd),W("DD",yd,ud),W("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),$(["D","DD"],Od),$("Do",function(a,b){b[Od]=r(a.match(yd)[0],10)});var pe=M("Date",!0);R("d",0,"do","day"),R("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),R("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),R("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),R("e",0,0,"weekday"),R("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),W("d",yd),W("e",yd),W("E",yd),W("dd",function(a,b){return b.weekdaysMinRegex(a)}),W("ddd",function(a,b){return b.weekdaysShortRegex(a)}),W("dddd",function(a,b){return b.weekdaysRegex(a)}),_(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:j(c).invalidWeekday=a}),_(["d","e","E"],function(a,b,c,d){b[d]=r(a)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),re="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),se="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),te=Jd,ue=Jd,ve=Jd;R("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),W("DDD",Bd),W("DDDD",vd),$(["DDD","DDDD"],function(a,b,c){c._dayOfYear=r(a)}),R("H",["HH",2],0,"hour"),R("h",["hh",2],0,oc),R("k",["kk",2],0,pc),R("hmm",0,0,function(){return""+oc.apply(this)+Q(this.minutes(),2)}),R("hmmss",0,0,function(){return""+oc.apply(this)+Q(this.minutes(),2)+Q(this.seconds(),2)}),R("Hmm",0,0,function(){return""+this.hours()+Q(this.minutes(),2)}),R("Hmmss",0,0,function(){return""+this.hours()+Q(this.minutes(),2)+Q(this.seconds(),2)}),qc("a",!0),qc("A",!1),J("hour","h"),W("a",rc),W("A",rc),W("H",yd),W("h",yd),W("HH",yd,ud),W("hh",yd,ud),W("hmm",zd),W("hmmss",Ad),W("Hmm",zd),W("Hmmss",Ad),$(["H","HH"],Pd),$(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),$(["h","hh"],function(a,b,c){b[Pd]=r(a),j(c).bigHour=!0}),$("hmm",function(a,b,c){var d=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d)),j(c).bigHour=!0}),$("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d,2)),b[Rd]=r(a.substr(e)),j(c).bigHour=!0}),$("Hmm",function(a,b,c){var d=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d))}),$("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d,2)),b[Rd]=r(a.substr(e))});var we=/[ap]\.?m?\.?/i,xe=M("Hours",!0);R("m",["mm",2],0,"minute"),J("minute","m"),W("m",yd),W("mm",yd,ud),$(["m","mm"],Qd);var ye=M("Minutes",!1);R("s",["ss",2],0,"second"),J("second","s"),W("s",yd),W("ss",yd,ud),$(["s","ss"],Rd);var ze=M("Seconds",!1);R("S",0,0,function(){return~~(this.millisecond()/100)}),R(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),R(0,["SSS",3],0,"millisecond"),R(0,["SSSS",4],0,function(){return 10*this.millisecond()}),R(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),R(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),R(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),R(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),R(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),W("S",Bd,td),W("SS",Bd,ud),W("SSS",Bd,vd);var Ae;for(Ae="SSSS";Ae.length<=9;Ae+="S")W(Ae,Ed);for(Ae="S";Ae.length<=9;Ae+="S")$(Ae,uc);var Be=M("Milliseconds",!1);R("z",0,0,"zoneAbbr"),R("zz",0,0,"zoneName");var Ce=o.prototype;Ce.add=le,Ce.calendar=kb,Ce.clone=lb,Ce.diff=sb,Ce.endOf=Eb,Ce.format=wb,Ce.from=xb,Ce.fromNow=yb,Ce.to=zb,Ce.toNow=Ab,Ce.get=P,Ce.invalidAt=Nb,Ce.isAfter=mb,Ce.isBefore=nb,Ce.isBetween=ob,Ce.isSame=pb,Ce.isSameOrAfter=qb,Ce.isSameOrBefore=rb,Ce.isValid=Lb,Ce.lang=ne,Ce.locale=Bb,Ce.localeData=Cb,Ce.max=ge,Ce.min=fe,Ce.parsingFlags=Mb,Ce.set=P,Ce.startOf=Db,Ce.subtract=me,Ce.toArray=Ib,Ce.toObject=Jb,Ce.toDate=Hb,Ce.toISOString=vb,Ce.toJSON=Kb,Ce.toString=ub,Ce.unix=Gb,Ce.valueOf=Fb,Ce.creationData=Ob,Ce.year=ee,Ce.isLeapYear=ta,Ce.weekYear=Qb,Ce.isoWeekYear=Rb,Ce.quarter=Ce.quarters=Wb,Ce.month=ha,Ce.daysInMonth=ia,Ce.week=Ce.weeks=$b,Ce.isoWeek=Ce.isoWeeks=_b,Ce.weeksInYear=Tb,Ce.isoWeeksInYear=Sb,Ce.date=pe,Ce.day=Ce.days=gc,Ce.weekday=hc,Ce.isoWeekday=ic,Ce.dayOfYear=nc,Ce.hour=Ce.hours=xe,Ce.minute=Ce.minutes=ye,Ce.second=Ce.seconds=ze,Ce.millisecond=Ce.milliseconds=Be,Ce.utcOffset=Ua,Ce.utc=Wa,Ce.local=Xa,Ce.parseZone=Ya,Ce.hasAlignedHourOffset=Za,Ce.isDST=$a,Ce.isDSTShifted=_a,Ce.isLocal=ab,Ce.isUtcOffset=bb,Ce.isUtc=cb,Ce.isUTC=cb,Ce.zoneAbbr=vc,Ce.zoneName=wc,Ce.dates=u("dates accessor is deprecated. Use date instead.",pe),Ce.months=u("months accessor is deprecated. Use month instead",ha),Ce.years=u("years accessor is deprecated. Use year instead",ee),Ce.zone=u("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Va);var De=Ce,Ee={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Fe={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Ge="Invalid date",He="%d",Ie=/\d{1,2}/,Je={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Ke=A.prototype;Ke._calendar=Ee,Ke.calendar=zc,Ke._longDateFormat=Fe,Ke.longDateFormat=Ac,Ke._invalidDate=Ge,Ke.invalidDate=Bc,Ke._ordinal=He,Ke.ordinal=Cc,Ke._ordinalParse=Ie,Ke.preparse=Dc,Ke.postformat=Dc,Ke._relativeTime=Je,Ke.relativeTime=Ec,Ke.pastFuture=Fc,Ke.set=y,Ke.months=ca,Ke._months=Wd,Ke.monthsShort=da,Ke._monthsShort=Xd,Ke.monthsParse=fa,Ke._monthsRegex=Zd,Ke.monthsRegex=ka,Ke._monthsShortRegex=Yd,Ke.monthsShortRegex=ja,Ke.week=Xb,Ke._week=oe,Ke.firstDayOfYear=Zb,Ke.firstDayOfWeek=Yb,Ke.weekdays=bc,Ke._weekdays=qe,Ke.weekdaysMin=dc,Ke._weekdaysMin=se,Ke.weekdaysShort=cc,Ke._weekdaysShort=re,Ke.weekdaysParse=fc,Ke._weekdaysRegex=te,Ke.weekdaysRegex=jc,Ke._weekdaysShortRegex=ue,Ke.weekdaysShortRegex=kc,Ke._weekdaysMinRegex=ve,Ke.weekdaysMinRegex=lc,Ke.isPM=sc,Ke._meridiemParse=we,Ke.meridiem=tc,E("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===r(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=u("moment.lang is deprecated. Use moment.locale instead.",E),a.langData=u("moment.langData is deprecated. Use moment.localeData instead.",H);var Le=Math.abs,Me=Yc("ms"),Ne=Yc("s"),Oe=Yc("m"),Pe=Yc("h"),Qe=Yc("d"),Re=Yc("w"),Se=Yc("M"),Te=Yc("y"),Ue=$c("milliseconds"),Ve=$c("seconds"),We=$c("minutes"),Xe=$c("hours"),Ye=$c("days"),Ze=$c("months"),$e=$c("years"),_e=Math.round,af={s:45,m:45,h:22,d:26,M:11},bf=Math.abs,cf=Oa.prototype;cf.abs=Oc,cf.add=Qc,cf.subtract=Rc,cf.as=Wc,cf.asMilliseconds=Me,cf.asSeconds=Ne,cf.asMinutes=Oe,cf.asHours=Pe,cf.asDays=Qe,cf.asWeeks=Re,cf.asMonths=Se,cf.asYears=Te,cf.valueOf=Xc,cf._bubble=Tc,cf.get=Zc,cf.milliseconds=Ue,cf.seconds=Ve,cf.minutes=We,cf.hours=Xe,cf.days=Ye,cf.weeks=_c,cf.months=Ze,cf.years=$e,cf.humanize=dd,cf.toISOString=ed,cf.toString=ed,cf.toJSON=ed,cf.locale=Bb,cf.localeData=Cb,cf.toIsoString=u("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ed),cf.lang=ne,R("X",0,0,"unix"),R("x",0,0,"valueOf"),W("x",Fd),W("X",Id),$("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),$("x",function(a,b,c){c._d=new Date(r(a))}),a.version="2.13.0",b(Ka),a.fn=De,a.min=Ma,a.max=Na,a.now=he,a.utc=h,a.unix=xc,a.months=Jc,a.isDate=d,a.locale=E,a.invalid=l,a.duration=db,a.isMoment=p,a.weekdays=Lc,a.parseZone=yc,a.localeData=H,a.isDuration=Pa,a.monthsShort=Kc,a.weekdaysMin=Nc,a.defineLocale=F,a.updateLocale=G,a.locales=I,a.weekdaysShort=Mc,a.normalizeUnits=K,a.relativeTimeThreshold=cd,a.prototype=De;var df=a;return df}); \ No newline at end of file
diff --git a/vendor/autoload.php b/vendor/autoload.php
index 568834318..f9e0189d7 100644
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
-return ComposerAutoloaderInit85a1cefa95be2f464cf7f947cbc4c785::getLoader();
+return ComposerAutoloaderInit02c7a5bb99a87a4c8dbf069d69b1a15c::getLoader();
diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php
index a78cbe6fb..24ffd3718 100644
--- a/vendor/composer/autoload_files.php
+++ b/vendor/composer/autoload_files.php
@@ -7,10 +7,10 @@ $baseDir = dirname($vendorDir);
return array(
'383eaff206634a77a1be54e64e6459c7' => $vendorDir . '/sabre/uri/lib/functions.php',
+ '3569eecfeed3bcf0bad3c998a494ecb8' => $vendorDir . '/sabre/xml/lib/Deserializer/functions.php',
+ '93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php',
'2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php',
'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php',
'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php',
- '3569eecfeed3bcf0bad3c998a494ecb8' => $vendorDir . '/sabre/xml/lib/Deserializer/functions.php',
- '93aa591bc4ca510c520999e34229ee79' => $vendorDir . '/sabre/xml/lib/Serializer/functions.php',
'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php',
);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
index b7fc0125d..10c9b8207 100644
--- a/vendor/composer/autoload_namespaces.php
+++ b/vendor/composer/autoload_namespaces.php
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
+ 'Psr\\Log\\' => array($vendorDir . '/psr/log'),
);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
index f2df43375..16f7dea85 100644
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInit85a1cefa95be2f464cf7f947cbc4c785
+class ComposerAutoloaderInit02c7a5bb99a87a4c8dbf069d69b1a15c
{
private static $loader;
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit85a1cefa95be2f464cf7f947cbc4c785
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInit85a1cefa95be2f464cf7f947cbc4c785', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInit02c7a5bb99a87a4c8dbf069d69b1a15c', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
- spl_autoload_unregister(array('ComposerAutoloaderInit85a1cefa95be2f464cf7f947cbc4c785', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInit02c7a5bb99a87a4c8dbf069d69b1a15c', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION');
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
- call_user_func(\Composer\Autoload\ComposerStaticInit85a1cefa95be2f464cf7f947cbc4c785::getInitializer($loader));
+ call_user_func(\Composer\Autoload\ComposerStaticInit02c7a5bb99a87a4c8dbf069d69b1a15c::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit85a1cefa95be2f464cf7f947cbc4c785
$loader->register(true);
if ($useStaticLoader) {
- $includeFiles = Composer\Autoload\ComposerStaticInit85a1cefa95be2f464cf7f947cbc4c785::$files;
+ $includeFiles = Composer\Autoload\ComposerStaticInit02c7a5bb99a87a4c8dbf069d69b1a15c::$files;
} else {
$includeFiles = require __DIR__ . '/autoload_files.php';
}
foreach ($includeFiles as $fileIdentifier => $file) {
- composerRequire85a1cefa95be2f464cf7f947cbc4c785($fileIdentifier, $file);
+ composerRequire02c7a5bb99a87a4c8dbf069d69b1a15c($fileIdentifier, $file);
}
return $loader;
}
}
-function composerRequire85a1cefa95be2f464cf7f947cbc4c785($fileIdentifier, $file)
+function composerRequire02c7a5bb99a87a4c8dbf069d69b1a15c($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
require $file;
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index 04dd83351..15dc46f55 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -4,15 +4,15 @@
namespace Composer\Autoload;
-class ComposerStaticInit85a1cefa95be2f464cf7f947cbc4c785
+class ComposerStaticInit02c7a5bb99a87a4c8dbf069d69b1a15c
{
public static $files = array (
'383eaff206634a77a1be54e64e6459c7' => __DIR__ . '/..' . '/sabre/uri/lib/functions.php',
+ '3569eecfeed3bcf0bad3c998a494ecb8' => __DIR__ . '/..' . '/sabre/xml/lib/Deserializer/functions.php',
+ '93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php',
'2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php',
'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php',
'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php',
- '3569eecfeed3bcf0bad3c998a494ecb8' => __DIR__ . '/..' . '/sabre/xml/lib/Deserializer/functions.php',
- '93aa591bc4ca510c520999e34229ee79' => __DIR__ . '/..' . '/sabre/xml/lib/Serializer/functions.php',
'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php',
);
@@ -70,11 +70,22 @@ class ComposerStaticInit85a1cefa95be2f464cf7f947cbc4c785
),
);
+ public static $prefixesPsr0 = array (
+ 'P' =>
+ array (
+ 'Psr\\Log\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/psr/log',
+ ),
+ ),
+ );
+
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInit85a1cefa95be2f464cf7f947cbc4c785::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInit85a1cefa95be2f464cf7f947cbc4c785::$prefixDirsPsr4;
+ $loader->prefixLengthsPsr4 = ComposerStaticInit02c7a5bb99a87a4c8dbf069d69b1a15c::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit02c7a5bb99a87a4c8dbf069d69b1a15c::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInit02c7a5bb99a87a4c8dbf069d69b1a15c::$prefixesPsr0;
}, null, ClassLoader::class);
}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 5714e1c19..835190d7f 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -53,134 +53,18 @@
]
},
{
- "name": "sabre/event",
- "version": "3.0.0",
- "version_normalized": "3.0.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/fruux/sabre-event.git",
- "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-event/zipball/831d586f5a442dceacdcf5e9c4c36a4db99a3534",
- "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534",
- "shasum": ""
- },
- "require": {
- "php": ">=5.5"
- },
- "require-dev": {
- "phpunit/phpunit": "*",
- "sabre/cs": "~0.0.4"
- },
- "time": "2015-11-05 20:14:39",
- "type": "library",
- "installation-source": "dist",
- "autoload": {
- "psr-4": {
- "Sabre\\Event\\": "lib/"
- },
- "files": [
- "lib/coroutine.php",
- "lib/Loop/functions.php",
- "lib/Promise/functions.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Evert Pot",
- "email": "me@evertpot.com",
- "homepage": "http://evertpot.com/",
- "role": "Developer"
- }
- ],
- "description": "sabre/event is a library for lightweight event-based programming",
- "homepage": "http://sabre.io/event/",
- "keywords": [
- "EventEmitter",
- "async",
- "events",
- "hooks",
- "plugin",
- "promise",
- "signal"
- ]
- },
- {
- "name": "sabre/http",
- "version": "4.2.1",
- "version_normalized": "4.2.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/fruux/sabre-http.git",
- "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-http/zipball/2e93bc8321524c67be4ca5b8415daebd4c8bf85e",
- "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e",
- "shasum": ""
- },
- "require": {
- "ext-mbstring": "*",
- "php": ">=5.4",
- "sabre/event": ">=1.0.0,<4.0.0",
- "sabre/uri": "~1.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.3",
- "sabre/cs": "~0.0.1"
- },
- "suggest": {
- "ext-curl": " to make http requests with the Client class"
- },
- "time": "2016-01-06 23:00:08",
- "type": "library",
- "installation-source": "dist",
- "autoload": {
- "files": [
- "lib/functions.php"
- ],
- "psr-4": {
- "Sabre\\HTTP\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Evert Pot",
- "email": "me@evertpot.com",
- "homepage": "http://evertpot.com/",
- "role": "Developer"
- }
- ],
- "description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
- "homepage": "https://github.com/fruux/sabre-http",
- "keywords": [
- "http"
- ]
- },
- {
"name": "sabre/xml",
- "version": "1.4.1",
- "version_normalized": "1.4.1.0",
+ "version": "1.4.2",
+ "version_normalized": "1.4.2.0",
"source": {
"type": "git",
"url": "https://github.com/fruux/sabre-xml.git",
- "reference": "59998046db252634259a878baf1af18159f508f3"
+ "reference": "f48d98c22a4a4bef76cabb5968ffaddbb2bb593e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/59998046db252634259a878baf1af18159f508f3",
- "reference": "59998046db252634259a878baf1af18159f508f3",
+ "url": "https://api.github.com/repos/fruux/sabre-xml/zipball/f48d98c22a4a4bef76cabb5968ffaddbb2bb593e",
+ "reference": "f48d98c22a4a4bef76cabb5968ffaddbb2bb593e",
"shasum": ""
},
"require": {
@@ -195,7 +79,7 @@
"phpunit/phpunit": "*",
"sabre/cs": "~0.0.2"
},
- "time": "2016-03-12 22:23:16",
+ "time": "2016-05-19 21:56:49",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -331,18 +215,174 @@
]
},
{
+ "name": "sabre/event",
+ "version": "3.0.0",
+ "version_normalized": "3.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-event.git",
+ "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-event/zipball/831d586f5a442dceacdcf5e9c4c36a4db99a3534",
+ "reference": "831d586f5a442dceacdcf5e9c4c36a4db99a3534",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*",
+ "sabre/cs": "~0.0.4"
+ },
+ "time": "2015-11-05 20:14:39",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Sabre\\Event\\": "lib/"
+ },
+ "files": [
+ "lib/coroutine.php",
+ "lib/Loop/functions.php",
+ "lib/Promise/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "sabre/event is a library for lightweight event-based programming",
+ "homepage": "http://sabre.io/event/",
+ "keywords": [
+ "EventEmitter",
+ "async",
+ "events",
+ "hooks",
+ "plugin",
+ "promise",
+ "signal"
+ ]
+ },
+ {
+ "name": "sabre/http",
+ "version": "4.2.1",
+ "version_normalized": "4.2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/fruux/sabre-http.git",
+ "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/fruux/sabre-http/zipball/2e93bc8321524c67be4ca5b8415daebd4c8bf85e",
+ "reference": "2e93bc8321524c67be4ca5b8415daebd4c8bf85e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.4",
+ "sabre/event": ">=1.0.0,<4.0.0",
+ "sabre/uri": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.3",
+ "sabre/cs": "~0.0.1"
+ },
+ "suggest": {
+ "ext-curl": " to make http requests with the Client class"
+ },
+ "time": "2016-01-06 23:00:08",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
+ "psr-4": {
+ "Sabre\\HTTP\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Evert Pot",
+ "email": "me@evertpot.com",
+ "homepage": "http://evertpot.com/",
+ "role": "Developer"
+ }
+ ],
+ "description": "The sabre/http library provides utilities for dealing with http requests and responses. ",
+ "homepage": "https://github.com/fruux/sabre-http",
+ "keywords": [
+ "http"
+ ]
+ },
+ {
+ "name": "psr/log",
+ "version": "1.0.0",
+ "version_normalized": "1.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+ "shasum": ""
+ },
+ "time": "2012-12-21 11:40:51",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "Psr\\Log\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ]
+ },
+ {
"name": "sabre/dav",
- "version": "3.1.3",
- "version_normalized": "3.1.3.0",
+ "version": "3.2.0",
+ "version_normalized": "3.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/fruux/sabre-dav.git",
- "reference": "8a266c7b5e140da79529414b9cde2a2d058b536b"
+ "reference": "5b9737cc2f0182e368d14c80df7f6b2d77dc1457"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/8a266c7b5e140da79529414b9cde2a2d058b536b",
- "reference": "8a266c7b5e140da79529414b9cde2a2d058b536b",
+ "url": "https://api.github.com/repos/fruux/sabre-dav/zipball/5b9737cc2f0182e368d14c80df7f6b2d77dc1457",
+ "reference": "5b9737cc2f0182e368d14c80df7f6b2d77dc1457",
"shasum": ""
},
"require": {
@@ -356,14 +396,16 @@
"ext-spl": "*",
"lib-libxml": ">=2.7.0",
"php": ">=5.5.0",
+ "psr/log": "^1.0",
"sabre/event": ">=2.0.0, <4.0.0",
"sabre/http": "^4.2.1",
- "sabre/uri": "~1.0",
- "sabre/vobject": "~4.0",
- "sabre/xml": "~1.0"
+ "sabre/uri": "^1.0.1",
+ "sabre/vobject": "^4.1.0",
+ "sabre/xml": "^1.4.0"
},
"require-dev": {
"evert/phpdoc-md": "~0.1.0",
+ "monolog/monolog": "^1.18",
"phpunit/phpunit": "> 4.8, <=6.0.0",
"sabre/cs": "~0.0.5"
},
@@ -371,7 +413,7 @@
"ext-curl": "*",
"ext-pdo": "*"
},
- "time": "2016-04-07 01:02:57",
+ "time": "2016-06-28 02:44:05",
"bin": [
"bin/sabredav",
"bin/naturalselection"
diff --git a/vendor/psr/log/.gitignore b/vendor/psr/log/.gitignore
new file mode 100644
index 000000000..22d0d82f8
--- /dev/null
+++ b/vendor/psr/log/.gitignore
@@ -0,0 +1 @@
+vendor
diff --git a/vendor/psr/log/LICENSE b/vendor/psr/log/LICENSE
new file mode 100644
index 000000000..474c952b4
--- /dev/null
+++ b/vendor/psr/log/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 PHP Framework Interoperability Group
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/psr/log/Psr/Log/AbstractLogger.php b/vendor/psr/log/Psr/Log/AbstractLogger.php
new file mode 100644
index 000000000..00f903452
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/AbstractLogger.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger implementation that other Loggers can inherit from.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+abstract class AbstractLogger implements LoggerInterface
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function emergency($message, array $context = array())
+ {
+ $this->log(LogLevel::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php
new file mode 100644
index 000000000..67f852d1d
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Psr\Log;
+
+class InvalidArgumentException extends \InvalidArgumentException
+{
+}
diff --git a/vendor/psr/log/Psr/Log/LogLevel.php b/vendor/psr/log/Psr/Log/LogLevel.php
new file mode 100644
index 000000000..e32c151cb
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LogLevel.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes log levels
+ */
+class LogLevel
+{
+ const EMERGENCY = 'emergency';
+ const ALERT = 'alert';
+ const CRITICAL = 'critical';
+ const ERROR = 'error';
+ const WARNING = 'warning';
+ const NOTICE = 'notice';
+ const INFO = 'info';
+ const DEBUG = 'debug';
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerAwareInterface.php b/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
new file mode 100644
index 000000000..2eebc4ebd
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger-aware instance
+ */
+interface LoggerAwareInterface
+{
+ /**
+ * Sets a logger instance on the object
+ *
+ * @param LoggerInterface $logger
+ * @return null
+ */
+ public function setLogger(LoggerInterface $logger);
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerAwareTrait.php b/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
new file mode 100644
index 000000000..f087a3dac
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Basic Implementation of LoggerAwareInterface.
+ */
+trait LoggerAwareTrait
+{
+ /** @var LoggerInterface */
+ protected $logger;
+
+ /**
+ * Sets a logger.
+ *
+ * @param LoggerInterface $logger
+ */
+ public function setLogger(LoggerInterface $logger)
+ {
+ $this->logger = $logger;
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php
new file mode 100644
index 000000000..476bb962a
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerInterface.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger instance
+ *
+ * The message MUST be a string or object implementing __toString().
+ *
+ * The message MAY contain placeholders in the form: {foo} where foo
+ * will be replaced by the context data in key "foo".
+ *
+ * The context array can contain arbitrary data, the only assumption that
+ * can be made by implementors is that if an Exception instance is given
+ * to produce a stack trace, it MUST be in a key named "exception".
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
+ * for the full interface specification.
+ */
+interface LoggerInterface
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function emergency($message, array $context = array());
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function alert($message, array $context = array());
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function critical($message, array $context = array());
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function error($message, array $context = array());
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function warning($message, array $context = array());
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function notice($message, array $context = array());
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function info($message, array $context = array());
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function debug($message, array $context = array());
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function log($level, $message, array $context = array());
+}
diff --git a/vendor/psr/log/Psr/Log/LoggerTrait.php b/vendor/psr/log/Psr/Log/LoggerTrait.php
new file mode 100644
index 000000000..591249600
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/LoggerTrait.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger trait that classes unable to extend AbstractLogger
+ * (because they extend another class, etc) can include.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+trait LoggerTrait
+{
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function emergency($message, array $context = array())
+ {
+ $this->log(LogLevel::EMERGENCY, $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log(LogLevel::ALERT, $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log(LogLevel::CRITICAL, $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log(LogLevel::ERROR, $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log(LogLevel::WARNING, $message, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log(LogLevel::NOTICE, $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log(LogLevel::INFO, $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log(LogLevel::DEBUG, $message, $context);
+ }
+
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ abstract public function log($level, $message, array $context = array());
+}
diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php
new file mode 100644
index 000000000..553a3c593
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/NullLogger.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This Logger can be used to avoid conditional log calls
+ *
+ * Logging should always be optional, and if no logger is provided to your
+ * library creating a NullLogger instance to have something to throw logs at
+ * is a good way to avoid littering your code with `if ($this->logger) { }`
+ * blocks.
+ */
+class NullLogger extends AbstractLogger
+{
+ /**
+ * Logs with an arbitrary level.
+ *
+ * @param mixed $level
+ * @param string $message
+ * @param array $context
+ * @return null
+ */
+ public function log($level, $message, array $context = array())
+ {
+ // noop
+ }
+}
diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
new file mode 100644
index 000000000..a93281511
--- /dev/null
+++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace Psr\Log\Test;
+
+use Psr\Log\LogLevel;
+
+/**
+ * Provides a base test class for ensuring compliance with the LoggerInterface
+ *
+ * Implementors can extend the class and implement abstract methods to run this as part of their test suite
+ */
+abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @return LoggerInterface
+ */
+ abstract function getLogger();
+
+ /**
+ * This must return the log messages in order with a simple formatting: "<LOG LEVEL> <MESSAGE>"
+ *
+ * Example ->error('Foo') would yield "error Foo"
+ *
+ * @return string[]
+ */
+ abstract function getLogs();
+
+ public function testImplements()
+ {
+ $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
+ }
+
+ /**
+ * @dataProvider provideLevelsAndMessages
+ */
+ public function testLogsAtAllLevels($level, $message)
+ {
+ $logger = $this->getLogger();
+ $logger->{$level}($message, array('user' => 'Bob'));
+ $logger->log($level, $message, array('user' => 'Bob'));
+
+ $expected = array(
+ $level.' message of level '.$level.' with context: Bob',
+ $level.' message of level '.$level.' with context: Bob',
+ );
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function provideLevelsAndMessages()
+ {
+ return array(
+ LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
+ LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
+ LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
+ LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
+ LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
+ LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
+ LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
+ LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
+ );
+ }
+
+ /**
+ * @expectedException Psr\Log\InvalidArgumentException
+ */
+ public function testThrowsOnInvalidLevel()
+ {
+ $logger = $this->getLogger();
+ $logger->log('invalid level', 'Foo');
+ }
+
+ public function testContextReplacement()
+ {
+ $logger = $this->getLogger();
+ $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+
+ $expected = array('info {Message {nothing} Bob Bar a}');
+ $this->assertEquals($expected, $this->getLogs());
+ }
+
+ public function testObjectCastToString()
+ {
+ $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
+ $dummy->expects($this->once())
+ ->method('__toString')
+ ->will($this->returnValue('DUMMY'));
+
+ $this->getLogger()->warning($dummy);
+ }
+
+ public function testContextCanContainAnything()
+ {
+ $context = array(
+ 'bool' => true,
+ 'null' => null,
+ 'string' => 'Foo',
+ 'int' => 0,
+ 'float' => 0.5,
+ 'nested' => array('with object' => new DummyTest),
+ 'object' => new \DateTime,
+ 'resource' => fopen('php://memory', 'r'),
+ );
+
+ $this->getLogger()->warning('Crazy context data', $context);
+ }
+
+ public function testContextExceptionKeyCanBeExceptionOrOtherValues()
+ {
+ $this->getLogger()->warning('Random message', array('exception' => 'oops'));
+ $this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
+ }
+}
+
+class DummyTest
+{
+} \ No newline at end of file
diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md
new file mode 100644
index 000000000..574bc1cb2
--- /dev/null
+++ b/vendor/psr/log/README.md
@@ -0,0 +1,45 @@
+PSR Log
+=======
+
+This repository holds all interfaces/classes/traits related to
+[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
+
+Note that this is not a logger of its own. It is merely an interface that
+describes a logger. See the specification for more details.
+
+Usage
+-----
+
+If you need a logger, you can use the interface like this:
+
+```php
+<?php
+
+use Psr\Log\LoggerInterface;
+
+class Foo
+{
+ private $logger;
+
+ public function __construct(LoggerInterface $logger = null)
+ {
+ $this->logger = $logger;
+ }
+
+ public function doSomething()
+ {
+ if ($this->logger) {
+ $this->logger->info('Doing work');
+ }
+
+ // do something useful
+ }
+}
+```
+
+You can then pick one of the implementations of the interface to get a logger.
+
+If you want to implement the interface, you can require this package and
+implement `Psr\Log\LoggerInterface` in your code. Please read the
+[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+for details.
diff --git a/vendor/sabre/dav/.travis.yml b/vendor/sabre/dav/.travis.yml
index 48c88b169..a9189c981 100644
--- a/vendor/sabre/dav/.travis.yml
+++ b/vendor/sabre/dav/.travis.yml
@@ -3,12 +3,6 @@ php:
- 5.5
- 5.6
- 7
- - hhvm
-
-matrix:
- fast_finish: true
- allow_failures:
- - php: hhvm
env:
matrix:
@@ -17,17 +11,25 @@ env:
services:
- mysql
+ - postgresql
sudo: false
-cache: vendor
-
before_script:
- - mysql -e 'create database sabredav'
+ - mysql -e 'create database sabredav_test'
+ - psql -c "create database sabredav_test" -U postgres
+ - psql -c "create user sabredav with PASSWORD 'sabredav';GRANT ALL PRIVILEGES ON DATABASE sabredav_test TO sabredav" -U postgres
+ - phpenv config-rm xdebug.ini; true
# - composer self-update
- - composer update --prefer-source $LOWEST_DEPS
+ - composer update --prefer-dist $LOWEST_DEPS
+
+# addons:
+# postgresql: "9.5"
script:
- - ./bin/phpunit --configuration tests/phpunit.xml $TEST_DEPS
+ - ./bin/phpunit --configuration tests/phpunit.xml.dist $TEST_DEPS
- ./bin/sabre-cs-fixer fix lib/ --dry-run --diff
+cache:
+ directories:
+ - $HOME/.composer/cache
diff --git a/vendor/sabre/dav/CHANGELOG.md b/vendor/sabre/dav/CHANGELOG.md
index f719c8e1a..d8a3898c3 100644
--- a/vendor/sabre/dav/CHANGELOG.md
+++ b/vendor/sabre/dav/CHANGELOG.md
@@ -1,6 +1,106 @@
ChangeLog
=========
+3.2.0 (2016-06-27)
+------------------
+
+* The default ACL rules allow an unauthenticated user to read information
+ about nodes that don't have their own ACL defined. This was a security
+ problem.
+* The zip release ships with [sabre/vobject 4.1.0][vobj],
+ [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt],
+ [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.2][xml].
+
+
+3.2.0-beta1 (2016-05-20)
+------------------------
+
+* #833: Calendars throw exceptions when the sharing plugin is not enabled.
+* #834: Return vCards exactly as they were stored if we don't need to convert
+ in between versions.
+* The zip release ships with [sabre/vobject 4.1.0][vobj],
+ [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt],
+ [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml].
+
+
+3.2.0-alpha1 (2016-05-09)
+-------------------------
+
+* Database changes for CalDAV. If you are using the CalDAV PDO backends, you
+ must migrate. Run `./bin/migrateto32.php` for more info.
+* Support for WebDAV Resource Sharing, an upcoming standard.
+* Added support for sharing in the CalDAV PDO backend! Users can now invite
+ others to their calendar and give them read/read-write access!
+* #397: Support for PSR-3. You can now log exceptions with your favourite
+ psr3-compatible logging tool.
+* #825: Actual proper, tested support for PostgreSQL. We require version 9.5.
+* Removed database migration script for sabre/dav 1.7. To update from that
+ version you now first need to update to sabre/dav 3.1.
+* Removed deprecated function: `Sabre\DAV\Auth\Plugin::getCurrentUser()`.
+* #774: Fixes for getting free disk space on Windows.
+* #803: Major changes in the sharing API. If you were using an old sabre/dav
+ sharing api, head to the website for more detailed migration notes.
+* #657: Support for optional auth using `{DAV:}unauthorized` and `{DAV:}all`
+ privileges. This allows you to assign a privilege to a resource, allowing
+ non-authenticated users to access it. For instance, this could allow you
+ to create a public read-only collection.
+* #812 #814: ICS/VCF exporter now includes a more useful filename in its
+ `Content-Disposition` header. (@Xenopathic).
+* #801: BC break: If you were using the `Href` object before, it's behavior
+ now changed a bit, and `LocalHref` was added to replace the old, default
+ behavior of `Href`. See the migration doc for more info.
+* Removed `Sabre\DAVACL\Plugin::$allowAccessToNodesWithoutACL` setting.
+ Instead, you can provide a set of default ACL rules with
+ `Sabre\DAVACL\Plugin::setDefaultAcl()`.
+* Introduced `Sabre\DAVACL\ACLTrait` which contains a default implementation
+ of `Sabre\DAV\IACL` with some sane defaults. We're using this trait all over
+ the place now, reducing the amount of boilerplate.
+* Plugins can now control the "Supported Privilege Set".
+* Added Sharing, ICSExport and VCFExport plugins to `groupwareserver.php`
+ example.
+* The `{DAV:}all` privilege is now no longer abstract, so it can be assigned
+ directly. We're using the `{DAV:}all` privilege now in a lot of cases where
+ we before assigned both `{DAV:}read` and `{DAV:}write`.
+* Resources that are not collections no longer support the `{DAV:}bind` and
+ `{DAV:}unbind` privileges.
+* Corrected the CalDAV-scheduling related privileges.
+* Doing an `UNLOCK` no longer requires the `{DAV:}write-content` privilege.
+* Added a new `getPrincipalByUri` plugin event. Allowing plugins to request
+ quickly where a principal lives on a server.
+* Renamed `phpunit.xml` to `phpunit.xml.dist` to make local modifications easy.
+* Functionality from `IShareableCalendar` is merged into `ISharedCalendar`.
+* #751: Fixed XML responses from failing `MKCOL` requests.
+* #600: Support for `principal-match` ACL `REPORT`.
+* #599: Support for `acl-principal-prop-set` ACL `REPORT`.
+* #798: Added an index on `firstoccurence` field in MySQL CalDAV backend. This
+ should speed up common calendar-query requests.
+* #759: DAV\Client is now able to actually correctly resolve relative urls.
+* #671: We are no longer checking the `read-free-busy` privilege on individual
+ calendars during freebusy operations in the scheduling plugin. Instead, we
+ check the `schedule-query-freebusy` privilege on the target users' inbox,
+ which validates access for the entire account, per the spec.
+* The zip release ships with [sabre/vobject 4.1.0][vobj],
+ [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt],
+ [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.1][xml].
+
+
+3.1.5 (????-??-??)
+------------------
+
+* Fixed: Creating a new calendar on some MySQL configurations caused an error.
+
+
+3.1.4 (2016-05-28)
+------------------
+
+* #834: Backport from `master`: Return vCards exactly as they were stored if
+ we don't need to convert in between versions. This should speed up many
+ large addressbook syncs sometimes up to 50%.
+* The zip release ships with [sabre/vobject 4.1.0][vobj],
+ [sabre/http 4.2.1][http], [sabre/event 3.0.0][evnt],
+ [sabre/uri 1.1.0][uri] and [sabre/xml 1.4.2][xml].
+
+
3.1.3 (2016-04-06)
------------------
diff --git a/vendor/sabre/dav/README.md b/vendor/sabre/dav/README.md
index 278187b55..8edcd4073 100644
--- a/vendor/sabre/dav/README.md
+++ b/vendor/sabre/dav/README.md
@@ -1,10 +1,10 @@
-![sabre's logo](http://sabre.io/img/logo.png) SabreDAV
-======================================================
+![sabre's logo](http://sabre.io/img/logo.png) sabre/dav
+=======================================================
Introduction
------------
-SabreDAV is the most popular WebDAV framework for PHP. Use it to create WebDAV, CalDAV and CardDAV servers.
+sabre/dav is the most popular WebDAV framework for PHP. Use it to create WebDAV, CalDAV and CardDAV servers.
Full documentation can be found on the website:
@@ -16,6 +16,7 @@ Build status
| branch | status | minimum PHP version |
| ------------ | ------ | ------------------- |
| master | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=master)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.5 |
+| 3.1 | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=3.0)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.5 |
| 3.0 | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=3.0)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.4 |
| 2.1 | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=2.1)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.4 |
| 2.0 | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=2.0)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.4 |
@@ -23,6 +24,12 @@ Build status
| 1.7 | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=1.7)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.3 |
| 1.6 | [![Build Status](https://travis-ci.org/fruux/sabre-dav.svg?branch=1.6)](https://travis-ci.org/fruux/sabre-dav) | PHP 5.3 |
+Documentation
+-------------
+
+* [Introduction](http://sabre.io/dav/).
+* [Installation](http://sabre.io/dav/install/).
+
Made at fruux
-------------
diff --git a/vendor/sabre/dav/bin/build.php b/vendor/sabre/dav/bin/build.php
index 82b1e7530..c4ba20941 100755..100644
--- a/vendor/sabre/dav/bin/build.php
+++ b/vendor/sabre/dav/bin/build.php
@@ -110,7 +110,7 @@ function test() {
echo " Running all unittests.\n";
echo " This may take a while.\n\n";
- system(__DIR__ . '/phpunit --configuration ' . $baseDir . '/tests/phpunit.xml --stop-on-failure', $code);
+ system(__DIR__ . '/phpunit --configuration ' . $baseDir . '/tests/phpunit.xml.dist --stop-on-failure', $code);
if ($code != 0) {
echo "PHPUnit reported error code $code\n";
die(1);
diff --git a/vendor/sabre/dav/bin/googlecode_upload.py b/vendor/sabre/dav/bin/googlecode_upload.py
index caafd5ded..caafd5ded 100755..100644
--- a/vendor/sabre/dav/bin/googlecode_upload.py
+++ b/vendor/sabre/dav/bin/googlecode_upload.py
diff --git a/vendor/sabre/dav/bin/migrateto17.php b/vendor/sabre/dav/bin/migrateto17.php
deleted file mode 100755
index a1173c584..000000000
--- a/vendor/sabre/dav/bin/migrateto17.php
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-echo "SabreDAV migrate script for version 1.7\n";
-
-if ($argc < 2) {
-
- echo <<<HELLO
-
-This script help you migrate from a pre-1.7 database to 1.7 and later\n
-Both the 'calendarobjects' and 'calendars' tables will be upgraded.
-
-If you do not have this table, or don't use the default PDO CalDAV backend
-it's pointless to run this script.
-
-Keep in mind that some processing will be done on every single record of this
-table and in addition, ALTER TABLE commands will be executed.
-If you have a large calendarobjects table, this may mean that this process
-takes a while.
-
-Usage:
-
-php {$argv[0]} [pdo-dsn] [username] [password]
-
-For example:
-
-php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
-php {$argv[0]} sqlite:data/sabredav.db
-
-HELLO;
-
- exit();
-
-}
-
-// There's a bunch of places where the autoloader could be, so we'll try all of
-// them.
-$paths = [
- __DIR__ . '/../vendor/autoload.php',
- __DIR__ . '/../../../autoload.php',
-];
-
-foreach ($paths as $path) {
- if (file_exists($path)) {
- include $path;
- break;
- }
-}
-
-$dsn = $argv[1];
-$user = isset($argv[2]) ? $argv[2] : null;
-$pass = isset($argv[3]) ? $argv[3] : null;
-
-echo "Connecting to database: " . $dsn . "\n";
-
-$pdo = new PDO($dsn, $user, $pass);
-$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
-
-echo "Validating existing table layout\n";
-
-// The only cross-db way to do this, is to just fetch a single record.
-$row = $pdo->query("SELECT * FROM calendarobjects LIMIT 1")->fetch();
-
-if (!$row) {
- echo "Error: This database did not have any records in the calendarobjects table, you should just recreate the table.\n";
- exit(-1);
-}
-
-$requiredFields = [
- 'id',
- 'calendardata',
- 'uri',
- 'calendarid',
- 'lastmodified',
-];
-
-foreach ($requiredFields as $requiredField) {
- if (!array_key_exists($requiredField, $row)) {
- echo "Error: The current 'calendarobjects' table was missing a field we expected to exist.\n";
- echo "For safety reasons, this process is stopped.\n";
- exit(-1);
- }
-}
-
-$fields17 = [
- 'etag',
- 'size',
- 'componenttype',
- 'firstoccurence',
- 'lastoccurence',
-];
-
-$found = 0;
-foreach ($fields17 as $field) {
- if (array_key_exists($field, $row)) {
- $found++;
- }
-}
-
-if ($found === 0) {
- echo "The database had the 1.6 schema. Table will now be altered.\n";
- echo "This may take some time for large tables\n";
-
- switch ($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)) {
-
- case 'mysql' :
-
- $pdo->exec(<<<SQL
-ALTER TABLE calendarobjects
-ADD etag VARCHAR(32),
-ADD size INT(11) UNSIGNED,
-ADD componenttype VARCHAR(8),
-ADD firstoccurence INT(11) UNSIGNED,
-ADD lastoccurence INT(11) UNSIGNED
-SQL
- );
- break;
- case 'sqlite' :
- $pdo->exec('ALTER TABLE calendarobjects ADD etag text');
- $pdo->exec('ALTER TABLE calendarobjects ADD size integer');
- $pdo->exec('ALTER TABLE calendarobjects ADD componenttype TEXT');
- $pdo->exec('ALTER TABLE calendarobjects ADD firstoccurence integer');
- $pdo->exec('ALTER TABLE calendarobjects ADD lastoccurence integer');
- break;
-
- default :
- die('This upgrade script does not support this driver (' . $pdo->getAttribute(PDO::ATTR_DRIVER_NAME) . ")\n");
-
- }
- echo "Database schema upgraded.\n";
-
-} elseif ($found === 5) {
-
- echo "Database already had the 1.7 schema\n";
-
-} else {
-
- echo "The database had $found out of 5 from the changes for 1.7. This is scary and unusual, so we have to abort.\n";
- echo "You can manually try to upgrade the schema, and then run this script again.\n";
- exit(-1);
-
-}
-
-echo "Now, we need to parse every record and pull out some information.\n";
-
-$result = $pdo->query('SELECT id, calendardata FROM calendarobjects');
-$stmt = $pdo->prepare('UPDATE calendarobjects SET etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ? WHERE id = ?');
-
-echo "Total records found: " . $result->rowCount() . "\n";
-$done = 0;
-$total = $result->rowCount();
-while ($row = $result->fetch()) {
-
- try {
- $newData = getDenormalizedData($row['calendardata']);
- } catch (Exception $e) {
- echo "===\nException caught will trying to parser calendarobject.\n";
- echo "Error message: " . $e->getMessage() . "\n";
- echo "Record id: " . $row['id'] . "\n";
- echo "This record is ignored, you should inspect it to see if there's anything wrong.\n===\n";
- continue;
- }
- $stmt->execute([
- $newData['etag'],
- $newData['size'],
- $newData['componentType'],
- $newData['firstOccurence'],
- $newData['lastOccurence'],
- $row['id'],
- ]);
- $done++;
-
- if ($done % 500 === 0) {
- echo "Completed: $done / $total\n";
- }
-}
-echo "Completed: $done / $total\n";
-
-echo "Checking the calendars table needs changes.\n";
-$row = $pdo->query("SELECT * FROM calendars LIMIT 1")->fetch();
-
-if (array_key_exists('transparent', $row)) {
-
- echo "The calendars table is already up to date\n";
-
-} else {
-
- echo "Adding the 'transparent' field to the calendars table\n";
-
- switch ($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)) {
-
- case 'mysql' :
- $pdo->exec("ALTER TABLE calendars ADD transparent TINYINT(1) NOT NULL DEFAULT '0'");
- break;
- case 'sqlite' :
- $pdo->exec("ALTER TABLE calendars ADD transparent bool");
- break;
-
- default :
- die('This upgrade script does not support this driver (' . $pdo->getAttribute(PDO::ATTR_DRIVER_NAME) . ")\n");
-
- }
-
-}
-
-echo "Process completed!\n";
-
-/**
- * Parses some information from calendar objects, used for optimized
- * calendar-queries.
- *
- * Blantently copied from Sabre\CalDAV\Backend\PDO
- *
- * Returns an array with the following keys:
- * * etag
- * * size
- * * componentType
- * * firstOccurence
- * * lastOccurence
- *
- * @param string $calendarData
- * @return array
- */
-function getDenormalizedData($calendarData) {
-
- $vObject = \Sabre\VObject\Reader::read($calendarData);
- $componentType = null;
- $component = null;
- $firstOccurence = null;
- $lastOccurence = null;
- foreach ($vObject->getComponents() as $component) {
- if ($component->name !== 'VTIMEZONE') {
- $componentType = $component->name;
- break;
- }
- }
- if (!$componentType) {
- throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
- }
- if ($componentType === 'VEVENT') {
- $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();
- // Finding the last occurence is a bit harder
- if (!isset($component->RRULE)) {
- if (isset($component->DTEND)) {
- $lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
- } elseif (isset($component->DURATION)) {
- $endDate = clone $component->DTSTART->getDateTime();
- $endDate->add(\Sabre\VObject\DateTimeParser::parse($component->DURATION->value));
- $lastOccurence = $endDate->getTimeStamp();
- } elseif (!$component->DTSTART->hasTime()) {
- $endDate = clone $component->DTSTART->getDateTime();
- $endDate->modify('+1 day');
- $lastOccurence = $endDate->getTimeStamp();
- } else {
- $lastOccurence = $firstOccurence;
- }
- } else {
- $it = new \Sabre\VObject\Recur\EventIterator($vObject, (string)$component->UID);
- $maxDate = new DateTime(\Sabre\CalDAV\Backend\PDO::MAX_DATE);
- if ($it->isInfinite()) {
- $lastOccurence = $maxDate->getTimeStamp();
- } else {
- $end = $it->getDtEnd();
- while ($it->valid() && $end < $maxDate) {
- $end = $it->getDtEnd();
- $it->next();
-
- }
- $lastOccurence = $end->getTimeStamp();
- }
-
- }
- }
-
- return [
- 'etag' => md5($calendarData),
- 'size' => strlen($calendarData),
- 'componentType' => $componentType,
- 'firstOccurence' => $firstOccurence,
- 'lastOccurence' => $lastOccurence,
- ];
-
-}
diff --git a/vendor/sabre/dav/bin/migrateto20.php b/vendor/sabre/dav/bin/migrateto20.php
index 77236804f..77236804f 100755..100644
--- a/vendor/sabre/dav/bin/migrateto20.php
+++ b/vendor/sabre/dav/bin/migrateto20.php
diff --git a/vendor/sabre/dav/bin/migrateto21.php b/vendor/sabre/dav/bin/migrateto21.php
index f42c4cf88..c81ee5cca 100755..100644
--- a/vendor/sabre/dav/bin/migrateto21.php
+++ b/vendor/sabre/dav/bin/migrateto21.php
@@ -169,10 +169,6 @@ switch ($driver) {
)
');
break;
- $pdo->exec('
- CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);
- ');
- break;
}
echo "Done.\n";
diff --git a/vendor/sabre/dav/bin/migrateto30.php b/vendor/sabre/dav/bin/migrateto30.php
index 9ca77c13c..9ca77c13c 100755..100644
--- a/vendor/sabre/dav/bin/migrateto30.php
+++ b/vendor/sabre/dav/bin/migrateto30.php
diff --git a/vendor/sabre/dav/bin/migrateto32.php b/vendor/sabre/dav/bin/migrateto32.php
new file mode 100644
index 000000000..7567aeb60
--- /dev/null
+++ b/vendor/sabre/dav/bin/migrateto32.php
@@ -0,0 +1,268 @@
+#!/usr/bin/env php
+<?php
+
+echo "SabreDAV migrate script for version 3.2\n";
+
+if ($argc < 2) {
+
+ echo <<<HELLO
+
+This script help you migrate from a 3.1 database to 3.2 and later
+
+Changes:
+* Created a new calendarinstances table to support calendar sharing.
+* Remove a lot of columns from calendars.
+
+Keep in mind that ALTER TABLE commands will be executed. If you have a large
+dataset this may mean that this process takes a while.
+
+Make a back-up first. This script has been tested, but the amount of
+potential variants are extremely high, so it's impossible to deal with every
+possible situation.
+
+In the worst case, you will lose all your data. This is not an overstatement.
+
+Lastly, if you are upgrading from an older version than 3.1, make sure you run
+the earlier migration script first. Migration scripts must be ran in order.
+
+Usage:
+
+php {$argv[0]} [pdo-dsn] [username] [password]
+
+For example:
+
+php {$argv[0]} "mysql:host=localhost;dbname=sabredav" root password
+php {$argv[0]} sqlite:data/sabredav.db
+
+HELLO;
+
+ exit();
+
+}
+
+// There's a bunch of places where the autoloader could be, so we'll try all of
+// them.
+$paths = [
+ __DIR__ . '/../vendor/autoload.php',
+ __DIR__ . '/../../../autoload.php',
+];
+
+foreach ($paths as $path) {
+ if (file_exists($path)) {
+ include $path;
+ break;
+ }
+}
+
+$dsn = $argv[1];
+$user = isset($argv[2]) ? $argv[2] : null;
+$pass = isset($argv[3]) ? $argv[3] : null;
+
+$backupPostfix = time();
+
+echo "Connecting to database: " . $dsn . "\n";
+
+$pdo = new PDO($dsn, $user, $pass);
+$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+
+$driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
+
+switch ($driver) {
+
+ case 'mysql' :
+ echo "Detected MySQL.\n";
+ break;
+ case 'sqlite' :
+ echo "Detected SQLite.\n";
+ break;
+ default :
+ echo "Error: unsupported driver: " . $driver . "\n";
+ die(-1);
+}
+
+echo "Creating 'calendarinstances'\n";
+$addValueType = false;
+try {
+ $result = $pdo->query('SELECT * FROM calendarinstances LIMIT 1');
+ $result->fetch(\PDO::FETCH_ASSOC);
+ echo "calendarinstances exists. Assuming this part of the migration has already been done.\n";
+} catch (Exception $e) {
+ echo "calendarinstances does not yet exist. Creating table and migrating data.\n";
+
+ switch ($driver) {
+ case 'mysql' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendarinstances (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ calendarid INTEGER UNSIGNED NOT NULL,
+ principaluri VARBINARY(100),
+ access TINYINT(1) NOT NULL DEFAULT '1' COMMENT '1 = owner, 2 = read, 3 = readwrite',
+ displayname VARCHAR(100),
+ uri VARBINARY(200),
+ description TEXT,
+ calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ calendarcolor VARBINARY(10),
+ timezone TEXT,
+ transparent TINYINT(1) NOT NULL DEFAULT '0',
+ share_href VARBINARY(100),
+ share_displayname VARCHAR(100),
+ share_invitestatus TINYINT(1) NOT NULL DEFAULT '2' COMMENT '1 = noresponse, 2 = accepted, 3 = declined, 4 = invalid',
+ UNIQUE(principaluri, uri),
+ UNIQUE(calendarid, principaluri),
+ UNIQUE(calendarid, share_href)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+SQL
+ );
+ $pdo->exec("
+INSERT INTO calendarinstances
+ (
+ calendarid,
+ principaluri,
+ access,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+ )
+SELECT
+ id,
+ principaluri,
+ 1,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+FROM calendars
+");
+ break;
+ case 'sqlite' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendarinstances (
+ id integer primary key asc NOT NULL,
+ calendarid integer,
+ principaluri text,
+ access integer COMMENT '1 = owner, 2 = read, 3 = readwrite' NOT NULL DEFAULT '1',
+ displayname text,
+ uri text NOT NULL,
+ description text,
+ calendarorder integer,
+ calendarcolor text,
+ timezone text,
+ transparent bool,
+ share_href text,
+ share_displayname text,
+ share_invitestatus integer DEFAULT '2',
+ UNIQUE (principaluri, uri),
+ UNIQUE (calendarid, principaluri),
+ UNIQUE (calendarid, share_href)
+);
+SQL
+ );
+ $pdo->exec("
+INSERT INTO calendarinstances
+ (
+ calendarid,
+ principaluri,
+ access,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+ )
+SELECT
+ id,
+ principaluri,
+ 1,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ transparent
+FROM calendars
+");
+ break;
+ }
+
+}
+try {
+ $result = $pdo->query('SELECT * FROM calendars LIMIT 1');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+
+ if (!$row) {
+ echo "Source table is empty.\n";
+ $migrateCalendars = true;
+ }
+
+ $columnCount = count($row);
+ if ($columnCount === 3) {
+ echo "The calendars table has 3 columns already. Assuming this part of the migration was already done.\n";
+ $migrateCalendars = false;
+ } else {
+ echo "The calendars table has " . $columnCount . " columns.\n";
+ $migrateCalendars = true;
+ }
+
+} catch (Exception $e) {
+ echo "calendars table does not exist. This is a major problem. Exiting.\n";
+ exit(-1);
+}
+
+if ($migrateCalendars) {
+
+ $calendarBackup = 'calendars_3_1_' . $backupPostfix;
+ echo "Backing up 'calendars' to '", $calendarBackup, "'\n";
+
+ switch ($driver) {
+ case 'mysql' :
+ $pdo->exec('RENAME TABLE calendars TO ' . $calendarBackup);
+ break;
+ case 'sqlite' :
+ $pdo->exec('ALTER TABLE calendars RENAME TO ' . $calendarBackup);
+ break;
+
+ }
+
+ echo "Creating new calendars table.\n";
+ switch ($driver) {
+ case 'mysql' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendars (
+ id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
+ components VARBINARY(21)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+SQL
+);
+ break;
+ case 'sqlite' :
+ $pdo->exec(<<<SQL
+CREATE TABLE calendars (
+ id integer primary key asc NOT NULL,
+ synctoken integer DEFAULT 1 NOT NULL,
+ components text NOT NULL
+);
+SQL
+ );
+ break;
+
+ }
+
+ echo "Migrating data from old to new table\n";
+
+ $pdo->exec(<<<SQL
+INSERT INTO calendars (id, synctoken, components) SELECT id, synctoken, COALESCE(components,"VEVENT,VTODO,VJOURNAL") as components FROM $calendarBackup
+SQL
+ );
+
+}
+
+
+echo "Upgrade to 3.2 schema completed.\n";
diff --git a/vendor/sabre/dav/bin/naturalselection b/vendor/sabre/dav/bin/naturalselection
index 52720e31e..7e20439c1 100755
--- a/vendor/sabre/dav/bin/naturalselection
+++ b/vendor/sabre/dav/bin/naturalselection
@@ -107,7 +107,7 @@ def main():
parser.add_option(
'-m', '--min-erase',
help="Minimum number of bytes to erase when the threshold is reached. " +
- "Setting this option higher will reduce the amount of times the cache directory will need to be scanned. " +
+ "Setting this option higher will reduce the number of times the cache directory will need to be scanned. " +
"(the default is 1073741824, which is 1GB.)",
type="int",
dest="min_erase",
diff --git a/vendor/sabre/dav/bin/sabredav.php b/vendor/sabre/dav/bin/sabredav.php
index 950075d1a..950075d1a 100755..100644
--- a/vendor/sabre/dav/bin/sabredav.php
+++ b/vendor/sabre/dav/bin/sabredav.php
diff --git a/vendor/sabre/dav/examples/addressbookserver.php b/vendor/sabre/dav/examples/addressbookserver.php
deleted file mode 100644
index 6d1c9b26c..000000000
--- a/vendor/sabre/dav/examples/addressbookserver.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-/*
-
-Addressbook/CardDAV server example
-
-This server features CardDAV support
-
-*/
-
-// settings
-date_default_timezone_set('Canada/Eastern');
-
-// Make sure this setting is turned on and reflect the root url for your WebDAV server.
-// This can be for example the root / or a complete path to your server script
-$baseUri = '/';
-
-/* Database */
-$pdo = new PDO('sqlite:data/db.sqlite');
-$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-
-//Mapping PHP errors to exceptions
-function exception_error_handler($errno, $errstr, $errfile, $errline) {
- throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
-}
-set_error_handler("exception_error_handler");
-
-// Autoloader
-require_once 'vendor/autoload.php';
-
-// Backends
-$authBackend = new Sabre\DAV\Auth\Backend\PDO($pdo);
-$principalBackend = new Sabre\DAVACL\PrincipalBackend\PDO($pdo);
-$carddavBackend = new Sabre\CardDAV\Backend\PDO($pdo);
-//$caldavBackend = new Sabre\CalDAV\Backend\PDO($pdo);
-
-// Setting up the directory tree //
-$nodes = [
- new Sabre\DAVACL\PrincipalCollection($principalBackend),
-// new Sabre\CalDAV\CalendarRoot($authBackend, $caldavBackend),
- new Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend),
-];
-
-// The object tree needs in turn to be passed to the server class
-$server = new Sabre\DAV\Server($nodes);
-$server->setBaseUri($baseUri);
-
-// Plugins
-$server->addPlugin(new Sabre\DAV\Auth\Plugin($authBackend));
-$server->addPlugin(new Sabre\DAV\Browser\Plugin());
-//$server->addPlugin(new Sabre\CalDAV\Plugin());
-$server->addPlugin(new Sabre\CardDAV\Plugin());
-$server->addPlugin(new Sabre\DAVACL\Plugin());
-$server->addPlugin(new Sabre\DAV\Sync\Plugin());
-
-// And off we go!
-$server->exec();
diff --git a/vendor/sabre/dav/examples/sql/mysql.addressbook.sql b/vendor/sabre/dav/examples/sql/mysql.addressbook.sql
deleted file mode 100644
index 9ec88babe..000000000
--- a/vendor/sabre/dav/examples/sql/mysql.addressbook.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-CREATE TABLE addressbooks (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- principaluri VARBINARY(255),
- displayname VARCHAR(255),
- uri VARBINARY(200),
- description TEXT,
- synctoken INT(11) UNSIGNED NOT NULL DEFAULT '1',
- UNIQUE(principaluri(100), uri(100))
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE cards (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- addressbookid INT(11) UNSIGNED NOT NULL,
- carddata MEDIUMBLOB,
- uri VARBINARY(200),
- lastmodified INT(11) UNSIGNED,
- etag VARBINARY(32),
- size INT(11) UNSIGNED NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE addressbookchanges (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- uri VARBINARY(200) NOT NULL,
- synctoken INT(11) UNSIGNED NOT NULL,
- addressbookid INT(11) UNSIGNED NOT NULL,
- operation TINYINT(1) NOT NULL,
- INDEX addressbookid_synctoken (addressbookid, synctoken)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/vendor/sabre/dav/examples/sql/mysql.calendars.sql b/vendor/sabre/dav/examples/sql/mysql.calendars.sql
deleted file mode 100644
index d41f11076..000000000
--- a/vendor/sabre/dav/examples/sql/mysql.calendars.sql
+++ /dev/null
@@ -1,64 +0,0 @@
-CREATE TABLE calendarobjects (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- calendardata MEDIUMBLOB,
- uri VARBINARY(200),
- calendarid INTEGER UNSIGNED NOT NULL,
- lastmodified INT(11) UNSIGNED,
- etag VARBINARY(32),
- size INT(11) UNSIGNED NOT NULL,
- componenttype VARBINARY(8),
- firstoccurence INT(11) UNSIGNED,
- lastoccurence INT(11) UNSIGNED,
- uid VARBINARY(200),
- UNIQUE(calendarid, uri)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE calendars (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- principaluri VARBINARY(100),
- displayname VARCHAR(100),
- uri VARBINARY(200),
- synctoken INTEGER UNSIGNED NOT NULL DEFAULT '1',
- description TEXT,
- calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
- calendarcolor VARBINARY(10),
- timezone TEXT,
- components VARBINARY(21),
- transparent TINYINT(1) NOT NULL DEFAULT '0',
- UNIQUE(principaluri, uri)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE calendarchanges (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- uri VARBINARY(200) NOT NULL,
- synctoken INT(11) UNSIGNED NOT NULL,
- calendarid INT(11) UNSIGNED NOT NULL,
- operation TINYINT(1) NOT NULL,
- INDEX calendarid_synctoken (calendarid, synctoken)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE calendarsubscriptions (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- uri VARBINARY(200) NOT NULL,
- principaluri VARBINARY(100) NOT NULL,
- source TEXT,
- displayname VARCHAR(100),
- refreshrate VARCHAR(10),
- calendarorder INT(11) UNSIGNED NOT NULL DEFAULT '0',
- calendarcolor VARBINARY(10),
- striptodos TINYINT(1) NULL,
- stripalarms TINYINT(1) NULL,
- stripattachments TINYINT(1) NULL,
- lastmodified INT(11) UNSIGNED,
- UNIQUE(principaluri, uri)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE schedulingobjects (
- id INT(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- principaluri VARBINARY(255),
- calendardata MEDIUMBLOB,
- uri VARBINARY(200),
- lastmodified INT(11) UNSIGNED,
- etag VARBINARY(32),
- size INT(11) UNSIGNED NOT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/vendor/sabre/dav/examples/sql/mysql.locks.sql b/vendor/sabre/dav/examples/sql/mysql.locks.sql
deleted file mode 100644
index 96a3a88d9..000000000
--- a/vendor/sabre/dav/examples/sql/mysql.locks.sql
+++ /dev/null
@@ -1,12 +0,0 @@
-CREATE TABLE locks (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- owner VARCHAR(100),
- timeout INTEGER UNSIGNED,
- created INTEGER,
- token VARBINARY(100),
- scope TINYINT,
- depth TINYINT,
- uri VARBINARY(1000),
- INDEX(token),
- INDEX(uri(100))
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/vendor/sabre/dav/examples/sql/mysql.principals.sql b/vendor/sabre/dav/examples/sql/mysql.principals.sql
deleted file mode 100644
index ea0d16a27..000000000
--- a/vendor/sabre/dav/examples/sql/mysql.principals.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-CREATE TABLE principals (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- uri VARBINARY(200) NOT NULL,
- email VARBINARY(80),
- displayname VARCHAR(80),
- UNIQUE(uri)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-CREATE TABLE groupmembers (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- principal_id INTEGER UNSIGNED NOT NULL,
- member_id INTEGER UNSIGNED NOT NULL,
- UNIQUE(principal_id, member_id)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-INSERT INTO principals (uri,email,displayname) VALUES
-('principals/admin', 'admin@example.org','Administrator'),
-('principals/admin/calendar-proxy-read', null, null),
-('principals/admin/calendar-proxy-write', null, null);
-
diff --git a/vendor/sabre/dav/examples/sql/mysql.users.sql b/vendor/sabre/dav/examples/sql/mysql.users.sql
deleted file mode 100644
index 22ac312d5..000000000
--- a/vendor/sabre/dav/examples/sql/mysql.users.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-CREATE TABLE users (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- username VARBINARY(50),
- digesta1 VARBINARY(32),
- UNIQUE(username)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
-INSERT INTO users (username,digesta1) VALUES
-('admin', '87fd274b7b6c01e48d7c2f965da8ddf7');
diff --git a/vendor/sabre/dav/examples/sql/pgsql.addressbook.sql b/vendor/sabre/dav/examples/sql/pgsql.addressbook.sql
deleted file mode 100644
index ef2cc5b9a..000000000
--- a/vendor/sabre/dav/examples/sql/pgsql.addressbook.sql
+++ /dev/null
@@ -1,52 +0,0 @@
-CREATE TABLE addressbooks (
- id SERIAL NOT NULL,
- principaluri VARCHAR(255),
- displayname VARCHAR(255),
- uri VARCHAR(200),
- description TEXT,
- synctoken INTEGER NOT NULL DEFAULT 1
-);
-
-ALTER TABLE ONLY addressbooks
- ADD CONSTRAINT addressbooks_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX addressbooks_ukey
- ON addressbooks USING btree (principaluri, uri);
-
-CREATE TABLE cards (
- id SERIAL NOT NULL,
- addressbookid INTEGER NOT NULL,
- carddata TEXT,
- uri VARCHAR(200),
- lastmodified INTEGER,
- etag VARCHAR(32),
- size INTEGER NOT NULL
-);
-
-ALTER TABLE ONLY cards
- ADD CONSTRAINT cards_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX cards_ukey
- ON cards USING btree (addressbookid, uri);
-
-ALTER TABLE ONLY cards
- ADD CONSTRAINT cards_addressbookid_fkey FOREIGN KEY (addressbookid) REFERENCES addressbooks(id)
- ON DELETE CASCADE;
-
-CREATE TABLE addressbookchanges (
- id SERIAL NOT NULL,
- uri VARCHAR(200) NOT NULL,
- synctoken INTEGER NOT NULL,
- addressbookid INTEGER NOT NULL,
- operation SMALLINT NOT NULL
-);
-
-ALTER TABLE ONLY addressbookchanges
- ADD CONSTRAINT addressbookchanges_pkey PRIMARY KEY (id);
-
-CREATE INDEX addressbookchanges_addressbookid_synctoken_ix
- ON addressbookchanges USING btree (addressbookid, synctoken);
-
-ALTER TABLE ONLY addressbookchanges
- ADD CONSTRAINT addressbookchanges_addressbookid_fkey FOREIGN KEY (addressbookid) REFERENCES addressbooks(id)
- ON DELETE CASCADE;
diff --git a/vendor/sabre/dav/examples/sql/pgsql.calendars.sql b/vendor/sabre/dav/examples/sql/pgsql.calendars.sql
deleted file mode 100644
index d31084b86..000000000
--- a/vendor/sabre/dav/examples/sql/pgsql.calendars.sql
+++ /dev/null
@@ -1,93 +0,0 @@
-CREATE TABLE calendars (
- id SERIAL NOT NULL,
- principaluri VARCHAR(100),
- displayname VARCHAR(100),
- uri VARCHAR(200),
- synctoken INTEGER NOT NULL DEFAULT 1,
- description TEXT,
- calendarorder INTEGER NOT NULL DEFAULT 0,
- calendarcolor VARCHAR(10),
- timezone TEXT,
- components VARCHAR(20),
- uid VARCHAR(200),
- transparent SMALLINT NOT NULL DEFAULT '0'
-);
-
-ALTER TABLE ONLY calendars
- ADD CONSTRAINT calendars_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX calendars_ukey
- ON calendars USING btree (principaluri, uri);
-
-CREATE TABLE calendarobjects (
- id SERIAL NOT NULL,
- calendardata TEXT,
- uri VARCHAR(200),
- calendarid INTEGER NOT NULL,
- lastmodified INTEGER,
- etag VARCHAR(32),
- size INTEGER NOT NULL,
- componenttype VARCHAR(8),
- firstoccurence INTEGER,
- lastoccurence INTEGER,
- uid VARCHAR(200)
-);
-
-ALTER TABLE ONLY calendarobjects
- ADD CONSTRAINT calendarobjects_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX calendarobjects_ukey
- ON calendarobjects USING btree (calendarid, uri);
-
-ALTER TABLE ONLY calendarobjects
- ADD CONSTRAINT calendarobjects_calendarid_fkey FOREIGN KEY (calendarid) REFERENCES calendars(id)
- ON DELETE CASCADE;
-
-CREATE TABLE calendarsubscriptions (
- id SERIAL NOT NULL,
- uri VARCHAR(200) NOT NULL,
- principaluri VARCHAR(100) NOT NULL,
- source TEXT,
- displayname VARCHAR(100),
- refreshrate VARCHAR(10),
- calendarorder INTEGER NOT NULL DEFAULT 0,
- calendarcolor VARCHAR(10),
- striptodos SMALLINT NULL,
- stripalarms SMALLINT NULL,
- stripattachments SMALLINT NULL,
- lastmodified INTEGER
-);
-
-ALTER TABLE ONLY calendarsubscriptions
- ADD CONSTRAINT calendarsubscriptions_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX calendarsubscriptions_ukey
- ON calendarsubscriptions USING btree (principaluri, uri);
-
-CREATE TABLE calendarchanges (
- id SERIAL NOT NULL,
- uri VARCHAR(200) NOT NULL,
- synctoken INTEGER NOT NULL,
- calendarid INTEGER NOT NULL,
- operation SMALLINT NOT NULL DEFAULT 0
-);
-
-ALTER TABLE ONLY calendarchanges
- ADD CONSTRAINT calendarchanges_pkey PRIMARY KEY (id);
-
-CREATE INDEX calendarchanges_calendarid_synctoken_ix
- ON calendarchanges USING btree (calendarid, synctoken);
-
-ALTER TABLE ONLY calendarchanges
- ADD CONSTRAINT calendarchanges_calendar_fk FOREIGN KEY (calendarid) REFERENCES calendars(id)
- ON DELETE CASCADE;
-
-CREATE TABLE schedulingobjects (
- id SERIAL NOT NULL,
- principaluri VARCHAR(255),
- calendardata BYTEA,
- uri VARCHAR(200),
- lastmodified INTEGER,
- etag VARCHAR(32),
- size INTEGER NOT NULL
-);
diff --git a/vendor/sabre/dav/examples/sql/pgsql.locks.sql b/vendor/sabre/dav/examples/sql/pgsql.locks.sql
deleted file mode 100644
index 0290528ce..000000000
--- a/vendor/sabre/dav/examples/sql/pgsql.locks.sql
+++ /dev/null
@@ -1,19 +0,0 @@
-CREATE TABLE locks (
- id SERIAL NOT NULL,
- owner VARCHAR(100),
- timeout INTEGER,
- created INTEGER,
- token VARCHAR(100),
- scope SMALLINT,
- depth SMALLINT,
- uri TEXT
-);
-
-ALTER TABLE ONLY locks
- ADD CONSTRAINT locks_pkey PRIMARY KEY (id);
-
-CREATE INDEX locks_token_ix
- ON locks USING btree (token);
-
-CREATE INDEX locks_uri_ix
- ON locks USING btree (uri);
diff --git a/vendor/sabre/dav/examples/sql/pgsql.principals.sql b/vendor/sabre/dav/examples/sql/pgsql.principals.sql
deleted file mode 100644
index 9157acde0..000000000
--- a/vendor/sabre/dav/examples/sql/pgsql.principals.sql
+++ /dev/null
@@ -1,38 +0,0 @@
-CREATE TABLE principals (
- id SERIAL NOT NULL,
- uri VARCHAR(200) NOT NULL,
- email VARCHAR(80),
- displayname VARCHAR(80)
-);
-
-ALTER TABLE ONLY principals
- ADD CONSTRAINT principals_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX principals_ukey
- ON principals USING btree (uri);
-
-CREATE TABLE groupmembers (
- id SERIAL NOT NULL,
- principal_id INTEGER NOT NULL,
- member_id INTEGER NOT NULL
-);
-
-ALTER TABLE ONLY groupmembers
- ADD CONSTRAINT groupmembers_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX groupmembers_ukey
- ON groupmembers USING btree (principal_id, member_id);
-
-ALTER TABLE ONLY groupmembers
- ADD CONSTRAINT groupmembers_principal_id_fkey FOREIGN KEY (principal_id) REFERENCES principals(id)
- ON DELETE CASCADE;
-
-ALTER TABLE ONLY groupmembers
- ADD CONSTRAINT groupmembers_member_id_id_fkey FOREIGN KEY (member_id) REFERENCES principals(id)
- ON DELETE CASCADE;
-
-INSERT INTO principals (uri,email,displayname) VALUES
-('principals/admin', 'admin@example.org','Administrator'),
-('principals/admin/calendar-proxy-read', null, null),
-('principals/admin/calendar-proxy-write', null, null);
-
diff --git a/vendor/sabre/dav/examples/sql/pgsql.users.sql b/vendor/sabre/dav/examples/sql/pgsql.users.sql
deleted file mode 100644
index 9d6047b8c..000000000
--- a/vendor/sabre/dav/examples/sql/pgsql.users.sql
+++ /dev/null
@@ -1,14 +0,0 @@
-CREATE TABLE users (
- id SERIAL NOT NULL,
- username VARCHAR(50),
- digesta1 VARCHAR(32)
-);
-
-ALTER TABLE ONLY users
- ADD CONSTRAINT users_pkey PRIMARY KEY (id);
-
-CREATE UNIQUE INDEX users_ukey
- ON users USING btree (username);
-
-INSERT INTO users (username,digesta1) VALUES
-('admin', '87fd274b7b6c01e48d7c2f965da8ddf7');
diff --git a/vendor/sabre/dav/examples/sql/sqlite.addressbooks.sql b/vendor/sabre/dav/examples/sql/sqlite.addressbooks.sql
deleted file mode 100644
index 0baed8bfb..000000000
--- a/vendor/sabre/dav/examples/sql/sqlite.addressbooks.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-CREATE TABLE addressbooks (
- id integer primary key asc NOT NULL,
- principaluri text NOT NULL,
- displayname text,
- uri text NOT NULL,
- description text,
- synctoken integer DEFAULT 1 NOT NULL
-);
-
-CREATE TABLE cards (
- id integer primary key asc NOT NULL,
- addressbookid integer NOT NULL,
- carddata blob,
- uri text NOT NULL,
- lastmodified integer,
- etag text,
- size integer
-);
-
-CREATE TABLE addressbookchanges (
- id integer primary key asc NOT NULL,
- uri text,
- synctoken integer NOT NULL,
- addressbookid integer NOT NULL,
- operation integer NOT NULL
-);
-
-CREATE INDEX addressbookid_synctoken ON addressbookchanges (addressbookid, synctoken);
diff --git a/vendor/sabre/dav/examples/sql/sqlite.calendars.sql b/vendor/sabre/dav/examples/sql/sqlite.calendars.sql
deleted file mode 100644
index a8654032d..000000000
--- a/vendor/sabre/dav/examples/sql/sqlite.calendars.sql
+++ /dev/null
@@ -1,64 +0,0 @@
-CREATE TABLE calendarobjects (
- id integer primary key asc NOT NULL,
- calendardata blob NOT NULL,
- uri text NOT NULL,
- calendarid integer NOT NULL,
- lastmodified integer NOT NULL,
- etag text NOT NULL,
- size integer NOT NULL,
- componenttype text,
- firstoccurence integer,
- lastoccurence integer,
- uid text
-);
-
-CREATE TABLE calendars (
- id integer primary key asc NOT NULL,
- principaluri text NOT NULL,
- displayname text,
- uri text NOT NULL,
- synctoken integer DEFAULT 1 NOT NULL,
- description text,
- calendarorder integer,
- calendarcolor text,
- timezone text,
- components text NOT NULL,
- transparent bool
-);
-
-CREATE TABLE calendarchanges (
- id integer primary key asc NOT NULL,
- uri text,
- synctoken integer NOT NULL,
- calendarid integer NOT NULL,
- operation integer NOT NULL
-);
-
-CREATE INDEX calendarid_synctoken ON calendarchanges (calendarid, synctoken);
-
-CREATE TABLE calendarsubscriptions (
- id integer primary key asc NOT NULL,
- uri text NOT NULL,
- principaluri text NOT NULL,
- source text NOT NULL,
- displayname text,
- refreshrate text,
- calendarorder integer,
- calendarcolor text,
- striptodos bool,
- stripalarms bool,
- stripattachments bool,
- lastmodified int
-);
-
-CREATE TABLE schedulingobjects (
- id integer primary key asc NOT NULL,
- principaluri text NOT NULL,
- calendardata blob,
- uri text NOT NULL,
- lastmodified integer,
- etag text NOT NULL,
- size integer NOT NULL
-);
-
-CREATE INDEX principaluri_uri ON calendarsubscriptions (principaluri, uri);
diff --git a/vendor/sabre/dav/examples/sql/sqlite.locks.sql b/vendor/sabre/dav/examples/sql/sqlite.locks.sql
deleted file mode 100644
index 622baea42..000000000
--- a/vendor/sabre/dav/examples/sql/sqlite.locks.sql
+++ /dev/null
@@ -1,12 +0,0 @@
-BEGIN TRANSACTION;
-CREATE TABLE locks (
- id integer primary key asc NOT NULL,
- owner text,
- timeout integer,
- created integer,
- token text,
- scope integer,
- depth integer,
- uri text
-);
-COMMIT;
diff --git a/vendor/sabre/dav/examples/sql/sqlite.principals.sql b/vendor/sabre/dav/examples/sql/sqlite.principals.sql
deleted file mode 100644
index 4105156f8..000000000
--- a/vendor/sabre/dav/examples/sql/sqlite.principals.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-CREATE TABLE principals (
- id INTEGER PRIMARY KEY ASC NOT NULL,
- uri TEXT NOT NULL,
- email TEXT,
- displayname TEXT,
- UNIQUE(uri)
-);
-
-CREATE TABLE groupmembers (
- id INTEGER PRIMARY KEY ASC NOT NULL,
- principal_id INTEGER NOT NULL,
- member_id INTEGER NOT NULL,
- UNIQUE(principal_id, member_id)
-);
-
-
-INSERT INTO principals (uri,email,displayname) VALUES ('principals/admin', 'admin@example.org','Administrator');
-INSERT INTO principals (uri,email,displayname) VALUES ('principals/admin/calendar-proxy-read', null, null);
-INSERT INTO principals (uri,email,displayname) VALUES ('principals/admin/calendar-proxy-write', null, null);
-
diff --git a/vendor/sabre/dav/examples/sql/sqlite.users.sql b/vendor/sabre/dav/examples/sql/sqlite.users.sql
deleted file mode 100644
index 5597b058a..000000000
--- a/vendor/sabre/dav/examples/sql/sqlite.users.sql
+++ /dev/null
@@ -1,9 +0,0 @@
-CREATE TABLE users (
- id integer primary key asc NOT NULL,
- username TEXT NOT NULL,
- digesta1 TEXT NOT NULL,
- UNIQUE(username)
-);
-
-INSERT INTO users (username,digesta1) VALUES
-('admin', '87fd274b7b6c01e48d7c2f965da8ddf7');
diff --git a/vendor/sabre/dav/examples/webserver/apache2_htaccess.conf b/vendor/sabre/dav/examples/webserver/apache2_htaccess.conf
deleted file mode 100644
index c5f29ba80..000000000
--- a/vendor/sabre/dav/examples/webserver/apache2_htaccess.conf
+++ /dev/null
@@ -1,16 +0,0 @@
-RewriteEngine On
-# This makes every request go to server.php
-RewriteRule (.*) server.php [L]
-
-# Output buffering needs to be off, to prevent high memory usage
-php_flag output_buffering off
-
-# This is also to prevent high memory usage
-php_flag always_populate_raw_post_data off
-
-# This is almost a given, but magic quotes is *still* on on some
-# linux distributions
-php_flag magic_quotes_gpc off
-
-# SabreDAV is not compatible with mbstring function overloading
-php_flag mbstring.func_overload off
diff --git a/vendor/sabre/dav/examples/webserver/apache2_vhost.conf b/vendor/sabre/dav/examples/webserver/apache2_vhost.conf
deleted file mode 100644
index 74289641e..000000000
--- a/vendor/sabre/dav/examples/webserver/apache2_vhost.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-# This is a sample configuration to setup a dedicated Apache vhost for WebDAV.
-#
-# The main thing that should be configured is the servername, and the path to
-# your SabreDAV installation (DocumentRoot).
-#
-# This configuration assumed mod_php5 is used, as it sets a few default php
-# settings as well.
-<VirtualHost *:*>
-
- # Don't forget to change the server name
- # ServerName dav.example.org
-
- # The DocumentRoot is also required
- # DocumentRoot /home/sabredav/
-
- RewriteEngine On
- # This makes every request go to server.php
- RewriteRule ^/(.*)$ /server.php [L]
-
- # Output buffering needs to be off, to prevent high memory usage
- php_flag output_buffering off
-
- # This is also to prevent high memory usage
- php_flag always_populate_raw_post_data off
-
- # SabreDAV is not compatible with mbstring function overloading
- php_flag mbstring.func_overload off
-
-</VirtualHost *:*>
diff --git a/vendor/sabre/dav/examples/webserver/apache2_vhost_cgi.conf b/vendor/sabre/dav/examples/webserver/apache2_vhost_cgi.conf
deleted file mode 100644
index 607254c6e..000000000
--- a/vendor/sabre/dav/examples/webserver/apache2_vhost_cgi.conf
+++ /dev/null
@@ -1,21 +0,0 @@
-# This is a sample configuration to setup a dedicated Apache vhost for WebDAV.
-#
-# The main thing that should be configured is the servername, and the path to
-# your SabreDAV installation (DocumentRoot).
-#
-# This configuration assumes CGI or FastCGI is used.
-<VirtualHost *:*>
-
- # Don't forget to change the server name
- # ServerName dav.example.org
-
- # The DocumentRoot is also required
- # DocumentRoot /home/sabredav/
-
- # This makes every request go to server.php. This also makes sure
- # the Authentication information is available. If your server script is
- # not called server.php, be sure to change it.
- RewriteEngine On
- RewriteRule ^/(.*)$ /server.php [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
-
-</VirtualHost *:*>
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php b/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php
index 7513fb60d..bd8ee7602 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/BackendInterface.php
@@ -44,10 +44,12 @@ interface BackendInterface {
* If the creation was a success, an id must be returned that can be used to
* reference this calendar in other methods, such as updateCalendar.
*
+ * The id can be any type, including ints, strings, objects or array.
+ *
* @param string $principalUri
* @param string $calendarUri
* @param array $properties
- * @return void
+ * @return mixed
*/
function createCalendar($principalUri, $calendarUri, array $properties);
@@ -63,7 +65,7 @@ interface BackendInterface {
*
* Read the PropPatch documentation for more info and examples.
*
- * @param string $path
+ * @param mixed $calendarId
* @param \Sabre\DAV\PropPatch $propPatch
* @return void
*/
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php b/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
index 19b9b22a7..9c00a89ef 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/NotificationSupport.php
@@ -43,4 +43,19 @@ interface NotificationSupport extends BackendInterface {
*/
function deleteNotification($principalUri, NotificationInterface $notification);
+ /**
+ * This method is called when a user replied to a request to share.
+ *
+ * If the user chose to accept the share, this method should return the
+ * newly created calendar url.
+ *
+ * @param string href The sharee who is replying (often a mailto: address)
+ * @param int status One of the SharingPlugin::STATUS_* constants
+ * @param string $calendarUri The url to the calendar thats being shared
+ * @param string $inReplyTo The unique id this message is a response to
+ * @param string $summary A description of the reply
+ * @return null|string
+ */
+ function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
+
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
index 76b69dc6e..95f1d49a6 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php
@@ -2,10 +2,11 @@
namespace Sabre\CalDAV\Backend;
-use Sabre\VObject;
use Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\Exception\Forbidden;
+use Sabre\VObject;
+use Sabre\DAV\Xml\Element\Sharee;
/**
* PDO CalDAV backend
@@ -17,7 +18,12 @@ use Sabre\DAV\Exception\Forbidden;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport {
+class PDO extends AbstractBackend
+ implements
+ SyncSupport,
+ SubscriptionSupport,
+ SchedulingSupport,
+ SharingSupport {
/**
* We need to specify a max date, because we need to stop *somewhere*
@@ -44,6 +50,16 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
public $calendarTableName = 'calendars';
/**
+ * The table name that will be used for calendars instances.
+ *
+ * A single calendar can have multiple instances, if the calendar is
+ * shared.
+ *
+ * @var string
+ */
+ public $calendarInstancesTableName = 'calendarinstances';
+
+ /**
* The table name that will be used for calendar objects
*
* @var string
@@ -140,16 +156,23 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
function getCalendarsForUser($principalUri) {
$fields = array_values($this->propertyMap);
- $fields[] = 'id';
+ $fields[] = 'calendarid';
$fields[] = 'uri';
$fields[] = 'synctoken';
$fields[] = 'components';
$fields[] = 'principaluri';
$fields[] = 'transparent';
+ $fields[] = 'access';
// Making fields a comma-delimited list
$fields = implode(', ', $fields);
- $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM " . $this->calendarTableName . " WHERE principaluri = ? ORDER BY calendarorder ASC");
+ $stmt = $this->pdo->prepare(<<<SQL
+SELECT {$this->calendarInstancesTableName}.id as id, $fields FROM {$this->calendarInstancesTableName}
+ LEFT JOIN {$this->calendarTableName} ON
+ {$this->calendarInstancesTableName}.calendarid = {$this->calendarTableName}.id
+WHERE principaluri = ? ORDER BY calendarorder ASC
+SQL
+ );
$stmt->execute([$principalUri]);
$calendars = [];
@@ -161,15 +184,27 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
}
$calendar = [
- 'id' => $row['id'],
+ 'id' => [(int)$row['calendarid'], (int)$row['id']],
'uri' => $row['uri'],
'principaluri' => $row['principaluri'],
'{' . CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken'] ? $row['synctoken'] : '0'),
'{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
'{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet($components),
'{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
+ 'share-resource-uri' => '/ns/share/' . $row['calendarid'],
];
+ $calendar['share-access'] = (int)$row['access'];
+ // 1 = owner, 2 = readonly, 3 = readwrite
+ if ($row['access'] > 1) {
+ // We need to find more information about the original owner.
+ //$stmt2 = $this->pdo->prepare('SELECT principaluri FROM ' . $this->calendarInstancesTableName . ' WHERE access = 1 AND id = ?');
+ //$stmt2->execute([$row['id']]);
+
+ // read-only is for backwards compatbility. Might go away in
+ // the future.
+ $calendar['read-only'] = (int)$row['access'] === \Sabre\DAV\Sharing\Plugin::ACCESS_READ;
+ }
foreach ($this->propertyMap as $xmlName => $dbName) {
$calendar[$xmlName] = $row[$dbName];
@@ -199,31 +234,38 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$fieldNames = [
'principaluri',
'uri',
- 'synctoken',
'transparent',
+ 'calendarid',
];
$values = [
':principaluri' => $principalUri,
':uri' => $calendarUri,
- ':synctoken' => 1,
':transparent' => 0,
];
- // Default value
+
$sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
- $fieldNames[] = 'components';
if (!isset($properties[$sccs])) {
- $values[':components'] = 'VEVENT,VTODO';
+ // Default value
+ $components = 'VEVENT,VTODO';
} else {
if (!($properties[$sccs] instanceof CalDAV\Xml\Property\SupportedCalendarComponentSet)) {
throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet');
}
- $values[':components'] = implode(',', $properties[$sccs]->getValue());
+ $components = implode(',', $properties[$sccs]->getValue());
}
$transp = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp';
if (isset($properties[$transp])) {
- $values[':transparent'] = $properties[$transp]->getValue() === 'transparent';
+ $values[':transparent'] = $properties[$transp]->getValue() === 'transparent' ? 1 : 0;
}
+ $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarTableName . " (synctoken, components) VALUES (1, ?)");
+ $stmt->execute([$components]);
+
+ $calendarId = $this->pdo->lastInsertId(
+ $this->calendarTableName . '_id_seq'
+ );
+
+ $values[':calendarid'] = $calendarId;
foreach ($this->propertyMap as $xmlName => $dbName) {
if (isset($properties[$xmlName])) {
@@ -233,10 +275,14 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
}
}
- $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
+ $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarInstancesTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
+
$stmt->execute($values);
- return $this->pdo->lastInsertId();
+ return [
+ $calendarId,
+ $this->pdo->lastInsertId($this->calendarInstancesTableName . '_id_seq')
+ ];
}
@@ -252,16 +298,21 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
*
* Read the PropPatch documenation for more info and examples.
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @param \Sabre\DAV\PropPatch $propPatch
* @return void
*/
function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$supportedProperties = array_keys($this->propertyMap);
$supportedProperties[] = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp';
- $propPatch->handle($supportedProperties, function($mutations) use ($calendarId) {
+ $propPatch->handle($supportedProperties, function($mutations) use ($calendarId, $instanceId) {
$newValues = [];
foreach ($mutations as $propertyName => $propertyValue) {
@@ -282,8 +333,8 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$valuesSql[] = $fieldName . ' = ?';
}
- $stmt = $this->pdo->prepare("UPDATE " . $this->calendarTableName . " SET " . implode(', ', $valuesSql) . " WHERE id = ?");
- $newValues['id'] = $calendarId;
+ $stmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET " . implode(', ', $valuesSql) . " WHERE id = ?");
+ $newValues['id'] = $instanceId;
$stmt->execute(array_values($newValues));
$this->addChange($calendarId, "", 2);
@@ -297,19 +348,49 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
/**
* Delete a calendar and all it's objects
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @return void
*/
function deleteCalendar($calendarId) {
- $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?');
- $stmt->execute([$calendarId]);
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
- $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarTableName . ' WHERE id = ?');
- $stmt->execute([$calendarId]);
+ $stmt = $this->pdo->prepare('SELECT access FROM ' . $this->calendarInstancesTableName . ' where id = ?');
+ $stmt->execute([$instanceId]);
+ $access = (int)$stmt->fetchColumn();
+
+ if ($access === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) {
+
+ /**
+ * If the user is the owner of the calendar, we delete all data and all
+ * instances.
+ **/
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarChangesTableName . ' WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarInstancesTableName . ' WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarTableName . ' WHERE id = ?');
+ $stmt->execute([$calendarId]);
+
+ } else {
+
+ /**
+ * If it was an instance of a shared calendar, we only delete that
+ * instance.
+ */
+ $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?');
+ $stmt->execute([$instanceId]);
+
+ }
- $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarChangesTableName . ' WHERE calendarid = ?');
- $stmt->execute([$calendarId]);
}
@@ -341,11 +422,16 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
* used/fetched to determine these numbers. If both are specified the
* amount of times this is needed is reduced by a great degree.
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @return array
*/
function getCalendarObjects($calendarId) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?');
$stmt->execute([$calendarId]);
@@ -354,9 +440,8 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$result[] = [
'id' => $row['id'],
'uri' => $row['uri'],
- 'lastmodified' => $row['lastmodified'],
+ 'lastmodified' => (int)$row['lastmodified'],
'etag' => '"' . $row['etag'] . '"',
- 'calendarid' => $row['calendarid'],
'size' => (int)$row['size'],
'component' => strtolower($row['componenttype']),
];
@@ -378,12 +463,17 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
*
* This method must return null if the object did not exist.
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @param string $objectUri
* @return array|null
*/
function getCalendarObject($calendarId, $objectUri) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri = ?');
$stmt->execute([$calendarId, $objectUri]);
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
@@ -393,9 +483,8 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
return [
'id' => $row['id'],
'uri' => $row['uri'],
- 'lastmodified' => $row['lastmodified'],
+ 'lastmodified' => (int)$row['lastmodified'],
'etag' => '"' . $row['etag'] . '"',
- 'calendarid' => $row['calendarid'],
'size' => (int)$row['size'],
'calendardata' => $row['calendardata'],
'component' => strtolower($row['componenttype']),
@@ -417,6 +506,11 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
*/
function getMultipleCalendarObjects($calendarId, array $uris) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri IN (';
// Inserting a whole bunch of question marks
$query .= implode(',', array_fill(0, count($uris), '?'));
@@ -431,9 +525,8 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$result[] = [
'id' => $row['id'],
'uri' => $row['uri'],
- 'lastmodified' => $row['lastmodified'],
+ 'lastmodified' => (int)$row['lastmodified'],
'etag' => '"' . $row['etag'] . '"',
- 'calendarid' => $row['calendarid'],
'size' => (int)$row['size'],
'calendardata' => $row['calendardata'],
'component' => strtolower($row['componenttype']),
@@ -465,6 +558,11 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
*/
function createCalendarObject($calendarId, $objectUri, $calendarData) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$extraData = $this->getDenormalizedData($calendarData);
$stmt = $this->pdo->prepare('INSERT INTO ' . $this->calendarObjectTableName . ' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence, uid) VALUES (?,?,?,?,?,?,?,?,?,?)');
@@ -506,6 +604,11 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
*/
function updateCalendarObject($calendarId, $objectUri, $calendarData) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$extraData = $this->getDenormalizedData($calendarData);
$stmt = $this->pdo->prepare('UPDATE ' . $this->calendarObjectTableName . ' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ?, uid = ? WHERE calendarid = ? AND uri = ?');
@@ -583,6 +686,10 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
}
}
+
+ // Ensure Occurence values are positive
+ if ($firstOccurence < 0) $firstOccurence = 0;
+ if ($lastOccurence < 0) $lastOccurence = 0;
}
// Destroy circular references to PHP will GC the object.
@@ -604,12 +711,17 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
*
* The object uri is only the basename, or filename and not a full path.
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @param string $objectUri
* @return void
*/
function deleteCalendarObject($calendarId, $objectUri) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri = ?');
$stmt->execute([$calendarId, $objectUri]);
@@ -665,12 +777,17 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
* This specific implementation (for the PDO) backend optimizes filters on
* specific components, and VEVENT time-ranges.
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @param array $filters
* @return array
*/
function calendarQuery($calendarId, array $filters) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
$componentType = null;
$requirePostFilter = true;
$timeRange = null;
@@ -766,14 +883,14 @@ class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, S
$query = <<<SQL
SELECT
- calendars.uri AS calendaruri, calendarobjects.uri as objecturi
+ calendar_instances.uri AS calendaruri, calendarobjects.uri as objecturi
FROM
$this->calendarObjectTableName AS calendarobjects
LEFT JOIN
- $this->calendarTableName AS calendars
- ON calendarobjects.calendarid = calendars.id
+ $this->calendarInstancesTableName AS calendar_instances
+ ON calendarobjects.calendarid = calendar_instances.calendarid
WHERE
- calendars.principaluri = ?
+ calendar_instances.principaluri = ?
AND
calendarobjects.uid = ?
SQL;
@@ -837,7 +954,7 @@ SQL;
*
* The limit is 'suggestive'. You are free to ignore it.
*
- * @param string $calendarId
+ * @param mixed $calendarId
* @param string $syncToken
* @param int $syncLevel
* @param int $limit
@@ -845,6 +962,11 @@ SQL;
*/
function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null) {
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
// Current synctoken
$stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->calendarTableName . ' WHERE id = ?');
$stmt->execute([ $calendarId ]);
@@ -1043,7 +1165,9 @@ SQL;
$stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarSubscriptionsTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
$stmt->execute($values);
- return $this->pdo->lastInsertId();
+ return $this->pdo->lastInsertId(
+ $this->calendarSubscriptionsTableName . '_id_seq'
+ );
}
@@ -1207,4 +1331,179 @@ SQL;
}
+ /**
+ * Updates the list of shares.
+ *
+ * @param mixed $calendarId
+ * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
+ * @return void
+ */
+ function updateInvites($calendarId, array $sharees) {
+
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
+ }
+ $currentInvites = $this->getInvites($calendarId);
+ list($calendarId, $instanceId) = $calendarId;
+
+ $removeStmt = $this->pdo->prepare("DELETE FROM " . $this->calendarInstancesTableName . " WHERE calendarid = ? AND share_href = ? AND access IN (2,3)");
+ $updateStmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET access = ?, share_displayname = ?, share_invitestatus = ? WHERE calendarid = ? AND share_href = ?");
+
+ $insertStmt = $this->pdo->prepare('
+INSERT INTO ' . $this->calendarInstancesTableName . '
+ (
+ calendarid,
+ principaluri,
+ access,
+ displayname,
+ uri,
+ description,
+ calendarorder,
+ calendarcolor,
+ timezone,
+ transparent,
+ share_href,
+ share_displayname,
+ share_invitestatus
+ )
+ SELECT
+ ?,
+ ?,
+ ?,
+ displayname,
+ ?,
+ description,
+ calendarorder,
+ calendarcolor,
+ timezone,
+ 1,
+ ?,
+ ?,
+ ?
+ FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?');
+
+ foreach ($sharees as $sharee) {
+
+ if ($sharee->access === \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS) {
+ // if access was set no NOACCESS, it means access for an
+ // existing sharee was removed.
+ $removeStmt->execute([$calendarId, $sharee->href]);
+ continue;
+ }
+
+ if (is_null($sharee->principal)) {
+ // If the server could not determine the principal automatically,
+ // we will mark the invite status as invalid.
+ $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_INVALID;
+ } else {
+ // Because sabre/dav does not yet have an invitation system,
+ // every invite is automatically accepted for now.
+ $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED;
+ }
+
+ foreach ($currentInvites as $oldSharee) {
+
+ if ($oldSharee->href === $sharee->href) {
+ // This is an update
+ $sharee->properties = array_merge(
+ $oldSharee->properties,
+ $sharee->properties
+ );
+ $updateStmt->execute([
+ $sharee->access,
+ isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null,
+ $sharee->inviteStatus ?: $oldSharee->inviteStatus,
+ $calendarId,
+ $sharee->href
+ ]);
+ continue 2;
+ }
+
+ }
+ // If we got here, it means it was a new sharee
+ $insertStmt->execute([
+ $calendarId,
+ $sharee->principal,
+ $sharee->access,
+ \Sabre\DAV\UUIDUtil::getUUID(),
+ $sharee->href,
+ isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null,
+ $sharee->inviteStatus ?: \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE,
+ $instanceId
+ ]);
+
+ }
+
+ }
+
+ /**
+ * Returns the list of people whom a calendar is shared with.
+ *
+ * Every item in the returned list must be a Sharee object with at
+ * least the following properties set:
+ * $href
+ * $shareAccess
+ * $inviteStatus
+ *
+ * and optionally:
+ * $properties
+ *
+ * @param mixed $calendarId
+ * @return \Sabre\DAV\Xml\Element\Sharee[]
+ */
+ function getInvites($calendarId) {
+
+ if (!is_array($calendarId)) {
+ throw new \InvalidArgumentException('The value passed to getInvites() is expected to be an array with a calendarId and an instanceId');
+ }
+ list($calendarId, $instanceId) = $calendarId;
+
+ $query = <<<SQL
+SELECT
+ principaluri,
+ access,
+ share_href,
+ share_displayname,
+ share_invitestatus
+FROM {$this->calendarInstancesTableName}
+WHERE
+ calendarid = ?
+SQL;
+
+ $stmt = $this->pdo->prepare($query);
+ $stmt->execute([$calendarId]);
+
+ $result = [];
+ while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+
+ $result[] = new Sharee([
+ 'href' => isset($row['share_href']) ? $row['share_href'] : \Sabre\HTTP\encodePath($row['principaluri']),
+ 'access' => (int)$row['access'],
+ /// Everyone is always immediately accepted, for now.
+ 'inviteStatus' => (int)$row['share_invitestatus'],
+ 'properties' =>
+ !empty($row['share_displayname'])
+ ? [ '{DAV:}displayname' => $row['share_displayname'] ]
+ : [],
+ 'principal' => $row['principaluri'],
+ ]);
+
+ }
+ return $result;
+
+ }
+
+ /**
+ * Publishes a calendar
+ *
+ * @param mixed $calendarId
+ * @param bool $value
+ * @return void
+ */
+ function setPublishStatus($calendarId, $value) {
+
+ throw new \Sabre\DAV\Exception\NotImplemented('Not implemented');
+
+ }
+
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php b/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
index 6a11b0ab1..8b6e074e0 100644
--- a/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/SharingSupport.php
@@ -5,231 +5,48 @@ namespace Sabre\CalDAV\Backend;
/**
* Adds support for sharing features to a CalDAV server.
*
- * Note: This feature is experimental, and may change in between different
- * SabreDAV versions.
+ * CalDAV backends that implement this interface, must make the following
+ * modifications to getCalendarsForUser:
*
- * Early warning: Currently SabreDAV provides no implementation for this. This
- * is, because in it's current state there is no elegant way to do this.
- * The problem lies in the fact that a real CalDAV server with sharing support
- * would first need email support (with invite notifications), and really also
- * a browser-frontend that allows people to accept or reject these shares.
- *
- * In addition, the CalDAV backends are currently kept as independent as
- * possible, and should not be aware of principals, email addresses or
- * accounts.
- *
- * Adding an implementation for Sharing to standard-sabredav would contradict
- * these goals, so for this reason this is currently not implemented, although
- * it may very well in the future; but probably not before SabreDAV 2.0.
- *
- * The interface works however, so if you implement all this, and do it
- * correctly sharing _will_ work. It's not particularly easy, and I _urge you_
- * to make yourself acquainted with the following document first:
- *
- * https://trac.calendarserver.org/browser/CalendarServer/trunk/doc/Extensions/caldav-sharing.txt
- *
- * An overview
- * ===========
- *
- * Implementing this interface will allow a user to share his or her calendars
- * to other users. Effectively, when a calendar is shared the calendar will
- * show up in both the Sharer's and Sharee's calendar-home root.
- * This interface adds a few methods that ensure that this happens, and there
- * are also a number of new requirements in the base-class you must now follow.
- *
- *
- * How it works
- * ============
- *
- * When a user shares a calendar, the updateShares() method will be called with
- * a list of sharees that are now added, and a list of sharees that have been
- * removed.
- * Removal is instant, but when a sharee is added the sharee first gets a
- * chance to accept or reject the invitation for a share.
- *
- * After a share is accepted, the calendar will be returned from
- * getUserCalendars for both the sharer, and the sharee.
- *
- * If the sharee deletes the calendar, only their share gets deleted. When the
- * owner deletes a calendar, it will be removed for everybody.
- *
- *
- * Notifications
- * =============
- *
- * During all these sharing operations, a lot of notifications are sent back
- * and forward.
- *
- * Whenever the list of sharees for a calendar has been changed (they have been
- * added, removed or modified) all sharees should get a notification for this
- * change.
- * This notification is always represented by:
- *
- * Sabre\CalDAV\Notifications\Notification\Invite
- *
- * In the case of an invite, the sharee may reply with an 'accept' or
- * 'decline'. These are always represented by:
- *
- * Sabre\CalDAV\Notifications\Notification\InviteReply
- *
- *
- * Calendar access by sharees
- * ==========================
- *
- * As mentioned earlier, shared calendars must now also be returned for
- * getCalendarsForUser for sharees. A few things change though.
- *
- * The following properties must be specified:
- *
- * 1. {http://calendarserver.org/ns/}shared-url
- *
- * This property MUST contain the url to the original calendar, that is.. the
- * path to the calendar from the owner.
- *
- * 2. {http://sabredav.org/ns}owner-principal
- *
- * This is a url to to the principal who is sharing the calendar.
- *
- * 3. {http://sabredav.org/ns}read-only
- *
- * This should be either 0 or 1, depending on if the user has read-only or
- * read-write access to the calendar.
- *
- * Only when this is done, the calendar will correctly be marked as a calendar
- * that's shared to him, thus allowing clients to display the correct interface
- * and ACL enforcement.
- *
- * If a sharee deletes their calendar, only their instance of the calendar
- * should be deleted, the original should still exists.
- * Pretty much any 'dead' WebDAV properties on these shared calendars should be
- * specific to a user. This means that if the displayname is changed by a
- * sharee, the original is not affected. This is also true for:
- * * The description
- * * The color
- * * The order
- * * And any other dead properties.
- *
- * Properties like a ctag should not be different for multiple instances of the
- * calendar.
- *
- * Lastly, objects *within* calendars should also have user-specific data. The
- * two things that are user-specific are:
- * * VALARM objects
- * * The TRANSP property
- *
- * This _also_ implies that if a VALARM is deleted by a sharee for some event,
- * this has no effect on the original VALARM.
- *
- * Understandably, the this last requirement is one of the hardest.
- * Realisticly, I can see people ignoring this part of the spec, but that could
- * cause a different set of issues.
- *
- *
- * Publishing
- * ==========
- *
- * When a user publishes a url, the server should generate a 'publish url'.
- * This is a read-only url, anybody can use to consume the calendar feed.
- *
- * Calendars are in one of two states:
- * * published
- * * unpublished
- *
- * If a calendar is published, the following property should be returned
- * for each calendar in getCalendarsForUser.
- *
- * {http://calendarserver.org/ns/}publish-url
- *
- * This element should contain a {DAV:}href element, which points to the
- * public url that does not require authentication. Unlike every other href,
- * this url must be absolute.
- *
- * Ideally, the following property is always returned
- *
- * {http://calendarserver.org/ns/}pre-publish-url
- *
- * This property should contain the url that the calendar _would_ have, if it
- * were to be published. iCal uses this to display the url, before the user
- * will actually publish it.
- *
- *
- * Selectively disabling publish or share feature
- * ==============================================
- *
- * If Sabre\CalDAV\Property\AllowedSharingModes is returned from
- * getCalendarsForUser, this allows the server to specify whether either sharing,
- * or publishing is supported.
- *
- * This allows a client to determine in advance which features are available,
- * and update the interface appropriately. If this property is not returned by
- * the backend, the SharingPlugin automatically injects it and assumes both
- * features are available.
+ * 1. Return shared calendars for users.
+ * 2. For every calendar, return calendar-resource-uri. This strings is a URI or
+ * relative URI reference that must be unique for every calendar, but
+ * identical for every instance of the same shared calenar.
+ * 3. For every calenar, you must return a share-access element. This element
+ * should contain one of the Sabre\DAV\Sharing\Plugin:ACCESS_* contants and
+ * indicates the access level the user has.
*
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-interface SharingSupport extends NotificationSupport {
+interface SharingSupport extends BackendInterface {
/**
* Updates the list of shares.
*
- * The first array is a list of people that are to be added to the
- * calendar.
- *
- * Every element in the add array has the following properties:
- * * href - A url. Usually a mailto: address
- * * commonName - Usually a first and last name, or false
- * * summary - A description of the share, can also be false
- * * readOnly - A boolean value
- *
- * Every element in the remove array is just the address string.
- *
- * Note that if the calendar is currently marked as 'not shared' by and
- * this method is called, the calendar should be 'upgraded' to a shared
- * calendar.
- *
* @param mixed $calendarId
- * @param array $add
- * @param array $remove
+ * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
* @return void
*/
- function updateShares($calendarId, array $add, array $remove);
+ function updateInvites($calendarId, array $sharees);
/**
* Returns the list of people whom this calendar is shared with.
*
- * Every element in this array should have the following properties:
- * * href - Often a mailto: address
- * * commonName - Optional, for example a first + last name
- * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
- * * readOnly - boolean
- * * summary - Optional, a description for the share
+ * Every item in the returned list must be a Sharee object with at
+ * least the following properties set:
+ * $href
+ * $shareAccess
+ * $inviteStatus
*
- * This method may be called by either the original instance of the
- * calendar, as well as the shared instances. In the case of the shared
- * instances, it is perfectly acceptable to return an empty array in case
- * there are privacy concerns.
+ * and optionally:
+ * $properties
*
* @param mixed $calendarId
- * @return array
- */
- function getShares($calendarId);
-
- /**
- * This method is called when a user replied to a request to share.
- *
- * If the user chose to accept the share, this method should return the
- * newly created calendar url.
- *
- * @param string href The sharee who is replying (often a mailto: address)
- * @param int status One of the SharingPlugin::STATUS_* constants
- * @param string $calendarUri The url to the calendar thats being shared
- * @param string $inReplyTo The unique id this message is a response to
- * @param string $summary A description of the reply
- * @return null|string
+ * @return \Sabre\DAV\Xml\Element\Sharee[]
*/
- function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null);
+ function getInvites($calendarId);
/**
* Publishes a calendar
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php b/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
new file mode 100644
index 000000000..f8238ea9a
--- /dev/null
+++ b/vendor/sabre/dav/lib/CalDAV/Backend/SimplePDO.php
@@ -0,0 +1,296 @@
+<?php
+
+namespace Sabre\CalDAV\Backend;
+
+use Sabre\CalDAV;
+use Sabre\DAV;
+
+/**
+ * Simple PDO CalDAV backend.
+ *
+ * This class is basically the most minmum example to get a caldav backend up
+ * and running. This class uses the following schema (MySQL example):
+ *
+ * CREATE TABLE simple_calendars (
+ * id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ * uri VARBINARY(200) NOT NULL,
+ * principaluri VARBINARY(200) NOT NULL
+ * );
+ *
+ * CREATE TABLE simple_calendarobjects (
+ * id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ * calendarid INT UNSIGNED NOT NULL,
+ * uri VARBINARY(200) NOT NULL,
+ * calendardata MEDIUMBLOB
+ * )
+ *
+ * To make this class work, you absolutely need to have the PropertyStorage
+ * plugin enabled.
+ *
+ * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class SimplePDO extends AbstractBackend {
+
+ /**
+ * pdo
+ *
+ * @var \PDO
+ */
+ protected $pdo;
+
+ /**
+ * Creates the backend
+ *
+ * @param \PDO $pdo
+ */
+ function __construct(\PDO $pdo) {
+
+ $this->pdo = $pdo;
+
+ }
+
+ /**
+ * Returns a list of calendars for a principal.
+ *
+ * Every project is an array with the following keys:
+ * * id, a unique id that will be used by other functions to modify the
+ * calendar. This can be the same as the uri or a database key.
+ * * uri. This is just the 'base uri' or 'filename' of the calendar.
+ * * principaluri. The owner of the calendar. Almost always the same as
+ * principalUri passed to this method.
+ *
+ * Furthermore it can contain webdav properties in clark notation. A very
+ * common one is '{DAV:}displayname'.
+ *
+ * Many clients also require:
+ * {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set
+ * For this property, you can just return an instance of
+ * Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet.
+ *
+ * If you return {http://sabredav.org/ns}read-only and set the value to 1,
+ * ACL will automatically be put in read-only mode.
+ *
+ * @param string $principalUri
+ * @return array
+ */
+ function getCalendarsForUser($principalUri) {
+
+ // Making fields a comma-delimited list
+ $stmt = $this->pdo->prepare("SELECT id, uri FROM simple_calendars WHERE principaluri = ? ORDER BY id ASC");
+ $stmt->execute([$principalUri]);
+
+ $calendars = [];
+ while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+
+ $calendars[] = [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'principaluri' => $principalUri,
+ ];
+
+ }
+
+ return $calendars;
+
+ }
+
+ /**
+ * Creates a new calendar for a principal.
+ *
+ * If the creation was a success, an id must be returned that can be used
+ * to reference this calendar in other methods, such as updateCalendar.
+ *
+ * @param string $principalUri
+ * @param string $calendarUri
+ * @param array $properties
+ * @return string
+ */
+ function createCalendar($principalUri, $calendarUri, array $properties) {
+
+ $stmt = $this->pdo->prepare("INSERT INTO simple_calendars (principaluri, uri) VALUES (?, ?)");
+ $stmt->execute([$principalUri, $calendarUri]);
+
+ return $this->pdo->lastInsertId();
+
+ }
+
+ /**
+ * Delete a calendar and all it's objects
+ *
+ * @param string $calendarId
+ * @return void
+ */
+ function deleteCalendar($calendarId) {
+
+ $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $stmt = $this->pdo->prepare('DELETE FROM simple_calendars WHERE id = ?');
+ $stmt->execute([$calendarId]);
+
+ }
+
+ /**
+ * Returns all calendar objects within a calendar.
+ *
+ * Every item contains an array with the following keys:
+ * * calendardata - The iCalendar-compatible calendar data
+ * * uri - a unique key which will be used to construct the uri. This can
+ * be any arbitrary string, but making sure it ends with '.ics' is a
+ * good idea. This is only the basename, or filename, not the full
+ * path.
+ * * lastmodified - a timestamp of the last modification time
+ * * etag - An arbitrary string, surrounded by double-quotes. (e.g.:
+ * ' "abcdef"')
+ * * size - The size of the calendar objects, in bytes.
+ * * component - optional, a string containing the type of object, such
+ * as 'vevent' or 'vtodo'. If specified, this will be used to populate
+ * the Content-Type header.
+ *
+ * Note that the etag is optional, but it's highly encouraged to return for
+ * speed reasons.
+ *
+ * The calendardata is also optional. If it's not returned
+ * 'getCalendarObject' will be called later, which *is* expected to return
+ * calendardata.
+ *
+ * If neither etag or size are specified, the calendardata will be
+ * used/fetched to determine these numbers. If both are specified the
+ * amount of times this is needed is reduced by a great degree.
+ *
+ * @param string $calendarId
+ * @return array
+ */
+ function getCalendarObjects($calendarId) {
+
+ $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ?');
+ $stmt->execute([$calendarId]);
+
+ $result = [];
+ foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
+ $result[] = [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'etag' => '"' . md5($row['calendardata']) . '"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($row['calendardata']),
+ 'calendardata' => $row['calendardata'],
+ ];
+ }
+
+ return $result;
+
+ }
+
+ /**
+ * Returns information from a single calendar object, based on it's object
+ * uri.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * The returned array must have the same keys as getCalendarObjects. The
+ * 'calendardata' object is required here though, while it's not required
+ * for getCalendarObjects.
+ *
+ * This method must return null if the object did not exist.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return array|null
+ */
+ function getCalendarObject($calendarId, $objectUri) {
+
+ $stmt = $this->pdo->prepare('SELECT id, uri, calendardata FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
+ $stmt->execute([$calendarId, $objectUri]);
+ $row = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+ if (!$row) return null;
+
+ return [
+ 'id' => $row['id'],
+ 'uri' => $row['uri'],
+ 'etag' => '"' . md5($row['calendardata']) . '"',
+ 'calendarid' => $calendarId,
+ 'size' => strlen($row['calendardata']),
+ 'calendardata' => $row['calendardata'],
+ ];
+
+ }
+
+ /**
+ * Creates a new calendar object.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * It is possible return an etag from this function, which will be used in
+ * the response to this PUT request. Note that the ETag must be surrounded
+ * by double-quotes.
+ *
+ * However, you should only really return this ETag if you don't mangle the
+ * calendar-data. If the result of a subsequent GET to this object is not
+ * the exact same as this request body, you should omit the ETag.
+ *
+ * @param mixed $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return string|null
+ */
+ function createCalendarObject($calendarId, $objectUri, $calendarData) {
+
+ $stmt = $this->pdo->prepare('INSERT INTO simple_calendarobjects (calendarid, uri, calendardata) VALUES (?,?,?)');
+ $stmt->execute([
+ $calendarId,
+ $objectUri,
+ $calendarData
+ ]);
+
+ return '"' . md5($calendarData) . '"';
+
+ }
+
+ /**
+ * Updates an existing calendarobject, based on it's uri.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * It is possible return an etag from this function, which will be used in
+ * the response to this PUT request. Note that the ETag must be surrounded
+ * by double-quotes.
+ *
+ * However, you should only really return this ETag if you don't mangle the
+ * calendar-data. If the result of a subsequent GET to this object is not
+ * the exact same as this request body, you should omit the ETag.
+ *
+ * @param mixed $calendarId
+ * @param string $objectUri
+ * @param string $calendarData
+ * @return string|null
+ */
+ function updateCalendarObject($calendarId, $objectUri, $calendarData) {
+
+ $stmt = $this->pdo->prepare('UPDATE simple_calendarobjects SET calendardata = ? WHERE calendarid = ? AND uri = ?');
+ $stmt->execute([$calendarData, $calendarId, $objectUri]);
+
+ return '"' . md5($calendarData) . '"';
+
+ }
+
+ /**
+ * Deletes an existing calendar object.
+ *
+ * The object uri is only the basename, or filename and not a full path.
+ *
+ * @param string $calendarId
+ * @param string $objectUri
+ * @return void
+ */
+ function deleteCalendarObject($calendarId, $objectUri) {
+
+ $stmt = $this->pdo->prepare('DELETE FROM simple_calendarobjects WHERE calendarid = ? AND uri = ?');
+ $stmt->execute([$calendarId, $objectUri]);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/CalDAV/Calendar.php b/vendor/sabre/dav/lib/CalDAV/Calendar.php
index ff8e19b15..90ace0d21 100644
--- a/vendor/sabre/dav/lib/CalDAV/Calendar.php
+++ b/vendor/sabre/dav/lib/CalDAV/Calendar.php
@@ -18,6 +18,8 @@ use Sabre\DAV\PropPatch;
*/
class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection, DAV\IMultiGet {
+ use DAVACL\ACLTrait;
+
/**
* This is an array with calendar information
*
@@ -86,7 +88,7 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
foreach ($this->calendarInfo as $propName => $propValue) {
- if ($propName[0] === '{')
+ if (!is_null($propValue) && $propName[0] === '{')
$response[$propName] = $this->calendarInfo[$propName];
}
@@ -227,7 +229,7 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
/**
* Returns the last modification date as a unix timestamp.
*
- * @return void
+ * @return null
*/
function getLastModified() {
@@ -249,19 +251,6 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -360,50 +349,6 @@ class Calendar implements ICalendar, DAV\IProperties, DAV\Sync\ISyncCollection,
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See \Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet();
-
- // We need to inject 'read-free-busy' in the tree, aggregated under
- // {DAV:}read.
- foreach ($default['aggregates'] as &$agg) {
-
- if ($agg['privilege'] !== '{DAV:}read') continue;
-
- $agg['aggregates'][] = [
- 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
- ];
-
- }
- return $default;
-
- }
/**
* Performs a calendar-query on the contents of this calendar.
diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarHome.php b/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
index a53f829e2..0a4bfb68f 100644
--- a/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
+++ b/vendor/sabre/dav/lib/CalDAV/CalendarHome.php
@@ -22,6 +22,8 @@ use Sabre\HTTP\URLUtil;
*/
class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
+ use DAVACL\ACLTrait;
+
/**
* CalDAV backend
*
@@ -147,11 +149,7 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) {
if ($calendar['uri'] === $name) {
if ($this->caldavBackend instanceof Backend\SharingSupport) {
- if (isset($calendar['{http://calendarserver.org/ns/}shared-url'])) {
- return new SharedCalendar($this->caldavBackend, $calendar);
- } else {
- return new ShareableCalendar($this->caldavBackend, $calendar);
- }
+ return new SharedCalendar($this->caldavBackend, $calendar);
} else {
return new Calendar($this->caldavBackend, $calendar);
}
@@ -198,11 +196,7 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
$objs = [];
foreach ($calendars as $calendar) {
if ($this->caldavBackend instanceof Backend\SharingSupport) {
- if (isset($calendar['{http://calendarserver.org/ns/}shared-url'])) {
- $objs[] = new SharedCalendar($this->caldavBackend, $calendar);
- } else {
- $objs[] = new ShareableCalendar($this->caldavBackend, $calendar);
- }
+ $objs[] = new SharedCalendar($this->caldavBackend, $calendar);
} else {
$objs[] = new Calendar($this->caldavBackend, $calendar);
}
@@ -278,11 +272,9 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
}
/**
- * Returns the owner principal
+ * Returns the owner of the calendar home.
*
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
+ * @return string
*/
function getOwner() {
@@ -291,19 +283,6 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -348,37 +327,6 @@ class CalendarHome implements DAV\IExtendedCollection, DAVACL\IACL {
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
/**
* This method is called when a user replied to a request to share.
diff --git a/vendor/sabre/dav/lib/CalDAV/CalendarObject.php b/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
index 393ca4cbd..001b35112 100644
--- a/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
+++ b/vendor/sabre/dav/lib/CalDAV/CalendarObject.php
@@ -11,6 +11,8 @@ namespace Sabre\CalDAV;
*/
class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL {
+ use \Sabre\DAVACL\ACLTrait;
+
/**
* Sabre\CalDAV\Backend\BackendInterface
*
@@ -192,19 +194,6 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -226,22 +215,12 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
// The default ACL
return [
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->calendarInfo['principaluri'],
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->calendarInfo['principaluri'],
'protected' => true,
],
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
'protected' => true,
],
@@ -255,36 +234,4 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new \Sabre\DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See \Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php b/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
index 8c296d50f..a3a824c71 100644
--- a/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/ICSExportPlugin.php
@@ -170,13 +170,13 @@ class ICSExportPlugin extends DAV\ServerPlugin {
protected function generateResponse($path, $start, $end, $expand, $componentType, $format, $properties, ResponseInterface $response) {
$calDataProp = '{' . Plugin::NS_CALDAV . '}calendar-data';
+ $calendarNode = $this->server->tree->getNodeForPath($path);
$blobs = [];
if ($start || $end || $componentType) {
// If there was a start or end filter, we need to enlist
// calendarQuery for speed.
- $calendarNode = $this->server->tree->getNodeForPath($path);
$queryResult = $calendarNode->calendarQuery([
'name' => 'VCALENDAR',
'comp-filters' => [
@@ -246,17 +246,29 @@ class ICSExportPlugin extends DAV\ServerPlugin {
$mergedCalendar = $mergedCalendar->expand($start, $end, $calendarTimeZone);
}
- $response->setHeader('Content-Type', $format);
+ $filenameExtension = '.ics';
switch ($format) {
case 'text/calendar' :
$mergedCalendar = $mergedCalendar->serialize();
+ $filenameExtension = '.ics';
break;
case 'application/calendar+json' :
$mergedCalendar = json_encode($mergedCalendar->jsonSerialize());
+ $filenameExtension = '.json';
break;
}
+ $filename = preg_replace(
+ '/[^a-zA-Z0-9-_ ]/um',
+ '',
+ $calendarNode->getName()
+ );
+ $filename .= '-' . date('Y-m-d') . $filenameExtension;
+
+ $response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
+ $response->setHeader('Content-Type', $format);
+
$response->setStatus(200);
$response->setBody($mergedCalendar);
@@ -272,11 +284,11 @@ class ICSExportPlugin extends DAV\ServerPlugin {
function mergeObjects(array $properties, array $inputObjects) {
$calendar = new VObject\Component\VCalendar();
- $calendar->version = '2.0';
+ $calendar->VERSION = '2.0';
if (DAV\Server::$exposeVersion) {
- $calendar->prodid = '-//SabreDAV//SabreDAV ' . DAV\Version::VERSION . '//EN';
+ $calendar->PRODID = '-//SabreDAV//SabreDAV ' . DAV\Version::VERSION . '//EN';
} else {
- $calendar->prodid = '-//SabreDAV//SabreDAV//EN';
+ $calendar->PRODID = '-//SabreDAV//SabreDAV//EN';
}
if (isset($properties['{DAV:}displayname'])) {
$calendar->{'X-WR-CALNAME'} = $properties['{DAV:}displayname'];
diff --git a/vendor/sabre/dav/lib/CalDAV/IShareableCalendar.php b/vendor/sabre/dav/lib/CalDAV/IShareableCalendar.php
deleted file mode 100644
index cfda91a55..000000000
--- a/vendor/sabre/dav/lib/CalDAV/IShareableCalendar.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-namespace Sabre\CalDAV;
-
-/**
- * This interface represents a Calendar that can be shared with other users.
- *
- * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-interface IShareableCalendar extends ICalendar {
-
- /**
- * Updates the list of shares.
- *
- * The first array is a list of people that are to be added to the
- * calendar.
- *
- * Every element in the add array has the following properties:
- * * href - A url. Usually a mailto: address
- * * commonName - Usually a first and last name, or false
- * * summary - A description of the share, can also be false
- * * readOnly - A boolean value
- *
- * Every element in the remove array is just the address string.
- *
- * @param array $add
- * @param array $remove
- * @return void
- */
- function updateShares(array $add, array $remove);
-
- /**
- * Returns the list of people whom this calendar is shared with.
- *
- * Every element in this array should have the following properties:
- * * href - Often a mailto: address
- * * commonName - Optional, for example a first + last name
- * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
- * * readOnly - boolean
- * * summary - Optional, a description for the share
- *
- * @return array
- */
- function getShares();
-
-}
diff --git a/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php b/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php
index 84442ac21..15f3b5335 100644
--- a/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php
+++ b/vendor/sabre/dav/lib/CalDAV/ISharedCalendar.php
@@ -2,6 +2,8 @@
namespace Sabre\CalDAV;
+use Sabre\DAV\Sharing\ISharedNode;
+
/**
* This interface represents a Calendar that is shared by a different user.
*
@@ -9,28 +11,16 @@ namespace Sabre\CalDAV;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-interface ISharedCalendar extends ICalendar {
-
- /**
- * This method should return the url of the owners' copy of the shared
- * calendar.
- *
- * @return string
- */
- function getSharedUrl();
+interface ISharedCalendar extends ISharedNode {
/**
- * Returns the list of people whom this calendar is shared with.
+ * Marks this calendar as published.
*
- * Every element in this array should have the following properties:
- * * href - Often a mailto: address
- * * commonName - Optional, for example a first + last name
- * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
- * * readOnly - boolean
- * * summary - Optional, a description for the share
+ * Publishing a calendar should automatically create a read-only, public,
+ * subscribable calendar.
*
- * @return array
+ * @param bool $value
+ * @return void
*/
- function getShares();
-
+ function setPublishStatus($value);
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php b/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
index 1fcc1171c..5fda61dfa 100644
--- a/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
+++ b/vendor/sabre/dav/lib/CalDAV/Notifications/Collection.php
@@ -22,6 +22,8 @@ use Sabre\DAVACL;
*/
class Collection extends DAV\Collection implements ICollection, DAVACL\IACL {
+ use DAVACL\ACLTrait;
+
/**
* The notification backend
*
@@ -96,78 +98,4 @@ class Collection extends DAV\Collection implements ICollection, DAVACL\IACL {
}
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
- * Returns a list of ACE's for this node.
- *
- * Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
- * currently the only supported privileges
- * * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
- */
- function getACL() {
-
- return [
- [
- 'principal' => $this->getOwner(),
- 'privilege' => '{DAV:}read',
- 'protected' => true,
- ],
- [
- 'principal' => $this->getOwner(),
- 'privilege' => '{DAV:}write',
- 'protected' => true,
- ]
- ];
-
- }
-
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's as an array argument.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\NotImplemented('Updating ACLs is not implemented here');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php b/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
index 47e78d5de..11df0c94b 100644
--- a/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
+++ b/vendor/sabre/dav/lib/CalDAV/Notifications/Node.php
@@ -20,6 +20,8 @@ use Sabre\DAVACL;
*/
class Node extends DAV\File implements INode, DAVACL\IACL {
+ use DAVACL\ACLTrait;
+
/**
* The notification backend
*
@@ -116,78 +118,4 @@ class Node extends DAV\File implements INode, DAVACL\IACL {
}
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
- * Returns a list of ACE's for this node.
- *
- * Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
- * currently the only supported privileges
- * * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
- */
- function getACL() {
-
- return [
- [
- 'principal' => $this->getOwner(),
- 'privilege' => '{DAV:}read',
- 'protected' => true,
- ],
- [
- 'principal' => $this->getOwner(),
- 'privilege' => '{DAV:}write',
- 'protected' => true,
- ]
- ];
-
- }
-
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's as an array argument.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\NotImplemented('Updating ACLs is not implemented here');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Plugin.php
index 663490023..71ba75206 100644
--- a/vendor/sabre/dav/lib/CalDAV/Plugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Plugin.php
@@ -5,8 +5,9 @@ namespace Sabre\CalDAV;
use DateTimeZone;
use Sabre\DAV;
use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\INode;
use Sabre\DAV\MkCol;
-use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\DAVACL;
use Sabre\VObject;
use Sabre\HTTP;
@@ -186,6 +187,7 @@ class Plugin extends DAV\ServerPlugin {
$server->on('beforeCreateFile', [$this, 'beforeCreateFile']);
$server->on('beforeWriteContent', [$this, 'beforeWriteContent']);
$server->on('afterMethod:GET', [$this, 'httpAfterGET']);
+ $server->on('getSupportedPrivilegeSet', [$this, 'getSupportedPrivilegeSet']);
$server->xml->namespaceMap[self::NS_CALDAV] = 'cal';
$server->xml->namespaceMap[self::NS_CALENDARSERVER] = 'cs';
@@ -233,9 +235,10 @@ class Plugin extends DAV\ServerPlugin {
*
* @param string $reportName
* @param mixed $report
+ * @param mixed $path
* @return bool
*/
- function report($reportName, $report) {
+ function report($reportName, $report, $path) {
switch ($reportName) {
case '{' . self::NS_CALDAV . '}calendar-multiget' :
@@ -341,7 +344,7 @@ class Plugin extends DAV\ServerPlugin {
$calendarHomePath = $this->getCalendarHomeForPrincipal($principalUrl);
if (is_null($calendarHomePath)) return null;
- return new Href($calendarHomePath . '/');
+ return new LocalHref($calendarHomePath . '/');
});
// The calendar-user-address-set property is basically mapped to
@@ -349,7 +352,7 @@ class Plugin extends DAV\ServerPlugin {
$propFind->handle('{' . self::NS_CALDAV . '}calendar-user-address-set', function() use ($node) {
$addresses = $node->getAlternateUriSet();
$addresses[] = $this->server->getBaseUri() . $node->getPrincipalUrl() . '/';
- return new Href($addresses, false);
+ return new LocalHref($addresses);
});
// For some reason somebody thought it was a good idea to add
// another one of these properties. We're supporting it too.
@@ -394,8 +397,8 @@ class Plugin extends DAV\ServerPlugin {
}
- $propFind->set($propRead, new Href($readList));
- $propFind->set($propWrite, new Href($writeList));
+ $propFind->set($propRead, new LocalHref($readList));
+ $propFind->set($propWrite, new LocalHref($writeList));
}
@@ -821,11 +824,7 @@ class Plugin extends DAV\ServerPlugin {
$data = stream_get_contents($data);
}
- $before = md5($data);
- // Converting the data to unicode, if needed.
- $data = DAV\StringUtil::ensureUTF8($data);
-
- if ($before !== md5($data)) $modified = true;
+ $before = $data;
try {
@@ -865,7 +864,7 @@ class Plugin extends DAV\ServerPlugin {
}
$foundType = null;
- $foundUID = null;
+
foreach ($vobj->getComponents() as $component) {
switch ($component->name) {
case 'VTIMEZONE' :
@@ -873,31 +872,59 @@ class Plugin extends DAV\ServerPlugin {
case 'VEVENT' :
case 'VTODO' :
case 'VJOURNAL' :
- if (is_null($foundType)) {
- $foundType = $component->name;
- if (!in_array($foundType, $supportedComponents)) {
- throw new Exception\InvalidComponentType('This calendar only supports ' . implode(', ', $supportedComponents) . '. We found a ' . $foundType);
- }
- if (!isset($component->UID)) {
- throw new DAV\Exception\BadRequest('Every ' . $component->name . ' component must have an UID');
- }
- $foundUID = (string)$component->UID;
- } else {
- if ($foundType !== $component->name) {
- throw new DAV\Exception\BadRequest('A calendar object must only contain 1 component. We found a ' . $component->name . ' as well as a ' . $foundType);
- }
- if ($foundUID !== (string)$component->UID) {
- throw new DAV\Exception\BadRequest('Every ' . $component->name . ' in this object must have identical UIDs');
- }
- }
+ $foundType = $component->name;
break;
- default :
- throw new DAV\Exception\BadRequest('You are not allowed to create components of type: ' . $component->name . ' here');
+ }
+
+ }
+
+ if (!$foundType || !in_array($foundType, $supportedComponents)) {
+ throw new Exception\InvalidComponentType('iCalendar objects must at least have a component of type ' . implode(', ', $supportedComponents));
+ }
+
+ $options = VObject\Node::PROFILE_CALDAV;
+ $prefer = $this->server->getHTTPPrefer();
+
+ if ($prefer['handling'] !== 'strict') {
+ $options |= VObject\Node::REPAIR;
+ }
+
+ $messages = $vobj->validate($options);
+ $highestLevel = 0;
+ $warningMessage = null;
+
+ // $messages contains a list of problems with the vcard, along with
+ // their severity.
+ foreach ($messages as $message) {
+
+ if ($message['level'] > $highestLevel) {
+ // Recording the highest reported error level.
+ $highestLevel = $message['level'];
+ $warningMessage = $message['message'];
}
+ switch ($message['level']) {
+
+ case 1 :
+ // Level 1 means that there was a problem, but it was repaired.
+ $modified = true;
+ break;
+ case 2 :
+ // Level 2 means a warning, but not critical
+ break;
+ case 3 :
+ // Level 3 means a critical error
+ throw new DAV\Exception\UnsupportedMediaType('Validation error in iCalendar: ' . $message['message']);
+
+ }
+
+ }
+ if ($warningMessage) {
+ $response->setHeader(
+ 'X-Sabre-Ew-Gross',
+ 'iCalendar validation warning: ' . $warningMessage
+ );
}
- if (!$foundType)
- throw new DAV\Exception\BadRequest('iCalendar object must contain at least 1 of VEVENT, VTODO or VJOURNAL');
// We use an extra variable to allow event handles to tell us wether
// the object was modified or not.
@@ -917,12 +944,12 @@ class Plugin extends DAV\ServerPlugin {
]
);
- if ($subModified) {
+ if ($modified || $subModified) {
// An event handler told us that it modified the object.
$data = $vobj->serialize();
// Using md5 to figure out if there was an *actual* change.
- if (!$modified && $before !== md5($data)) {
+ if (!$modified && strcmp($data, $before) !== 0) {
$modified = true;
}
@@ -933,6 +960,22 @@ class Plugin extends DAV\ServerPlugin {
}
+ /**
+ * This method is triggered whenever a subsystem reqeuests the privileges
+ * that are supported on a particular node.
+ *
+ * @param INode $node
+ * @param array $supportedPrivilegeSet
+ */
+ function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilegeSet) {
+
+ if ($node instanceof ICalendar) {
+ $supportedPrivilegeSet['{DAV:}read']['aggregates']['{' . self::NS_CALDAV . '}read-free-busy'] = [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ];
+ }
+ }
/**
* This method is used to generate HTML output for the
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php
index 13212565e..6b374ea3f 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Inbox.php
@@ -17,6 +17,8 @@ use Sabre\VObject;
*/
class Inbox extends DAV\Collection implements IInbox {
+ use DAVACL\ACLTrait;
+
/**
* CalDAV backend
*
@@ -119,19 +121,6 @@ class Inbox extends DAV\Collection implements IInbox {
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -167,58 +156,11 @@ class Inbox extends DAV\Collection implements IInbox {
'protected' => true,
],
[
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-deliver-invite',
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-deliver',
'principal' => '{DAV:}authenticated',
'protected' => true,
],
- [
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-deliver-reply',
- 'principal' => '{DAV:}authenticated',
- 'protected' => true,
- ],
- ];
-
- }
-
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('You\'re not allowed to update the ACL');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- $ns = '{' . CalDAV\Plugin::NS_CALDAV . '}';
-
- $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet();
- $default['aggregates'][] = [
- 'privilege' => $ns . 'schedule-deliver',
- 'aggregates' => [
- ['privilege' => $ns . 'schedule-deliver-invite'],
- ['privilege' => $ns . 'schedule-deliver-reply'],
- ],
];
- return $default;
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php
index dabaee2ca..29eefa744 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Outbox.php
@@ -19,6 +19,8 @@ use Sabre\DAVACL;
*/
class Outbox extends DAV\Collection implements IOutbox {
+ use DAVACL\ACLTrait;
+
/**
* The principal Uri
*
@@ -75,19 +77,6 @@ class Outbox extends DAV\Collection implements IOutbox {
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -103,12 +92,7 @@ class Outbox extends DAV\Collection implements IOutbox {
return [
[
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
- 'principal' => $this->getOwner(),
- 'protected' => true,
- ],
- [
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
'principal' => $this->getOwner(),
'protected' => true,
],
@@ -118,12 +102,7 @@ class Outbox extends DAV\Collection implements IOutbox {
'protected' => true,
],
[
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
- 'principal' => $this->getOwner() . '/calendar-proxy-write',
- 'protected' => true,
- ],
- [
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
'principal' => $this->getOwner() . '/calendar-proxy-write',
'protected' => true,
],
@@ -141,44 +120,4 @@ class Outbox extends DAV\Collection implements IOutbox {
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('You\'re not allowed to update the ACL');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet();
- $default['aggregates'][] = [
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
- ];
- $default['aggregates'][] = [
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
- ];
-
- return $default;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php b/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php
index 827d6209b..47511140f 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/Plugin.php
@@ -5,10 +5,12 @@ namespace Sabre\CalDAV\Schedule;
use DateTimeZone;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
+use Sabre\DAV\Sharing;
use Sabre\DAV\PropFind;
use Sabre\DAV\PropPatch;
use Sabre\DAV\INode;
use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Sabre\VObject;
@@ -100,12 +102,13 @@ class Plugin extends ServerPlugin {
function initialize(Server $server) {
$this->server = $server;
- $server->on('method:POST', [$this, 'httpPost']);
- $server->on('propFind', [$this, 'propFind']);
- $server->on('propPatch', [$this, 'propPatch']);
- $server->on('calendarObjectChange', [$this, 'calendarObjectChange']);
- $server->on('beforeUnbind', [$this, 'beforeUnbind']);
- $server->on('schedule', [$this, 'scheduleLocalDelivery']);
+ $server->on('method:POST', [$this, 'httpPost']);
+ $server->on('propFind', [$this, 'propFind']);
+ $server->on('propPatch', [$this, 'propPatch']);
+ $server->on('calendarObjectChange', [$this, 'calendarObjectChange']);
+ $server->on('beforeUnbind', [$this, 'beforeUnbind']);
+ $server->on('schedule', [$this, 'scheduleLocalDelivery']);
+ $server->on('getSupportedPrivilegeSet', [$this, 'getSupportedPrivilegeSet']);
$ns = '{' . self::NS_CALDAV . '}';
@@ -215,7 +218,7 @@ class Plugin extends ServerPlugin {
}
$outboxPath = $calendarHomePath . '/outbox/';
- return new Href($outboxPath);
+ return new LocalHref($outboxPath);
});
// schedule-inbox-URL property
@@ -227,7 +230,7 @@ class Plugin extends ServerPlugin {
}
$inboxPath = $calendarHomePath . '/inbox/';
- return new Href($inboxPath);
+ return new LocalHref($inboxPath);
});
@@ -245,18 +248,28 @@ class Plugin extends ServerPlugin {
$result = $this->server->getPropertiesForPath($calendarHomePath, [
'{DAV:}resourcetype',
+ '{DAV:}share-access',
$sccs,
], 1);
foreach ($result as $child) {
- if (!isset($child[200]['{DAV:}resourcetype']) || !$child[200]['{DAV:}resourcetype']->is('{' . self::NS_CALDAV . '}calendar') || $child[200]['{DAV:}resourcetype']->is('{http://calendarserver.org/ns/}shared')) {
- // Node is either not a calendar or a shared instance.
+ if (!isset($child[200]['{DAV:}resourcetype']) || !$child[200]['{DAV:}resourcetype']->is('{' . self::NS_CALDAV . '}calendar')) {
+ // Node is either not a calendar
continue;
}
+ if (isset($child[200]['{DAV:}share-access'])) {
+ $shareAccess = $child[200]['{DAV:}share-access']->getValue();
+ if ($shareAccess !== Sharing\Plugin::ACCESS_NOTSHARED && $shareAccess !== Sharing\Plugin::ACCESS_SHAREDOWNER) {
+ // Node is a shared node, not owned by the relevant
+ // user.
+ continue;
+ }
+
+ }
if (!isset($child[200][$sccs]) || in_array('VEVENT', $child[200][$sccs]->getValue())) {
// Either there is no supported-calendar-component-set
// (which is fine) or we found one that supports VEVENT.
- return new Href($child['href']);
+ return new LocalHref($child['href']);
}
}
@@ -492,7 +505,7 @@ class Plugin extends ServerPlugin {
}
if (!$aclPlugin->checkPrivileges($inboxPath, $caldavNS . $privilege, DAVACL\Plugin::R_PARENT, false)) {
- $iTipMessage->scheduleStatus = '3.8;organizer did not have the ' . $privilege . ' privilege on the attendees inbox';
+ $iTipMessage->scheduleStatus = '3.8;insufficient privileges: ' . $privilege . ' is required on the recipient schedule inbox.';
return;
}
@@ -561,6 +574,65 @@ class Plugin extends ServerPlugin {
}
/**
+ * This method is triggered whenever a subsystem requests the privileges
+ * that are supported on a particular node.
+ *
+ * We need to add a number of privileges for scheduling purposes.
+ *
+ * @param INode $node
+ * @param array $supportedPrivilegeSet
+ */
+ function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilegeSet) {
+
+ $ns = '{' . self::NS_CALDAV . '}';
+ if ($node instanceof IOutbox) {
+ $supportedPrivilegeSet[$ns . 'schedule-send'] = [
+ 'abstract' => false,
+ 'aggregates' => [
+ $ns . 'schedule-send-invite' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ $ns . 'schedule-send-reply' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ $ns . 'schedule-send-freebusy' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ // Privilege from an earlier scheduling draft, but still
+ // used by some clients.
+ $ns . 'schedule-post-vevent' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ ]
+ ];
+ }
+ if ($node instanceof IInbox) {
+ $supportedPrivilegeSet[$ns . 'schedule-deliver'] = [
+ 'abstract' => false,
+ 'aggregates' => [
+ $ns . 'schedule-deliver-invite' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ $ns . 'schedule-deliver-reply' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ $ns . 'schedule-query-freebusy' => [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ],
+ ]
+ ];
+ }
+
+ }
+
+ /**
* This method looks at an old iCalendar object, a new iCalendar object and
* starts sending scheduling messages based on the changes.
*
@@ -647,7 +719,7 @@ class Plugin extends ServerPlugin {
/**
* This method handles POST requests to the schedule-outbox.
*
- * Currently, two types of requests are support:
+ * Currently, two types of requests are supported:
* * FREEBUSY requests from RFC 6638
* * Simple iTIP messages from draft-desruisseaux-caldav-sched-04
*
@@ -699,7 +771,7 @@ class Plugin extends ServerPlugin {
if ($componentType === 'VFREEBUSY' && $method === 'REQUEST') {
- $acl && $acl->checkPrivileges($outboxPath, '{' . self::NS_CALDAV . '}schedule-query-freebusy');
+ $acl && $acl->checkPrivileges($outboxPath, '{' . self::NS_CALDAV . '}schedule-send-freebusy');
$this->handleFreeBusyRequest($outboxNode, $vObject, $request, $response);
// Destroy circular references so PHP can GC the object.
@@ -727,7 +799,7 @@ class Plugin extends ServerPlugin {
protected function handleFreeBusyRequest(IOutbox $outbox, VObject\Component $vObject, RequestInterface $request, ResponseInterface $response) {
$vFreeBusy = $vObject->VFREEBUSY;
- $organizer = $vFreeBusy->organizer;
+ $organizer = $vFreeBusy->ORGANIZER;
$organizer = (string)$organizer;
@@ -863,6 +935,9 @@ class Plugin extends ServerPlugin {
$homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref();
$inboxUrl = $result[0][200][$caldavNS . 'schedule-inbox-URL']->getHref();
+ // Do we have permission?
+ $aclPlugin->checkPrivileges($inboxUrl, $caldavNS . 'schedule-query-freebusy');
+
// Grabbing the calendar list
$objects = [];
$calendarTimeZone = new DateTimeZone('UTC');
@@ -882,8 +957,6 @@ class Plugin extends ServerPlugin {
continue;
}
- $aclPlugin->checkPrivileges($homeSet . $node->getName(), $caldavNS . 'read-free-busy');
-
if (isset($props[$ctz])) {
$vtimezoneObj = VObject\Reader::read($props[$ctz]);
$calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone();
diff --git a/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php b/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php
index a36646e6c..6d9d3d5ec 100644
--- a/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php
+++ b/vendor/sabre/dav/lib/CalDAV/Schedule/SchedulingObject.php
@@ -134,22 +134,12 @@ class SchedulingObject extends \Sabre\CalDAV\CalendarObject implements IScheduli
// The default ACL
return [
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->objectData['principaluri'],
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
- 'principal' => $this->objectData['principaluri'],
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}read',
- 'principal' => $this->objectData['principaluri'] . '/calendar-proxy-write',
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
],
[
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->objectData['principaluri'] . '/calendar-proxy-write',
'protected' => true,
],
diff --git a/vendor/sabre/dav/lib/CalDAV/ShareableCalendar.php b/vendor/sabre/dav/lib/CalDAV/ShareableCalendar.php
deleted file mode 100644
index c11695d5f..000000000
--- a/vendor/sabre/dav/lib/CalDAV/ShareableCalendar.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-namespace Sabre\CalDAV;
-
-/**
- * This object represents a CalDAV calendar that can be shared with other
- * users.
- *
- * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
- * @author Evert Pot (http://evertpot.com/)
- * @license http://sabre.io/license/ Modified BSD License
- */
-class ShareableCalendar extends Calendar implements IShareableCalendar {
-
- /**
- * Updates the list of shares.
- *
- * The first array is a list of people that are to be added to the
- * calendar.
- *
- * Every element in the add array has the following properties:
- * * href - A url. Usually a mailto: address
- * * commonName - Usually a first and last name, or false
- * * summary - A description of the share, can also be false
- * * readOnly - A boolean value
- *
- * Every element in the remove array is just the address string.
- *
- * @param array $add
- * @param array $remove
- * @return void
- */
- function updateShares(array $add, array $remove) {
-
- $this->caldavBackend->updateShares($this->calendarInfo['id'], $add, $remove);
-
- }
-
- /**
- * Returns the list of people whom this calendar is shared with.
- *
- * Every element in this array should have the following properties:
- * * href - Often a mailto: address
- * * commonName - Optional, for example a first + last name
- * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
- * * readOnly - boolean
- * * summary - Optional, a description for the share
- *
- * @return array
- */
- function getShares() {
-
- return $this->caldavBackend->getShares($this->calendarInfo['id']);
-
- }
-
- /**
- * Marks this calendar as published.
- *
- * Publishing a calendar should automatically create a read-only, public,
- * subscribable calendar.
- *
- * @param bool $value
- * @return void
- */
- function setPublishStatus($value) {
-
- $this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value);
-
- }
-
-}
diff --git a/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php b/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php
index 7973eff9c..7a77616e3 100644
--- a/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php
+++ b/vendor/sabre/dav/lib/CalDAV/SharedCalendar.php
@@ -2,6 +2,8 @@
namespace Sabre\CalDAV;
+use Sabre\DAV\Sharing\Plugin as SPlugin;
+
/**
* This object represents a CalDAV calendar that is shared by a different user.
*
@@ -12,50 +14,84 @@ namespace Sabre\CalDAV;
class SharedCalendar extends Calendar implements ISharedCalendar {
/**
- * Constructor
+ * Returns the 'access level' for the instance of this shared resource.
+ *
+ * The value should be one of the Sabre\DAV\Sharing\Plugin::ACCESS_
+ * constants.
*
- * @param Backend\BackendInterface $caldavBackend
- * @param array $calendarInfo
+ * @return int
*/
- function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo) {
-
- $required = [
- '{http://calendarserver.org/ns/}shared-url',
- '{http://sabredav.org/ns}owner-principal',
- '{http://sabredav.org/ns}read-only',
- ];
- foreach ($required as $r) {
- if (!isset($calendarInfo[$r])) {
- throw new \InvalidArgumentException('The ' . $r . ' property must be specified for SharedCalendar(s)');
- }
- }
+ function getShareAccess() {
- parent::__construct($caldavBackend, $calendarInfo);
+ return isset($this->calendarInfo['share-access']) ? $this->calendarInfo['share-access'] : SPlugin::ACCESS_NOTSHARED;
}
/**
- * This method should return the url of the owners' copy of the shared
- * calendar.
+ * This function must return a URI that uniquely identifies the shared
+ * resource. This URI should be identical across instances, and is
+ * also used in several other XML bodies to connect invites to
+ * resources.
+ *
+ * This may simply be a relative reference to the original shared instance,
+ * but it could also be a urn. As long as it's a valid URI and unique.
*
* @return string
*/
- function getSharedUrl() {
+ function getShareResourceUri() {
+
+ return $this->calendarInfo['share-resource-uri'];
+
+ }
+
+ /**
+ * Updates the list of sharees.
+ *
+ * Every item must be a Sharee object.
+ *
+ * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
+ * @return void
+ */
+ function updateInvites(array $sharees) {
- return $this->calendarInfo['{http://calendarserver.org/ns/}shared-url'];
+ $this->caldavBackend->updateInvites($this->calendarInfo['id'], $sharees);
}
/**
- * Returns the owner principal
+ * Returns the list of people whom this resource is shared with.
+ *
+ * Every item in the returned array must be a Sharee object with
+ * at least the following properties set:
+ *
+ * * $href
+ * * $shareAccess
+ * * $inviteStatus
*
- * This must be a url to a principal, or null if there's no owner
+ * and optionally:
*
- * @return string|null
+ * * $properties
+ *
+ * @return \Sabre\DAV\Xml\Element\Sharee[]
*/
- function getOwner() {
+ function getInvites() {
- return $this->calendarInfo['{http://sabredav.org/ns}owner-principal'];
+ return $this->caldavBackend->getInvites($this->calendarInfo['id']);
+
+ }
+
+ /**
+ * Marks this calendar as published.
+ *
+ * Publishing a calendar should automatically create a read-only, public,
+ * subscribable calendar.
+ *
+ * @param bool $value
+ * @return void
+ */
+ function setPublishStatus($value) {
+
+ $this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value);
}
@@ -73,32 +109,72 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
*/
function getACL() {
- // The top-level ACL only contains access information for the true
- // owner of the calendar, so we need to add the information for the
- // sharee.
- $acl = parent::getACL();
- $acl[] = [
- 'privilege' => '{DAV:}read',
- 'principal' => $this->calendarInfo['principaluri'],
- 'protected' => true,
- ];
- if ($this->calendarInfo['{http://sabredav.org/ns}read-only']) {
- $acl[] = [
- 'privilege' => '{DAV:}write-properties',
- 'principal' => $this->calendarInfo['principaluri'],
- 'protected' => true,
- ];
- } else {
- $acl[] = [
- 'privilege' => '{DAV:}write',
- 'principal' => $this->calendarInfo['principaluri'],
- 'protected' => true,
- ];
+ $acl = [];
+
+ switch ($this->getShareAccess()) {
+ case SPlugin::ACCESS_NOTSHARED :
+ case SPlugin::ACCESS_SHAREDOWNER :
+ $acl[] = [
+ 'privilege' => '{DAV:}share',
+ 'principal' => $this->calendarInfo['principaluri'],
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}share',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
+ // No break intentional!
+ case SPlugin::ACCESS_READWRITE :
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->calendarInfo['principaluri'],
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
+ // No break intentional!
+ case SPlugin::ACCESS_READ :
+ $acl[] = [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => $this->calendarInfo['principaluri'],
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->calendarInfo['principaluri'],
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ ];
+ break;
}
return $acl;
}
+
/**
* This method returns the ACL's for calendar objects in this calendar.
* The result of this method automatically gets passed to the
@@ -108,40 +184,45 @@ class SharedCalendar extends Calendar implements ISharedCalendar {
*/
function getChildACL() {
- $acl = parent::getChildACL();
- $acl[] = [
- 'privilege' => '{DAV:}read',
- 'principal' => $this->calendarInfo['principaluri'],
- 'protected' => true,
- ];
-
- if (!$this->calendarInfo['{http://sabredav.org/ns}read-only']) {
- $acl[] = [
- 'privilege' => '{DAV:}write',
- 'principal' => $this->calendarInfo['principaluri'],
- 'protected' => true,
- ];
+ $acl = [];
+
+ switch ($this->getShareAccess()) {
+ case SPlugin::ACCESS_NOTSHARED :
+ // No break intentional
+ case SPlugin::ACCESS_SHAREDOWNER :
+ // No break intentional
+ case SPlugin::ACCESS_READWRITE:
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->calendarInfo['principaluri'],
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}write',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
+ // No break intentional
+ case SPlugin::ACCESS_READ:
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->calendarInfo['principaluri'],
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write',
+ 'protected' => true,
+ ];
+ $acl[] = [
+ 'privilege' => '{DAV:}read',
+ 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read',
+ 'protected' => true,
+ ];
+ break;
}
- return $acl;
-
- }
-
- /**
- * Returns the list of people whom this calendar is shared with.
- *
- * Every element in this array should have the following properties:
- * * href - Often a mailto: address
- * * commonName - Optional, for example a first + last name
- * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
- * * readOnly - boolean
- * * summary - Optional, a description for the share
- *
- * @return array
- */
- function getShares() {
-
- return $this->caldavBackend->getShares($this->calendarInfo['id']);
+ return $acl;
}
diff --git a/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php b/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php
index 5154fb1de..6f7df02bc 100644
--- a/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php
+++ b/vendor/sabre/dav/lib/CalDAV/SharingPlugin.php
@@ -4,6 +4,7 @@ namespace Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -26,15 +27,6 @@ use Sabre\HTTP\ResponseInterface;
class SharingPlugin extends DAV\ServerPlugin {
/**
- * These are the various status constants used by sharing-messages.
- */
- const STATUS_ACCEPTED = 1;
- const STATUS_DECLINED = 2;
- const STATUS_DELETED = 3;
- const STATUS_NORESPONSE = 4;
- const STATUS_INVALID = 5;
-
- /**
* Reference to SabreDAV server object.
*
* @var Sabre\DAV\Server
@@ -83,7 +75,10 @@ class SharingPlugin extends DAV\ServerPlugin {
function initialize(DAV\Server $server) {
$this->server = $server;
- $server->resourceTypeMapping['Sabre\\CalDAV\\ISharedCalendar'] = '{' . Plugin::NS_CALENDARSERVER . '}shared';
+
+ if (is_null($this->server->getPlugin('sharing'))) {
+ throw new \LogicException('The generic "sharing" plugin must be loaded before the caldav sharing plugin. Call $server->addPlugin(new \Sabre\DAV\Sharing\Plugin()); before this one.');
+ }
array_push(
$this->server->protectedProperties,
@@ -114,24 +109,8 @@ class SharingPlugin extends DAV\ServerPlugin {
*/
function propFindEarly(DAV\PropFind $propFind, DAV\INode $node) {
- if ($node instanceof IShareableCalendar) {
-
- $propFind->handle('{' . Plugin::NS_CALENDARSERVER . '}invite', function() use ($node) {
- return new Xml\Property\Invite(
- $node->getShares()
- );
- });
-
- }
-
if ($node instanceof ISharedCalendar) {
- $propFind->handle('{' . Plugin::NS_CALENDARSERVER . '}shared-url', function() use ($node) {
- return new Href(
- $node->getSharedUrl()
- );
- });
-
$propFind->handle('{' . Plugin::NS_CALENDARSERVER . '}invite', function() use ($node) {
// Fetching owner information
@@ -158,7 +137,7 @@ class SharingPlugin extends DAV\ServerPlugin {
}
return new Xml\Property\Invite(
- $node->getShares(),
+ $node->getInvites(),
$ownerInfo
);
@@ -179,10 +158,18 @@ class SharingPlugin extends DAV\ServerPlugin {
*/
function propFindLate(DAV\PropFind $propFind, DAV\INode $node) {
- if ($node instanceof IShareableCalendar) {
+ if ($node instanceof ISharedCalendar) {
+ $shareAccess = $node->getShareAccess();
if ($rt = $propFind->get('{DAV:}resourcetype')) {
- if (count($node->getShares()) > 0) {
- $rt->add('{' . Plugin::NS_CALENDARSERVER . '}shared-owner');
+ switch ($shareAccess) {
+ case \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER :
+ $rt->add('{' . Plugin::NS_CALENDARSERVER . '}shared-owner');
+ break;
+ case \Sabre\DAV\Sharing\Plugin::ACCESS_READ :
+ case \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE :
+ $rt->add('{' . Plugin::NS_CALENDARSERVER . '}shared');
+ break;
+
}
}
$propFind->handle('{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes', function() {
@@ -211,21 +198,24 @@ class SharingPlugin extends DAV\ServerPlugin {
function propPatch($path, DAV\PropPatch $propPatch) {
$node = $this->server->tree->getNodeForPath($path);
- if (!$node instanceof IShareableCalendar)
+ if (!$node instanceof ISharedCalendar)
return;
- $propPatch->handle('{DAV:}resourcetype', function($value) use ($node) {
- if ($value->is('{' . Plugin::NS_CALENDARSERVER . '}shared-owner')) return false;
- $shares = $node->getShares();
- $remove = [];
- foreach ($shares as $share) {
- $remove[] = $share['href'];
- }
- $node->updateShares([], $remove);
+ if ($node->getShareAccess() === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER || $node->getShareAccess() === \Sabre\DAV\Sharing\Plugin::ACCESS_NOTSHARED) {
- return true;
+ $propPatch->handle('{DAV:}resourcetype', function($value) use ($node) {
+ if ($value->is('{' . Plugin::NS_CALENDARSERVER . '}shared-owner')) return false;
+ $shares = $node->getInvites();
+ foreach ($shares as $share) {
+ $share->access = DAV\Sharing\Plugin::ACCESS_NOACCESS;
+ }
+ $node->updateInvites($shares);
- });
+ return true;
+
+ });
+
+ }
}
@@ -267,26 +257,12 @@ class SharingPlugin extends DAV\ServerPlugin {
switch ($documentType) {
- // Dealing with the 'share' document, which modified invitees on a
- // calendar.
+ // Both the DAV:share-resource and CALENDARSERVER:share requests
+ // behave identically.
case '{' . Plugin::NS_CALENDARSERVER . '}share' :
- // We can only deal with IShareableCalendar objects
- if (!$node instanceof IShareableCalendar) {
- return;
- }
-
- $this->server->transactionType = 'post-calendar-share';
-
- // Getting ACL info
- $acl = $this->server->getPlugin('acl');
-
- // If there's no ACL support, we allow everything
- if ($acl) {
- $acl->checkPrivileges($path, '{DAV:}write');
- }
-
- $node->updateShares($message->set, $message->remove);
+ $sharingPlugin = $this->server->getPlugin('sharing');
+ $sharingPlugin->shareResource($path, $message->sharees);
$response->setStatus(200);
// Adding this because sending a response body may cause issues,
@@ -328,11 +304,11 @@ class SharingPlugin extends DAV\ServerPlugin {
$response->setHeader('X-Sabre-Status', 'everything-went-well');
if ($url) {
- $writer = $this->server->xml->getWriter($this->server->getBaseUri());
+ $writer = $this->server->xml->getWriter();
$writer->openMemory();
$writer->startDocument();
$writer->startElement('{' . Plugin::NS_CALENDARSERVER . '}shared-as');
- $writer->write(new Href($url));
+ $writer->write(new LocalHref($url));
$writer->endElement();
$response->setHeader('Content-Type', 'application/xml');
$response->setBody($writer->outputMemory());
@@ -345,7 +321,7 @@ class SharingPlugin extends DAV\ServerPlugin {
case '{' . Plugin::NS_CALENDARSERVER . '}publish-calendar' :
// We can only deal with IShareableCalendar objects
- if (!$node instanceof IShareableCalendar) {
+ if (!$node instanceof ISharedCalendar) {
return;
}
$this->server->transactionType = 'post-publish-calendar';
@@ -355,7 +331,7 @@ class SharingPlugin extends DAV\ServerPlugin {
// If there's no ACL support, we allow everything
if ($acl) {
- $acl->checkPrivileges($path, '{DAV:}write');
+ $acl->checkPrivileges($path, '{DAV:}share');
}
$node->setPublishStatus(true);
@@ -373,7 +349,7 @@ class SharingPlugin extends DAV\ServerPlugin {
case '{' . Plugin::NS_CALENDARSERVER . '}unpublish-calendar' :
// We can only deal with IShareableCalendar objects
- if (!$node instanceof IShareableCalendar) {
+ if (!$node instanceof ISharedCalendar) {
return;
}
$this->server->transactionType = 'post-unpublish-calendar';
@@ -383,7 +359,7 @@ class SharingPlugin extends DAV\ServerPlugin {
// If there's no ACL support, we allow everything
if ($acl) {
- $acl->checkPrivileges($path, '{DAV:}write');
+ $acl->checkPrivileges($path, '{DAV:}share');
}
$node->setPublishStatus(false);
diff --git a/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php b/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php
index ee53da2c6..3bb3451f3 100644
--- a/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php
+++ b/vendor/sabre/dav/lib/CalDAV/Subscriptions/Subscription.php
@@ -5,8 +5,8 @@ namespace Sabre\CalDAV\Subscriptions;
use Sabre\DAV\Collection;
use Sabre\DAV\Xml\Property\Href;
use Sabre\DAV\PropPatch;
-use Sabre\DAV\Exception\MethodNotAllowed;
use Sabre\DAVACL\IACL;
+use Sabre\DAVACL\ACLTrait;
use Sabre\CalDAV\Backend\SubscriptionSupport;
/**
@@ -20,6 +20,8 @@ use Sabre\CalDAV\Backend\SubscriptionSupport;
*/
class Subscription extends Collection implements ISubscription, IACL {
+ use ACLTrait;
+
/**
* caldavBackend
*
@@ -144,7 +146,7 @@ class Subscription extends Collection implements ISubscription, IACL {
* The Server class will filter out the extra.
*
* @param array $properties
- * @return void
+ * @return array
*/
function getProperties($properties) {
@@ -154,7 +156,7 @@ class Subscription extends Collection implements ISubscription, IACL {
switch ($prop) {
case '{http://calendarserver.org/ns/}source' :
- $r[$prop] = new Href($this->subscriptionInfo['source'], false);
+ $r[$prop] = new Href($this->subscriptionInfo['source']);
break;
default :
if (array_key_exists($prop, $this->subscriptionInfo)) {
@@ -183,19 +185,6 @@ class Subscription extends Collection implements ISubscription, IACL {
}
/**
- * Returns a group principal.
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -211,22 +200,12 @@ class Subscription extends Collection implements ISubscription, IACL {
return [
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->getOwner(),
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->getOwner(),
'protected' => true,
],
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->getOwner() . '/calendar-proxy-write',
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->getOwner() . '/calendar-proxy-write',
'protected' => true,
],
@@ -239,36 +218,4 @@ class Subscription extends Collection implements ISubscription, IACL {
}
- /**
- * Updates the ACL.
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See \Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php
index 7fb022e33..1ca64f3e8 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/Invite.php
@@ -5,6 +5,7 @@ namespace Sabre\CalDAV\Xml\Notification;
use Sabre\Xml\Writer;
use Sabre\CalDAV\SharingPlugin as SharingPlugin;
use Sabre\CalDAV;
+use Sabre\DAV;
/**
* This class represents the cs:invite-notification notification element.
@@ -210,16 +211,10 @@ class Invite implements NotificationInterface {
switch ($this->type) {
- case SharingPlugin::STATUS_ACCEPTED :
+ case DAV\Sharing\Plugin::INVITE_ACCEPTED :
$writer->writeElement($cs . 'invite-accepted');
break;
- case SharingPlugin::STATUS_DECLINED :
- $writer->writeElement($cs . 'invite-declined');
- break;
- case SharingPlugin::STATUS_DELETED :
- $writer->writeElement($cs . 'invite-deleted');
- break;
- case SharingPlugin::STATUS_NORESPONSE :
+ case DAV\Sharing\Plugin::INVITE_NORESPONSE :
$writer->writeElement($cs . 'invite-noresponse');
break;
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php
index 945323fed..51bfc178a 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Notification/InviteReply.php
@@ -5,6 +5,7 @@ namespace Sabre\CalDAV\Xml\Notification;
use Sabre\Xml\Writer;
use Sabre\CalDAV;
use Sabre\CalDAV\SharingPlugin;
+use Sabre\DAV;
/**
* This class represents the cs:invite-reply notification element.
@@ -162,10 +163,10 @@ class InviteReply implements NotificationInterface {
switch ($this->type) {
- case SharingPlugin::STATUS_ACCEPTED :
+ case DAV\Sharing\Plugin::INVITE_ACCEPTED :
$writer->writeElement($cs . 'invite-accepted');
break;
- case SharingPlugin::STATUS_DECLINED :
+ case DAV\Sharing\Plugin::INVITE_DECLINED :
$writer->writeElement($cs . 'invite-declined');
break;
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php
index 3ee053214..40ff6b936 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/Invite.php
@@ -2,11 +2,10 @@
namespace Sabre\CalDAV\Xml\Property;
-use Sabre\Xml\Element;
-use Sabre\Xml\Reader;
+use Sabre\Xml\XmlSerializable;
use Sabre\Xml\Writer;
use Sabre\CalDAV\Plugin;
-use Sabre\CalDAV\SharingPlugin;
+use Sabre\DAV;
/**
* Invite property
@@ -20,53 +19,23 @@ use Sabre\CalDAV\SharingPlugin;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Invite implements Element {
+class Invite implements XmlSerializable {
/**
* The list of users a calendar has been shared to.
*
- * @var array
+ * @var Sharee[]
*/
- protected $users;
-
- /**
- * The organizer contains information about the person who shared the
- * object.
- *
- * @var array
- */
- protected $organizer;
+ protected $sharees;
/**
* Creates the property.
*
- * Users is an array. Each element of the array has the following
- * properties:
- *
- * * href - Often a mailto: address
- * * commonName - Optional, for example a first and lastname for a user.
- * * status - One of the SharingPlugin::STATUS_* constants.
- * * readOnly - true or false
- * * summary - Optional, description of the share
- *
- * The organizer key is optional to specify. It's only useful when a
- * 'sharee' requests the sharing information.
- *
- * The organizer may have the following properties:
- * * href - Often a mailto: address.
- * * commonName - Optional human-readable name.
- * * firstName - Optional first name.
- * * lastName - Optional last name.
- *
- * If you wonder why these two structures are so different, I guess a
- * valid answer is that the current spec is still a draft.
- *
- * @param array $users
+ * @param Sharee[] $sharees
*/
- function __construct(array $users, array $organizer = null) {
+ function __construct(array $sharees) {
- $this->users = $users;
- $this->organizer = $organizer;
+ $this->sharees = $sharees;
}
@@ -77,7 +46,7 @@ class Invite implements Element {
*/
function getValue() {
- return $this->users;
+ return $this->sharees;
}
@@ -104,149 +73,55 @@ class Invite implements Element {
$cs = '{' . Plugin::NS_CALENDARSERVER . '}';
- if (!is_null($this->organizer)) {
-
- $writer->startElement($cs . 'organizer');
- $writer->writeElement('{DAV:}href', $this->organizer['href']);
-
- if (isset($this->organizer['commonName']) && $this->organizer['commonName']) {
- $writer->writeElement($cs . 'common-name', $this->organizer['commonName']);
- }
- if (isset($this->organizer['firstName']) && $this->organizer['firstName']) {
- $writer->writeElement($cs . 'first-name', $this->organizer['firstName']);
- }
- if (isset($this->organizer['lastName']) && $this->organizer['lastName']) {
- $writer->writeElement($cs . 'last-name', $this->organizer['lastName']);
- }
- $writer->endElement(); // organizer
+ foreach ($this->sharees as $sharee) {
- }
-
- foreach ($this->users as $user) {
-
- $writer->startElement($cs . 'user');
- $writer->writeElement('{DAV:}href', $user['href']);
- if (isset($user['commonName']) && $user['commonName']) {
- $writer->writeElement($cs . 'common-name', $user['commonName']);
- }
- switch ($user['status']) {
-
- case SharingPlugin::STATUS_ACCEPTED :
- $writer->writeElement($cs . 'invite-accepted');
- break;
- case SharingPlugin::STATUS_DECLINED :
- $writer->writeElement($cs . 'invite-declined');
- break;
- case SharingPlugin::STATUS_NORESPONSE :
- $writer->writeElement($cs . 'invite-noresponse');
- break;
- case SharingPlugin::STATUS_INVALID :
- $writer->writeElement($cs . 'invite-invalid');
- break;
- }
-
- $writer->startElement($cs . 'access');
- if ($user['readOnly']) {
- $writer->writeElement($cs . 'read');
+ if ($sharee->access === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) {
+ $writer->startElement($cs . 'organizer');
} else {
- $writer->writeElement($cs . 'read-write');
- }
- $writer->endElement(); // access
-
- if (isset($user['summary']) && $user['summary']) {
- $writer->writeElement($cs . 'summary', $user['summary']);
- }
-
- $writer->endElement(); //user
-
- }
-
- }
-
- /**
- * The deserialize method is called during xml parsing.
- *
- * This method is called statictly, this is because in theory this method
- * may be used as a type of constructor, or factory method.
- *
- * Often you want to return an instance of the current class, but you are
- * free to return other data as well.
- *
- * You are responsible for advancing the reader to the next element. Not
- * doing anything will result in a never-ending loop.
- *
- * If you just want to skip parsing for this element altogether, you can
- * just call $reader->next();
- *
- * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
- * the next element.
- *
- * @param Reader $reader
- * @return mixed
- */
- static function xmlDeserialize(Reader $reader) {
-
- $cs = '{' . Plugin::NS_CALENDARSERVER . '}';
-
- $users = [];
-
- foreach ($reader->parseInnerTree() as $elem) {
+ $writer->startElement($cs . 'user');
- if ($elem['name'] !== $cs . 'user')
- continue;
-
- $user = [
- 'href' => null,
- 'commonName' => null,
- 'readOnly' => null,
- 'summary' => null,
- 'status' => null,
- ];
-
- foreach ($elem['value'] as $userElem) {
-
- switch ($userElem['name']) {
- case $cs . 'invite-accepted' :
- $user['status'] = SharingPlugin::STATUS_ACCEPTED;
- break;
- case $cs . 'invite-declined' :
- $user['status'] = SharingPlugin::STATUS_DECLINED;
+ switch ($sharee->inviteStatus) {
+ case DAV\Sharing\Plugin::INVITE_ACCEPTED :
+ $writer->writeElement($cs . 'invite-accepted');
break;
- case $cs . 'invite-noresponse' :
- $user['status'] = SharingPlugin::STATUS_NORESPONSE;
+ case DAV\Sharing\Plugin::INVITE_DECLINED :
+ $writer->writeElement($cs . 'invite-declined');
break;
- case $cs . 'invite-invalid' :
- $user['status'] = SharingPlugin::STATUS_INVALID;
+ case DAV\Sharing\Plugin::INVITE_NORESPONSE :
+ $writer->writeElement($cs . 'invite-noresponse');
break;
- case '{DAV:}href' :
- $user['href'] = $userElem['value'];
+ case DAV\Sharing\Plugin::INVITE_INVALID :
+ $writer->writeElement($cs . 'invite-invalid');
break;
- case $cs . 'common-name' :
- $user['commonName'] = $userElem['value'];
- break;
- case $cs . 'access' :
- foreach ($userElem['value'] as $accessHref) {
- if ($accessHref['name'] === $cs . 'read') {
- $user['readOnly'] = true;
- }
- }
+ }
+
+ $writer->startElement($cs . 'access');
+ switch ($sharee->access) {
+ case DAV\Sharing\Plugin::ACCESS_READWRITE :
+ $writer->writeElement($cs . 'read-write');
break;
- case $cs . 'summary' :
- $user['summary'] = $userElem['value'];
+ case DAV\Sharing\Plugin::ACCESS_READ :
+ $writer->writeElement($cs . 'read');
break;
}
+ $writer->endElement(); // access
}
- if (!$user['status']) {
- throw new \InvalidArgumentException('Every user must have one of cs:invite-accepted, cs:invite-declined, cs:invite-noresponse or cs:invite-invalid');
- }
- $users[] = $user;
+ $href = new \Sabre\DAV\Xml\Property\Href($sharee->href);
+ $href->xmlSerialize($writer);
- }
+ if (isset($sharee->properties['{DAV:}displayname'])) {
+ $writer->writeElement($cs . 'common-name', $sharee->properties['{DAV:}displayname']);
+ }
+ if ($sharee->comment) {
+ $writer->writeElement($cs . 'summary', $sharee->comment);
+ }
+ $writer->endElement(); // organizer or user
- return new self($users);
+ }
}
+
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php b/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php
index 4a253e008..a82b8eff7 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Property/ScheduleCalendarTransp.php
@@ -4,8 +4,8 @@ namespace Sabre\CalDAV\Xml\Property;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
+use Sabre\Xml\Deserializer;
use Sabre\Xml\Writer;
-use Sabre\Xml\Element\Elements;
use Sabre\CalDAV\Plugin;
/**
@@ -116,23 +116,13 @@ class ScheduleCalendarTransp implements Element {
*/
static function xmlDeserialize(Reader $reader) {
- $elems = Elements::xmlDeserialize($reader);
+ $elems = Deserializer\enum($reader, Plugin::NS_CALDAV);
- $value = null;
-
- foreach ($elems as $elem) {
- switch ($elem) {
- case '{' . Plugin::NS_CALDAV . '}opaque' :
- $value = self::OPAQUE;
- break;
- case '{' . Plugin::NS_CALDAV . '}transparent' :
- $value = self::TRANSPARENT;
- break;
- }
+ if (in_array('transparent', $elems)) {
+ $value = self::TRANSPARENT;
+ } else {
+ $value = self::OPAQUE;
}
- if (is_null($value))
- return null;
-
return new self($value);
}
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php
index ec627156f..2ecf6c2bb 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/InviteReply.php
@@ -2,12 +2,13 @@
namespace Sabre\CalDAV\Xml\Request;
+use Sabre\CalDAV\Plugin;
+use Sabre\CalDAV\SharingPlugin;
+use Sabre\DAV;
+use Sabre\DAV\Exception\BadRequest;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
use Sabre\Xml\Element\KeyValue;
-use Sabre\DAV\Exception\BadRequest;
-use Sabre\CalDAV\Plugin;
-use Sabre\CalDAV\SharingPlugin;
/**
* Invite-reply POST request parser
@@ -121,10 +122,10 @@ class InviteReply implements XmlDeserializable {
}
break;
case '{' . Plugin::NS_CALENDARSERVER . '}invite-accepted' :
- $status = SharingPlugin::STATUS_ACCEPTED;
+ $status = DAV\Sharing\Plugin::INVITE_ACCEPTED;
break;
case '{' . Plugin::NS_CALENDARSERVER . '}invite-declined' :
- $status = SharingPlugin::STATUS_DECLINED;
+ $status = DAV\Sharing\Plugin::INVITE_DECLINED;
break;
case '{' . Plugin::NS_CALENDARSERVER . '}in-reply-to' :
$inReplyTo = $value;
diff --git a/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php b/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php
index dacc5dc94..b5d9a133c 100644
--- a/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php
+++ b/vendor/sabre/dav/lib/CalDAV/Xml/Request/Share.php
@@ -2,9 +2,10 @@
namespace Sabre\CalDAV\Xml\Request;
+use Sabre\CalDAV\Plugin;
+use Sabre\DAV\Xml\Element\Sharee;
use Sabre\Xml\Reader;
use Sabre\Xml\XmlDeserializable;
-use Sabre\CalDAV\Plugin;
/**
* Share POST request parser
@@ -20,37 +21,20 @@ use Sabre\CalDAV\Plugin;
class Share implements XmlDeserializable {
/**
- * The list of new people added or updated.
- *
- * Every element has the following keys:
- * 1. href - An email address
- * 2. commonName - Some name
- * 3. summary - An optional description of the share
- * 4. readOnly - true or false
- *
- * @var array
- */
- public $set = [];
-
- /**
- * List of people removed from the share list.
- *
- * The list is a flat list of email addresses (including mailto:).
+ * The list of new people added or updated or removed from the share.
*
- * @var array
+ * @var Sharee[]
*/
- public $remove = [];
+ public $sharees = [];
/**
* Constructor
*
- * @param array $set
- * @param array $remove
+ * @param Sharee[] $sharees
*/
- function __construct(array $set, array $remove) {
+ function __construct(array $sharees) {
- $this->set = $set;
- $this->remove = $remove;
+ $this->sharees = $sharees;
}
@@ -77,13 +61,12 @@ class Share implements XmlDeserializable {
*/
static function xmlDeserialize(Reader $reader) {
- $elems = $reader->parseInnerTree([
+ $elems = $reader->parseGetElements([
'{' . Plugin::NS_CALENDARSERVER . '}set' => 'Sabre\\Xml\\Element\\KeyValue',
'{' . Plugin::NS_CALENDARSERVER . '}remove' => 'Sabre\\Xml\\Element\\KeyValue',
]);
- $set = [];
- $remove = [];
+ $sharees = [];
foreach ($elems as $elem) {
switch ($elem['name']) {
@@ -94,22 +77,34 @@ class Share implements XmlDeserializable {
$sumElem = '{' . Plugin::NS_CALENDARSERVER . '}summary';
$commonName = '{' . Plugin::NS_CALENDARSERVER . '}common-name';
- $set[] = [
+ $properties = [];
+ if (isset($sharee[$commonName])) {
+ $properties['{DAV:}displayname'] = $sharee[$commonName];
+ }
+
+ $access = array_key_exists('{' . Plugin::NS_CALENDARSERVER . '}read-write', $sharee)
+ ? \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE
+ : \Sabre\DAV\Sharing\Plugin::ACCESS_READ;
+
+ $sharees[] = new Sharee([
'href' => $sharee['{DAV:}href'],
- 'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null,
- 'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null,
- 'readOnly' => !array_key_exists('{' . Plugin::NS_CALENDARSERVER . '}read-write', $sharee),
- ];
+ 'properties' => $properties,
+ 'access' => $access,
+ 'comment' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null
+ ]);
break;
case '{' . Plugin::NS_CALENDARSERVER . '}remove' :
- $remove[] = $elem['value']['{DAV:}href'];
+ $sharees[] = new Sharee([
+ 'href' => $elem['value']['{DAV:}href'],
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS
+ ]);
break;
}
}
- return new self($set, $remove);
+ return new self($sharees);
}
diff --git a/vendor/sabre/dav/lib/CardDAV/AddressBook.php b/vendor/sabre/dav/lib/CardDAV/AddressBook.php
index 70bec8760..6dd098618 100644
--- a/vendor/sabre/dav/lib/CardDAV/AddressBook.php
+++ b/vendor/sabre/dav/lib/CardDAV/AddressBook.php
@@ -16,6 +16,8 @@ use Sabre\DAVACL;
*/
class AddressBook extends DAV\Collection implements IAddressBook, DAV\IProperties, DAVACL\IACL, DAV\Sync\ISyncCollection, DAV\IMultiGet {
+ use DAVACL\ACLTrait;
+
/**
* This is an array with addressbook information
*
@@ -236,48 +238,6 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
}
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
- * Returns a list of ACE's for this node.
- *
- * Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
- * currently the only supported privileges
- * * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
- */
- function getACL() {
-
- return [
- [
- 'privilege' => '{DAV:}read',
- 'principal' => $this->getOwner(),
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
- 'principal' => $this->getOwner(),
- 'protected' => true,
- ],
-
- ];
-
- }
/**
* This method returns the ACL's for card nodes in this address book.
@@ -290,12 +250,7 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
return [
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->getOwner(),
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->getOwner(),
'protected' => true,
],
@@ -303,37 +258,6 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
/**
* This method returns the current sync-token for this collection.
diff --git a/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php b/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php
index ebc251832..888a44a40 100644
--- a/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php
+++ b/vendor/sabre/dav/lib/CardDAV/AddressBookHome.php
@@ -18,6 +18,8 @@ use Sabre\Uri;
*/
class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection, DAVACL\IACL {
+ use DAVACL\ACLTrait;
+
/**
* Principal uri
*
@@ -186,78 +188,4 @@ class AddressBookHome extends DAV\Collection implements DAV\IExtendedCollection,
}
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
- * Returns a list of ACE's for this node.
- *
- * Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
- * currently the only supported privileges
- * * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
- */
- function getACL() {
-
- return [
- [
- 'privilege' => '{DAV:}read',
- 'principal' => $this->principalUri,
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
- 'principal' => $this->principalUri,
- 'protected' => true,
- ],
- ];
-
- }
-
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php b/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php
index b9691b906..54e42b899 100644
--- a/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php
+++ b/vendor/sabre/dav/lib/CardDAV/Backend/BackendInterface.php
@@ -55,12 +55,15 @@ interface BackendInterface {
function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch);
/**
- * Creates a new address book
+ * Creates a new address book.
+ *
+ * This method should return the id of the new address book. The id can be
+ * in any format, including ints, strings, arrays or objects.
*
* @param string $principalUri
* @param string $url Just the 'basename' of the url.
* @param array $properties
- * @return void
+ * @return mixed
*/
function createAddressBook($principalUri, $url, array $properties);
diff --git a/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php
index 5509ddc02..7c3feff93 100644
--- a/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/CardDAV/Backend/PDO.php
@@ -128,7 +128,7 @@ class PDO extends AbstractBackend implements SyncSupport {
} else {
$query .= ', ';
}
- $query .= ' `' . $key . '` = :' . $key . ' ';
+ $query .= ' ' . $key . ' = :' . $key . ' ';
}
$query .= ' WHERE id = :addressbookid';
@@ -180,7 +180,9 @@ class PDO extends AbstractBackend implements SyncSupport {
$query = 'INSERT INTO ' . $this->addressBooksTableName . ' (uri, displayname, description, principaluri, synctoken) VALUES (:uri, :displayname, :description, :principaluri, 1)';
$stmt = $this->pdo->prepare($query);
$stmt->execute($values);
- return $this->pdo->lastInsertId();
+ return $this->pdo->lastInsertId(
+ $this->addressBooksTableName . '_id_seq'
+ );
}
@@ -230,6 +232,7 @@ class PDO extends AbstractBackend implements SyncSupport {
$result = [];
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$row['etag'] = '"' . $row['etag'] . '"';
+ $row['lastmodified'] = (int)$row['lastmodified'];
$result[] = $row;
}
return $result;
@@ -258,6 +261,7 @@ class PDO extends AbstractBackend implements SyncSupport {
if (!$result) return false;
$result['etag'] = '"' . $result['etag'] . '"';
+ $result['lastmodified'] = (int)$result['lastmodified'];
return $result;
}
@@ -286,6 +290,7 @@ class PDO extends AbstractBackend implements SyncSupport {
$result = [];
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
$row['etag'] = '"' . $row['etag'] . '"';
+ $row['lastmodified'] = (int)$row['lastmodified'];
$result[] = $row;
}
return $result;
diff --git a/vendor/sabre/dav/lib/CardDAV/Card.php b/vendor/sabre/dav/lib/CardDAV/Card.php
index 8da672502..0a040be6b 100644
--- a/vendor/sabre/dav/lib/CardDAV/Card.php
+++ b/vendor/sabre/dav/lib/CardDAV/Card.php
@@ -14,6 +14,8 @@ use Sabre\DAV;
*/
class Card extends DAV\File implements ICard, DAVACL\IACL {
+ use DAVACL\ACLTrait;
+
/**
* CardDAV backend
*
@@ -181,18 +183,6 @@ class Card extends DAV\File implements ICard, DAVACL\IACL {
}
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
/**
* Returns a list of ACE's for this node.
@@ -215,12 +205,7 @@ class Card extends DAV\File implements ICard, DAVACL\IACL {
return [
[
- 'privilege' => '{DAV:}read',
- 'principal' => $this->addressBookInfo['principaluri'],
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
+ 'privilege' => '{DAV:}all',
'principal' => $this->addressBookInfo['principaluri'],
'protected' => true,
],
@@ -228,36 +213,4 @@ class Card extends DAV\File implements ICard, DAVACL\IACL {
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/CardDAV/Plugin.php b/vendor/sabre/dav/lib/CardDAV/Plugin.php
index b8bded098..0507df100 100644
--- a/vendor/sabre/dav/lib/CardDAV/Plugin.php
+++ b/vendor/sabre/dav/lib/CardDAV/Plugin.php
@@ -4,7 +4,7 @@ namespace Sabre\CardDAV;
use Sabre\DAV;
use Sabre\DAV\Exception\ReportNotSupported;
-use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAV\Xml\Property\LocalHref;
use Sabre\DAVACL;
use Sabre\HTTP;
use Sabre\HTTP\RequestInterface;
@@ -156,11 +156,11 @@ class Plugin extends DAV\ServerPlugin {
$path = $propFind->getPath();
$propFind->handle('{' . self::NS_CARDDAV . '}addressbook-home-set', function() use ($path) {
- return new Href($this->getAddressBookHomeForPrincipal($path) . '/');
+ return new LocalHref($this->getAddressBookHomeForPrincipal($path) . '/');
});
if ($this->directories) $propFind->handle('{' . self::NS_CARDDAV . '}directory-gateway', function() {
- return new Href($this->directories);
+ return new LocalHref($this->directories);
});
}
@@ -334,12 +334,7 @@ class Plugin extends DAV\ServerPlugin {
$data = stream_get_contents($data);
}
- $before = md5($data);
-
- // Converting the data to unicode, if needed.
- $data = DAV\StringUtil::ensureUTF8($data);
-
- if (md5($data) !== $before) $modified = true;
+ $before = $data;
try {
@@ -366,11 +361,56 @@ class Plugin extends DAV\ServerPlugin {
throw new DAV\Exception\UnsupportedMediaType('This collection can only support vcard objects.');
}
- if (!isset($vobj->UID)) {
- // No UID in vcards is invalid, but we'll just add it in anyway.
- $vobj->add('UID', DAV\UUIDUtil::getUUID());
+ $options = VObject\Node::PROFILE_CARDDAV;
+ $prefer = $this->server->getHTTPPrefer();
+
+ if ($prefer['handling'] !== 'strict') {
+ $options |= VObject\Node::REPAIR;
+ }
+
+ $messages = $vobj->validate($options);
+
+ $highestLevel = 0;
+ $warningMessage = null;
+
+ // $messages contains a list of problems with the vcard, along with
+ // their severity.
+ foreach ($messages as $message) {
+
+ if ($message['level'] > $highestLevel) {
+ // Recording the highest reported error level.
+ $highestLevel = $message['level'];
+ $warningMessage = $message['message'];
+ }
+
+ switch ($message['level']) {
+
+ case 1 :
+ // Level 1 means that there was a problem, but it was repaired.
+ $modified = true;
+ break;
+ case 2 :
+ // Level 2 means a warning, but not critical
+ break;
+ case 3 :
+ // Level 3 means a critical error
+ throw new DAV\Exception\UnsupportedMediaType('Validation error in vCard: ' . $message['message']);
+
+ }
+
+ }
+ if ($warningMessage) {
+ $this->server->httpResponse->setHeader(
+ 'X-Sabre-Ew-Gross',
+ 'vCard validation warning: ' . $warningMessage
+ );
+
+ // Re-serializing object.
$data = $vobj->serialize();
- $modified = true;
+ if (!$modified && strcmp($data, $before) !== 0) {
+ // This ensures that the system does not send an ETag back.
+ $modified = true;
+ }
}
// Destroy circular references to PHP will GC the object.
@@ -803,33 +843,49 @@ class Plugin extends DAV\ServerPlugin {
/**
* Converts a vcard blob to a different version, or jcard.
*
- * @param string $data
+ * @param string|resource $data
* @param string $target
* @return string
*/
protected function convertVCard($data, $target) {
- $data = VObject\Reader::read($data);
- switch ($target) {
- default :
- case 'vcard3' :
- $data = $data->convert(VObject\Document::VCARD30);
- $newResult = $data->serialize();
- break;
- case 'vcard4' :
- $data = $data->convert(VObject\Document::VCARD40);
- $newResult = $data->serialize();
- break;
- case 'jcard' :
- $data = $data->convert(VObject\Document::VCARD40);
- $newResult = json_encode($data->jsonSerialize());
- break;
-
+ if (is_resource($data)) {
+ $data = stream_get_contents($data);
}
- // Destroy circular references to PHP will GC the object.
- $data->destroy();
+ $input = VObject\Reader::read($data);
+ $output = null;
+ try {
- return $newResult;
+ switch ($target) {
+ default :
+ case 'vcard3' :
+ if ($input->getDocumentType() === VObject\Document::VCARD30) {
+ // Do nothing
+ return $data;
+ }
+ $output = $input->convert(VObject\Document::VCARD30);
+ return $output->serialize();
+ case 'vcard4' :
+ if ($input->getDocumentType() === VObject\Document::VCARD40) {
+ // Do nothing
+ return $data;
+ }
+ $output = $input->convert(VObject\Document::VCARD40);
+ return $output->serialize();
+ case 'jcard' :
+ $output = $input->convert(VObject\Document::VCARD40);
+ return json_encode($output);
+
+ }
+
+ } finally {
+
+ // Destroy circular references to PHP will GC the object.
+ $input->destroy();
+ if (!is_null($output)) {
+ $output->destroy();
+ }
+ }
}
diff --git a/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php b/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php
index de8b3bb84..d015589ad 100644
--- a/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php
+++ b/vendor/sabre/dav/lib/CardDAV/VCFExportPlugin.php
@@ -70,14 +70,34 @@ class VCFExportPlugin extends DAV\ServerPlugin {
$aclPlugin->checkPrivileges($path, '{DAV:}read');
}
- $response->setHeader('Content-Type', 'text/directory');
- $response->setStatus(200);
-
$nodes = $this->server->getPropertiesForPath($path, [
'{' . Plugin::NS_CARDDAV . '}address-data',
], 1);
- $response->setBody($this->generateVCF($nodes));
+ $format = 'text/directory';
+
+ $output = null;
+ $filenameExtension = null;
+
+ switch ($format) {
+ case 'text/directory':
+ $output = $this->generateVCF($nodes);
+ $filenameExtension = '.vcf';
+ break;
+ }
+
+ $filename = preg_replace(
+ '/[^a-zA-Z0-9-_ ]/um',
+ '',
+ $node->getName()
+ );
+ $filename .= '-' . date('Y-m-d') . $filenameExtension;
+
+ $response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
+ $response->setHeader('Content-Type', $format);
+
+ $response->setStatus(200);
+ $response->setBody($output);
// Returning false to break the event chain
return false;
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php
index 0251decc1..85c5f30d5 100644
--- a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php
+++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php
@@ -155,8 +155,14 @@ abstract class AbstractDigest implements BackendInterface {
$response
);
$auth->init();
+
+ $oldStatus = $response->getStatus() ?: 200;
$auth->requireLogin();
+ // Preventing the digest utility from modifying the http status code,
+ // this should be handled by the main plugin.
+ $response->setStatus($oldStatus);
+
}
}
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php
index 6756e68df..3a687d747 100644
--- a/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php
+++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php
@@ -25,7 +25,7 @@ class File extends AbstractDigest {
/**
* Creates the backend object.
*
- * If the filename argument is passed in, it will parse out the specified file fist.
+ * If the filename argument is passed in, it will parse out the specified file first.
*
* @param string|null $filename
*/
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Plugin.php b/vendor/sabre/dav/lib/DAV/Auth/Plugin.php
index 818d8a4ad..4b5f35ac3 100644
--- a/vendor/sabre/dav/lib/DAV/Auth/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Auth/Plugin.php
@@ -4,7 +4,6 @@ namespace Sabre\DAV\Auth;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
-use Sabre\HTTP\URLUtil;
use Sabre\DAV\Exception\NotAuthenticated;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;
@@ -26,6 +25,20 @@ use Sabre\DAV\ServerPlugin;
class Plugin extends ServerPlugin {
/**
+ * By default this plugin will require that the user is authenticated,
+ * and refuse any access if the user is not authenticated.
+ *
+ * If this setting is set to false, we let the user through, whether they
+ * are authenticated or not.
+ *
+ * This is useful if you want to allow both authenticated and
+ * unauthenticated access to your server.
+ *
+ * @param bool
+ */
+ public $autoRequireLogin = true;
+
+ /**
* authentication backends
*/
protected $backends;
@@ -108,27 +121,6 @@ class Plugin extends ServerPlugin {
}
/**
- * Returns the current username.
- *
- * This method is deprecated and is only kept for backwards compatibility
- * purposes. Please switch to getCurrentPrincipal().
- *
- * @deprecated Will be removed in a future version!
- * @return string|null
- */
- function getCurrentUser() {
-
- // We just do a 'basename' on the principal to give back a sane value
- // here.
- list(, $userName) = URLUtil::splitPath(
- $this->getCurrentPrincipal()
- );
-
- return $userName;
-
- }
-
- /**
* This method is called before any HTTP method and forces users to be authenticated
*
* @param RequestInterface $request
@@ -154,6 +146,50 @@ class Plugin extends ServerPlugin {
return;
}
+
+ $authResult = $this->check($request, $response);
+
+ if ($authResult[0]) {
+ // Auth was successful
+ $this->currentPrincipal = $authResult[1];
+ $this->loginFailedReasons = null;
+ return;
+ }
+
+
+
+ // If we got here, it means that no authentication backend was
+ // successful in authenticating the user.
+ $this->currentPrincipal = null;
+ $this->loginFailedReasons = $authResult[1];
+
+ if ($this->autoRequireLogin) {
+ $this->challenge($request, $response);
+ throw new NotAuthenticated(implode(', ', $authResult[1]));
+ }
+
+ }
+
+ /**
+ * Checks authentication credentials, and logs the user in if possible.
+ *
+ * This method returns an array. The first item in the array is a boolean
+ * indicating if login was successful.
+ *
+ * If login was successful, the second item in the array will contain the
+ * current principal url/path of the logged in user.
+ *
+ * If login was not successful, the second item in the array will contain a
+ * an array with strings. The strings are a list of reasons why login was
+ * unsuccesful. For every auth backend there will be one reason, so usually
+ * there's just one.
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return array
+ */
+ function check(RequestInterface $request, ResponseInterface $response) {
+
if (!$this->backends) {
throw new \Sabre\DAV\Exception('No authentication backends were configured on this server.');
}
@@ -172,20 +208,56 @@ class Plugin extends ServerPlugin {
if ($result[0]) {
$this->currentPrincipal = $result[1];
// Exit early
- return;
+ return [true, $result[1]];
}
$reasons[] = $result[1];
}
- // If we got here, it means that no authentication backend was
- // successful in authenticating the user.
- $this->currentPrincipal = null;
+ return [false, $reasons];
+
+ }
+
+ /**
+ * This method sends authentication challenges to the user.
+ *
+ * This method will for example cause a HTTP Basic backend to set a
+ * WWW-Authorization header, indicating to the client that it should
+ * authenticate.
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return array
+ */
+ function challenge(RequestInterface $request, ResponseInterface $response) {
foreach ($this->backends as $backend) {
$backend->challenge($request, $response);
}
- throw new NotAuthenticated(implode(', ', $reasons));
+
+ }
+
+ /**
+ * List of reasons why login failed for the last login operation.
+ *
+ * @var string[]|null
+ */
+ protected $loginFailedReasons;
+
+ /**
+ * Returns a list of reasons why login was unsuccessful.
+ *
+ * This method will return the login failed reasons for the last login
+ * operation. One for each auth backend.
+ *
+ * This method returns null if the last authentication attempt was
+ * successful, or if there was no authentication attempt yet.
+ *
+ * @return string[]|null
+ */
+ function getLoginFailedReasons() {
+
+ return $this->loginFailedReasons;
}
diff --git a/vendor/sabre/dav/lib/DAV/Browser/Plugin.php b/vendor/sabre/dav/lib/DAV/Browser/Plugin.php
index 07ca6c3e5..49359a045 100644
--- a/vendor/sabre/dav/lib/DAV/Browser/Plugin.php
+++ b/vendor/sabre/dav/lib/DAV/Browser/Plugin.php
@@ -48,7 +48,7 @@ class Plugin extends DAV\ServerPlugin {
public $uninterestingProperties = [
'{DAV:}supportedlock',
'{DAV:}acl-restrictions',
- '{DAV:}supported-privilege-set',
+// '{DAV:}supported-privilege-set',
'{DAV:}supported-method-set',
];
@@ -112,7 +112,7 @@ class Plugin extends DAV\ServerPlugin {
$getVars = $request->getQueryParameters();
// CSP headers
- $this->server->httpResponse->setHeader('Content-Security-Policy', "img-src 'self'; style-src 'self';");
+ $this->server->httpResponse->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
$sabreAction = isset($getVars['sabreAction']) ? $getVars['sabreAction'] : null;
@@ -354,7 +354,7 @@ class Plugin extends DAV\ServerPlugin {
$output = '';
if ($this->enablePost) {
- $this->server->emit('onHTMLActionsPanel', [$node, &$output]);
+ $this->server->emit('onHTMLActionsPanel', [$node, &$output, $path]);
}
if ($output) {
@@ -368,7 +368,7 @@ class Plugin extends DAV\ServerPlugin {
$html .= $this->generateFooter();
- $this->server->httpResponse->setHeader('Content-Security-Policy', "img-src 'self'; style-src 'self';");
+ $this->server->httpResponse->setHeader('Content-Security-Policy', "default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';");
return $html;
@@ -477,7 +477,7 @@ HTML;
$version = DAV\Version::VERSION;
return <<<HTML
-<footer>Generated by SabreDAV $version (c)2007-2015 <a href="http://sabre.io/">http://sabre.io/</a></footer>
+<footer>Generated by SabreDAV $version (c)2007-2016 <a href="http://sabre.io/">http://sabre.io/</a></footer>
</body>
</html>
HTML;
@@ -493,9 +493,10 @@ HTML;
*
* @param DAV\INode $node
* @param mixed $output
+ * @param string $path
* @return void
*/
- function htmlActionsPanel(DAV\INode $node, &$output) {
+ function htmlActionsPanel(DAV\INode $node, &$output, $path) {
if (!$node instanceof DAV\ICollection)
return;
diff --git a/vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.css b/vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.css
index c9ab2c74f..8869597f0 100644
--- a/vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.css
+++ b/vendor/sabre/dav/lib/DAV/Browser/assets/sabredav.css
@@ -96,12 +96,12 @@ header a {
vertical-align: middle;
border: 0;
}
-input, button {
+input, button, select {
font: inherit;
color: inherit;
}
-input[type=text] {
+input[type=text], select {
border: 1px solid #bbbbbb;
line-height: 22px;
padding: 5px 10px;
@@ -200,7 +200,7 @@ section table {
line-height: 40px;
}
-.actions input[type=text] {
+.actions input[type=text], select {
width: 450px;
}
diff --git a/vendor/sabre/dav/lib/DAV/Client.php b/vendor/sabre/dav/lib/DAV/Client.php
index d46b397b6..08d5d4702 100644
--- a/vendor/sabre/dav/lib/DAV/Client.php
+++ b/vendor/sabre/dav/lib/DAV/Client.php
@@ -3,6 +3,7 @@
namespace Sabre\DAV;
use Sabre\HTTP;
+use Sabre\Uri;
/**
* SabreDAV DAV client
@@ -387,20 +388,10 @@ class Client extends HTTP\Client {
*/
function getAbsoluteUrl($url) {
- // If the url starts with http:// or https://, the url is already absolute.
- if (preg_match('/^http(s?):\/\//', $url)) {
- return $url;
- }
-
- // If the url starts with a slash, we must calculate the url based off
- // the root of the base url.
- if (strpos($url, '/') === 0) {
- $parts = parse_url($this->baseUri);
- return $parts['scheme'] . '://' . $parts['host'] . (isset($parts['port']) ? ':' . $parts['port'] : '') . $url;
- }
-
- // Otherwise...
- return $this->baseUri . $url;
+ return Uri\resolve(
+ $this->baseUri,
+ $url
+ );
}
diff --git a/vendor/sabre/dav/lib/DAV/CorePlugin.php b/vendor/sabre/dav/lib/DAV/CorePlugin.php
index 3a70b2a7e..a1b052915 100644
--- a/vendor/sabre/dav/lib/DAV/CorePlugin.php
+++ b/vendor/sabre/dav/lib/DAV/CorePlugin.php
@@ -50,6 +50,8 @@ class CorePlugin extends ServerPlugin {
$server->on('propFind', [$this, 'propFindNode'], 120);
$server->on('propFind', [$this, 'propFindLate'], 200);
+ $server->on('exception', [$this, 'exception']);
+
}
/**
@@ -844,10 +846,8 @@ class CorePlugin extends ServerPlugin {
if ($node instanceof IProperties && $propertyNames = $propFind->get404Properties()) {
$nodeProperties = $node->getProperties($propertyNames);
- foreach ($propertyNames as $propertyName) {
- if (array_key_exists($propertyName, $nodeProperties)) {
- $propFind->set($propertyName, $nodeProperties[$propertyName], 200);
- }
+ foreach ($nodeProperties as $propertyName => $propertyValue) {
+ $propFind->set($propertyName, $propertyValue, 200);
}
}
@@ -905,6 +905,38 @@ class CorePlugin extends ServerPlugin {
}
/**
+ * Listens for exception events, and automatically logs them.
+ *
+ * @param Exception $e
+ */
+ function exception($e) {
+
+ $logLevel = \Psr\Log\LogLevel::CRITICAL;
+ if ($e instanceof \Sabre\DAV\Exception) {
+ // If it's a standard sabre/dav exception, it means we have a http
+ // status code available.
+ $code = $e->getHTTPCode();
+
+ if ($code >= 400 && $code < 500) {
+ // user error
+ $logLevel = \Psr\Log\LogLevel::INFO;
+ } else {
+ // Server-side error. We mark it's as an error, but it's not
+ // critical.
+ $logLevel = \Psr\Log\LogLevel::ERROR;
+ }
+ }
+
+ $this->server->getLogger()->log(
+ $logLevel,
+ 'Uncaught exception',
+ [
+ 'exception' => $e,
+ ]
+ );
+ }
+
+ /**
* Returns a bunch of meta-data about the plugin.
*
* Providing this information is optional, and is mainly displayed by the
diff --git a/vendor/sabre/dav/lib/DAV/FS/Directory.php b/vendor/sabre/dav/lib/DAV/FS/Directory.php
index 963e5554c..362f7a411 100644
--- a/vendor/sabre/dav/lib/DAV/FS/Directory.php
+++ b/vendor/sabre/dav/lib/DAV/FS/Directory.php
@@ -140,10 +140,10 @@ class Directory extends Node implements DAV\ICollection, DAV\IQuota {
* @return array
*/
function getQuotaInfo() {
-
+ $absolute = realpath($this->path);
return [
- disk_total_space($this->path) - disk_free_space($this->path),
- disk_free_space($this->path)
+ disk_total_space($absolute) - disk_free_space($absolute),
+ disk_free_space($absolute)
];
}
diff --git a/vendor/sabre/dav/lib/DAV/FSExt/Directory.php b/vendor/sabre/dav/lib/DAV/FSExt/Directory.php
index 648079e26..dd5f992db 100644
--- a/vendor/sabre/dav/lib/DAV/FSExt/Directory.php
+++ b/vendor/sabre/dav/lib/DAV/FSExt/Directory.php
@@ -131,12 +131,7 @@ class Directory extends Node implements DAV\ICollection, DAV\IQuota, DAV\IMoveTa
foreach ($iterator as $entry) {
- $node = $entry->getFilename();
-
- if ($node === '.sabredav')
- continue;
-
- $nodes[] = $this->getChild($node);
+ $nodes[] = $this->getChild($entry->getFilename());
}
return $nodes;
@@ -153,9 +148,6 @@ class Directory extends Node implements DAV\ICollection, DAV\IQuota, DAV\IMoveTa
// Deleting all children
foreach ($this->getChildren() as $child) $child->delete();
- // Removing resource info, if its still around
- if (file_exists($this->path . '/.sabredav')) unlink($this->path . '/.sabredav');
-
// Removing the directory itself
rmdir($this->path);
diff --git a/vendor/sabre/dav/lib/DAV/File.php b/vendor/sabre/dav/lib/DAV/File.php
index e0a0391db..675956b22 100644
--- a/vendor/sabre/dav/lib/DAV/File.php
+++ b/vendor/sabre/dav/lib/DAV/File.php
@@ -15,12 +15,24 @@ namespace Sabre\DAV;
abstract class File extends Node implements IFile {
/**
- * Updates the data
+ * Replaces the contents of the file.
*
- * data is a readable stream resource.
+ * The data argument is a readable stream resource.
*
- * @param resource $data
- * @return void
+ * After a succesful put operation, you may choose to return an ETag. The
+ * etag must always be surrounded by double-quotes. These quotes must
+ * appear in the actual string you're returning.
+ *
+ * Clients may use the ETag from a PUT request to later on make sure that
+ * when they update the file, the contents haven't changed in the mean
+ * time.
+ *
+ * If you don't plan to store the file byte-by-byte, and you return a
+ * different object on a subsequent GET you are strongly recommended to not
+ * return an ETag, and just return null.
+ *
+ * @param string|resource $data
+ * @return string|null
*/
function put($data) {
diff --git a/vendor/sabre/dav/lib/DAV/ICollection.php b/vendor/sabre/dav/lib/DAV/ICollection.php
index 390d9b741..7793070d3 100644
--- a/vendor/sabre/dav/lib/DAV/ICollection.php
+++ b/vendor/sabre/dav/lib/DAV/ICollection.php
@@ -54,14 +54,14 @@ interface ICollection extends INode {
* exist.
*
* @param string $name
- * @return DAV\INode
+ * @return INode
*/
function getChild($name);
/**
* Returns an array with all the child nodes
*
- * @return DAV\INode[]
+ * @return INode[]
*/
function getChildren();
diff --git a/vendor/sabre/dav/lib/DAV/IFile.php b/vendor/sabre/dav/lib/DAV/IFile.php
index e16a3a58a..37e7cd33c 100644
--- a/vendor/sabre/dav/lib/DAV/IFile.php
+++ b/vendor/sabre/dav/lib/DAV/IFile.php
@@ -32,7 +32,7 @@ interface IFile extends INode {
* different object on a subsequent GET you are strongly recommended to not
* return an ETag, and just return null.
*
- * @param resource $data
+ * @param resource|data $data
* @return string|null
*/
function put($data);
diff --git a/vendor/sabre/dav/lib/DAV/INode.php b/vendor/sabre/dav/lib/DAV/INode.php
index b5e6cb9ef..bb884934d 100644
--- a/vendor/sabre/dav/lib/DAV/INode.php
+++ b/vendor/sabre/dav/lib/DAV/INode.php
@@ -36,9 +36,10 @@ interface INode {
function setName($name);
/**
- * Returns the last modification time, as a unix timestamp
+ * Returns the last modification time, as a unix timestamp. Return null
+ * if the information is not available.
*
- * @return int
+ * @return int|null
*/
function getLastModified();
diff --git a/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php b/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php
index 910e4979d..2fe843884 100644
--- a/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php
+++ b/vendor/sabre/dav/lib/DAV/PropertyStorage/Backend/PDO.php
@@ -88,6 +88,9 @@ class PDO implements BackendInterface {
$stmt->execute([$path]);
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ if (gettype($row['value']) === 'resource') {
+ $row['value'] = stream_get_contents($row['value']);
+ }
switch ($row['valuetype']) {
case null :
case self::VT_STRING :
@@ -121,7 +124,26 @@ class PDO implements BackendInterface {
$propPatch->handleRemaining(function($properties) use ($path) {
- $updateStmt = $this->pdo->prepare("REPLACE INTO " . $this->tableName . " (path, name, valuetype, value) VALUES (?, ?, ?, ?)");
+
+ if ($this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'pgsql') {
+
+ $updateSql = <<<SQL
+INSERT INTO {$this->tableName} (path, name, valuetype, value)
+VALUES (:path, :name, :valuetype, :value)
+ON CONFLICT (path, name)
+DO UPDATE SET valuetype = :valuetype, value = :value
+SQL;
+
+
+ } else {
+ $updateSql = <<<SQL
+REPLACE INTO {$this->tableName} (path, name, valuetype, value)
+VALUES (:path, :name, :valuetype, :value)
+SQL;
+
+ }
+
+ $updateStmt = $this->pdo->prepare($updateSql);
$deleteStmt = $this->pdo->prepare("DELETE FROM " . $this->tableName . " WHERE path = ? AND name = ?");
foreach ($properties as $name => $value) {
@@ -136,7 +158,14 @@ class PDO implements BackendInterface {
$valueType = self::VT_OBJECT;
$value = serialize($value);
}
- $updateStmt->execute([$path, $name, $valueType, $value]);
+
+ $updateStmt->bindParam('path', $path, \PDO::PARAM_STR);
+ $updateStmt->bindParam('name', $name, \PDO::PARAM_STR);
+ $updateStmt->bindParam('valuetype', $valueType, \PDO::PARAM_INT);
+ $updateStmt->bindParam('value', $value, \PDO::PARAM_LOB);
+
+ $updateStmt->execute();
+
} else {
$deleteStmt->execute([$path, $name]);
}
diff --git a/vendor/sabre/dav/lib/DAV/Server.php b/vendor/sabre/dav/lib/DAV/Server.php
index b37652812..024b7a557 100644
--- a/vendor/sabre/dav/lib/DAV/Server.php
+++ b/vendor/sabre/dav/lib/DAV/Server.php
@@ -8,6 +8,10 @@ use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Sabre\HTTP\URLUtil;
use Sabre\Uri;
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerAwareTrait;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
/**
* Main DAV server class
@@ -16,7 +20,9 @@ use Sabre\Uri;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class Server extends EventEmitter {
+class Server extends EventEmitter implements LoggerAwareInterface {
+
+ use LoggerAwareTrait;
/**
* Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree
@@ -431,6 +437,20 @@ class Server extends EventEmitter {
}
/**
+ * Returns the PSR-3 logger objcet.
+ *
+ * @return LoggerInterface
+ */
+ function getLogger() {
+
+ if (!$this->logger) {
+ $this->logger = new NullLogger();
+ }
+ return $this->logger;
+
+ }
+
+ /**
* Handles a http request, and execute a method based on its name
*
* @param RequestInterface $request
@@ -1177,9 +1197,20 @@ class Server extends EventEmitter {
if (!$success) {
$result = $mkCol->getResult();
- // generateMkCol needs the href key to exist.
- $result['href'] = $uri;
- return $result;
+
+ $formattedResult = [
+ 'href' => $uri,
+ ];
+
+ foreach ($result as $propertyName => $status) {
+
+ if (!isset($formattedResult[$status])) {
+ $formattedResult[$status] = [];
+ }
+ $formattedResult[$status][$propertyName] = null;
+
+ }
+ return $formattedResult;
}
$this->tree->markDirty($parentUri);
diff --git a/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php b/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php
new file mode 100644
index 000000000..034aefbdc
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Sharing/ISharedNode.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Sabre\DAV\Sharing;
+
+use Sabre\DAV\INode;
+
+/**
+ * This interface represents a resource that has sharing capabilities, either
+ * because it's possible for an owner to share the resource, or because this is
+ * an instance of a shared resource.
+ *
+ * @copyright Copyright (C) fruux GmbH. (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+interface ISharedNode extends INode {
+
+ /**
+ * Returns the 'access level' for the instance of this shared resource.
+ *
+ * The value should be one of the Sabre\DAV\Sharing\Plugin::ACCESS_
+ * constants.
+ *
+ * @return int
+ */
+ function getShareAccess();
+
+ /**
+ * This function must return a URI that uniquely identifies the shared
+ * resource. This URI should be identical across instances, and is
+ * also used in several other XML bodies to connect invites to
+ * resources.
+ *
+ * This may simply be a relative reference to the original shared instance,
+ * but it could also be a urn. As long as it's a valid URI and unique.
+ *
+ * @return string
+ */
+ function getShareResourceUri();
+
+ /**
+ * Updates the list of sharees.
+ *
+ * Every item must be a Sharee object.
+ *
+ * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees
+ * @return void
+ */
+ function updateInvites(array $sharees);
+
+ /**
+ * Returns the list of people whom this resource is shared with.
+ *
+ * Every item in the returned array must be a Sharee object with
+ * at least the following properties set:
+ *
+ * * $href
+ * * $shareAccess
+ * * $inviteStatus
+ *
+ * and optionally:
+ *
+ * * $properties
+ *
+ * @return \Sabre\DAV\Xml\Element\Sharee[]
+ */
+ function getInvites();
+
+}
diff --git a/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php b/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php
new file mode 100644
index 000000000..354d06a56
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Sharing/Plugin.php
@@ -0,0 +1,342 @@
+<?php
+
+namespace Sabre\DAV\Sharing;
+
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\INode;
+use Sabre\DAV\PropFind;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+use Sabre\DAV\Xml\Property;
+use Sabre\DAV\Xml\Element\Sharee;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
+
+/**
+ * This plugin implements HTTP requests and properties related to:
+ *
+ * draft-pot-webdav-resource-sharing
+ *
+ * This specification allows people to share webdav resources with others.
+ *
+ * @copyright Copyright (C) 2007-2015 fruux GmbH. (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Plugin extends ServerPlugin {
+
+ const ACCESS_NOTSHARED = 0;
+ const ACCESS_SHAREDOWNER = 1;
+ const ACCESS_READ = 2;
+ const ACCESS_READWRITE = 3;
+ const ACCESS_NOACCESS = 4;
+
+ const INVITE_NORESPONSE = 1;
+ const INVITE_ACCEPTED = 2;
+ const INVITE_DECLINED = 3;
+ const INVITE_INVALID = 4;
+
+ /**
+ * Reference to SabreDAV server object.
+ *
+ * @var Sabre\DAV\Server
+ */
+ protected $server;
+
+ /**
+ * This method should return a list of server-features.
+ *
+ * This is for example 'versioning' and is added to the DAV: header
+ * in an OPTIONS response.
+ *
+ * @return array
+ */
+ function getFeatures() {
+
+ return ['resource-sharing'];
+
+ }
+
+ /**
+ * Returns a plugin name.
+ *
+ * Using this name other plugins will be able to access other plugins
+ * using \Sabre\DAV\Server::getPlugin
+ *
+ * @return string
+ */
+ function getPluginName() {
+
+ return 'sharing';
+
+ }
+
+ /**
+ * This initializes the plugin.
+ *
+ * This function is called by Sabre\DAV\Server, after
+ * addPlugin is called.
+ *
+ * This method should set up the required event subscriptions.
+ *
+ * @param Server $server
+ * @return void
+ */
+ function initialize(Server $server) {
+
+ $this->server = $server;
+
+ $server->xml->elementMap['{DAV:}share-resource'] = 'Sabre\\DAV\\Xml\\Request\\ShareResource';
+
+ array_push(
+ $server->protectedProperties,
+ '{DAV:}share-mode'
+ );
+
+ $server->on('method:POST', [$this, 'httpPost']);
+ $server->on('propFind', [$this, 'propFind']);
+ $server->on('getSupportedPrivilegeSet', [$this, 'getSupportedPrivilegeSet']);
+ $server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']);
+ $server->on('onBrowserPostAction', [$this, 'browserPostAction']);
+
+ }
+
+ /**
+ * Updates the list of sharees on a shared resource.
+ *
+ * The sharees array is a list of people that are to be added modified
+ * or removed in the list of shares.
+ *
+ * @param string $path
+ * @param Sharee[] $sharees
+ * @return void
+ */
+ function shareResource($path, array $sharees) {
+
+ $node = $this->server->tree->getNodeForPath($path);
+
+ if (!$node instanceof ISharedNode) {
+
+ throw new Forbidden('Sharing is not allowed on this node');
+
+ }
+
+ // Getting ACL info
+ $acl = $this->server->getPlugin('acl');
+
+ // If there's no ACL support, we allow everything
+ if ($acl) {
+ $acl->checkPrivileges($path, '{DAV:}share');
+ }
+
+ foreach ($sharees as $sharee) {
+ // We're going to attempt to get a local principal uri for a share
+ // href by emitting the getPrincipalByUri event.
+ $principal = null;
+ $this->server->emit('getPrincipalByUri', [$sharee->href, &$principal]);
+ $sharee->principal = $principal;
+ }
+ $node->updateInvites($sharees);
+
+ }
+
+ /**
+ * This event is triggered when properties are requested for nodes.
+ *
+ * This allows us to inject any sharings-specific properties.
+ *
+ * @param PropFind $propFind
+ * @param INode $node
+ * @return void
+ */
+ function propFind(PropFind $propFind, INode $node) {
+
+ if ($node instanceof ISharedNode) {
+
+ $propFind->handle('{DAV:}share-access', function() use ($node) {
+
+ return new Property\ShareAccess($node->getShareAccess());
+
+ });
+ $propFind->handle('{DAV:}invite', function() use ($node) {
+
+ return new Property\Invite($node->getInvites());
+
+ });
+ $propFind->handle('{DAV:}share-resource-uri', function() use ($node) {
+
+ return new Property\Href($node->getShareResourceUri());
+
+ });
+
+ }
+
+ }
+
+ /**
+ * We intercept this to handle POST requests on shared resources
+ *
+ * @param RequestInterface $request
+ * @param ResponseInterface $response
+ * @return null|bool
+ */
+ function httpPost(RequestInterface $request, ResponseInterface $response) {
+
+ $path = $request->getPath();
+ $contentType = $request->getHeader('Content-Type');
+
+ // We're only interested in the davsharing content type.
+ if (strpos($contentType, 'application/davsharing+xml') === false) {
+ return;
+ }
+
+ $message = $this->server->xml->parse(
+ $request->getBody(),
+ $request->getUrl(),
+ $documentType
+ );
+
+ switch ($documentType) {
+
+ case '{DAV:}share-resource':
+
+ $this->shareResource($path, $message->sharees);
+ $response->setStatus(200);
+ // Adding this because sending a response body may cause issues,
+ // and I wanted some type of indicator the response was handled.
+ $response->setHeader('X-Sabre-Status', 'everything-went-well');
+
+ // Breaking the event chain
+ return false;
+
+ default :
+ throw new BadRequest('Unexpected document type: ' . $documentType . ' for this Content-Type');
+
+ }
+
+ }
+
+ /**
+ * This method is triggered whenever a subsystem reqeuests the privileges
+ * hat are supported on a particular node.
+ *
+ * We need to add a number of privileges for scheduling purposes.
+ *
+ * @param INode $node
+ * @param array $supportedPrivilegeSet
+ */
+ function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilegeSet) {
+
+ if ($node instanceof ISharedNode) {
+ $supportedPrivilegeSet['{DAV:}share'] = [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ];
+ }
+ }
+
+ /**
+ * Returns a bunch of meta-data about the plugin.
+ *
+ * Providing this information is optional, and is mainly displayed by the
+ * Browser plugin.
+ *
+ * The description key in the returned array may contain html and will not
+ * be sanitized.
+ *
+ * @return array
+ */
+ function getPluginInfo() {
+
+ return [
+ 'name' => $this->getPluginName(),
+ 'description' => 'This plugin implements WebDAV resource sharing',
+ 'link' => 'https://github.com/evert/webdav-sharing'
+ ];
+
+ }
+
+ /**
+ * This method is used to generate HTML output for the
+ * DAV\Browser\Plugin.
+ *
+ * @param INode $node
+ * @param string $output
+ * @param string $path
+ * @return bool|null
+ */
+ function htmlActionsPanel(INode $node, &$output, $path) {
+
+ if (!$node instanceof ISharedNode) {
+ return;
+ }
+
+ $aclPlugin = $this->server->getPlugin('acl');
+ if ($aclPlugin) {
+ if (!$aclPlugin->checkPrivileges($path, '{DAV:}share', \Sabre\DAVACL\Plugin::R_PARENT, false)) {
+ // Sharing is not permitted, we will not draw this interface.
+ return;
+ }
+ }
+
+ $output .= '<tr><td colspan="2"><form method="post" action="">
+ <h3>Share this resource</h3>
+ <input type="hidden" name="sabreAction" value="share" />
+ <label>Share with (uri):</label> <input type="text" name="href" placeholder="mailto:user@example.org"/><br />
+ <label>Access</label>
+ <select name="access">
+ <option value="readwrite">Read-write</option>
+ <option value="read">Read-only</option>
+ <option value="no-access">Revoke access</option>
+ </select><br />
+ <input type="submit" value="share" />
+ </form>
+ </td></tr>';
+
+ }
+
+ /**
+ * This method is triggered for POST actions generated by the browser
+ * plugin.
+ *
+ * @param string $path
+ * @param string $action
+ * @param array $postVars
+ */
+ function browserPostAction($path, $action, $postVars) {
+
+ if ($action !== 'share') {
+ return;
+ }
+
+ if (empty($postVars['href'])) {
+ throw new BadRequest('The "href" POST parameter is required');
+ }
+ if (empty($postVars['access'])) {
+ throw new BadRequest('The "access" POST parameter is required');
+ }
+
+ $accessMap = [
+ 'readwrite' => self::ACCESS_READWRITE,
+ 'read' => self::ACCESS_READ,
+ 'no-access' => self::ACCESS_NOACCESS,
+ ];
+
+ if (!isset($accessMap[$postVars['access']])) {
+ throw new BadRequest('The "access" POST must be readwrite, read or no-access');
+ }
+ $sharee = new Sharee([
+ 'href' => $postVars['href'],
+ 'access' => $accessMap[$postVars['access']],
+ ]);
+
+ $this->shareResource(
+ $path,
+ [$sharee]
+ );
+ return false;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAV/Tree.php b/vendor/sabre/dav/lib/DAV/Tree.php
index 4563f7c72..5d2792503 100644
--- a/vendor/sabre/dav/lib/DAV/Tree.php
+++ b/vendor/sabre/dav/lib/DAV/Tree.php
@@ -229,7 +229,7 @@ class Tree {
// flushing the entire cache
$path = trim($path, '/');
foreach ($this->cache as $nodePath => $node) {
- if ($nodePath == $path || strpos($nodePath, $path . '/') === 0)
+ if ($path === '' || $nodePath == $path || strpos($nodePath, $path . '/') === 0)
unset($this->cache[$nodePath]);
}
diff --git a/vendor/sabre/dav/lib/DAV/Version.php b/vendor/sabre/dav/lib/DAV/Version.php
index f9331943a..2fda85db8 100644
--- a/vendor/sabre/dav/lib/DAV/Version.php
+++ b/vendor/sabre/dav/lib/DAV/Version.php
@@ -14,6 +14,6 @@ class Version {
/**
* Full version number
*/
- const VERSION = '3.1.3';
+ const VERSION = '3.2.0';
}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php b/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php
new file mode 100644
index 000000000..dcfd7bd2e
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Xml/Element/Sharee.php
@@ -0,0 +1,199 @@
+<?php
+
+namespace Sabre\DAV\Xml\Element;
+
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Sharing\Plugin;
+use Sabre\DAV\Xml\Property\Href;
+use Sabre\DAV\Xml\Property\ShareAccess;
+use Sabre\Xml\Deserializer;
+use Sabre\Xml\Element;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+
+/**
+ * This class represents the {DAV:}sharee element.
+ *
+ * @copyright Copyright (C) fruux GmbH. (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Sharee implements Element {
+
+ /**
+ * A URL. Usually a mailto: address, could also be a principal url.
+ * This uniquely identifies the sharee.
+ *
+ * @var string
+ */
+ public $href;
+
+ /**
+ * A local principal path. The server will do its best to locate the
+ * principal uri based on the given uri. If we could find a local matching
+ * principal uri, this property will contain the value.
+ *
+ * @var string|null
+ */
+ public $principal;
+
+ /**
+ * A list of WebDAV properties that describe the sharee. This might for
+ * example contain a {DAV:}displayname with the real name of the user.
+ *
+ * @var array
+ */
+ public $properties = [];
+
+ /**
+ * Share access level. One of the Sabre\DAV\Sharing\Plugin::ACCESS
+ * constants.
+ *
+ * Can be one of:
+ *
+ * ACCESS_READ
+ * ACCESS_READWRITE
+ * ACCESS_SHAREDOWNER
+ * ACCESS_NOACCESS
+ *
+ * depending on context.
+ *
+ * @var int
+ */
+ public $access;
+
+ /**
+ * When a sharee is originally invited to a share, the sharer may add
+ * a comment. This will be placed in this property.
+ *
+ * @var string
+ */
+ public $comment;
+
+ /**
+ * The status of the invite, should be one of the
+ * Sabre\DAV\Sharing\Plugin::INVITE constants.
+ *
+ * @var int
+ */
+ public $inviteStatus;
+
+ /**
+ * Creates the object
+ *
+ * $properties will be used to populate all internal properties.
+ *
+ * @param array $properties
+ */
+ function __construct(array $properties = []) {
+
+ foreach ($properties as $k => $v) {
+
+ if (property_exists($this, $k)) {
+ $this->$k = $v;
+ } else {
+ throw new \InvalidArgumentException('Unknown property: ' . $k);
+ }
+
+ }
+
+ }
+
+ /**
+ * The xmlSerialize method is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+
+ $writer->write([
+ new Href($this->href),
+ '{DAV:}prop' => $this->properties,
+ '{DAV:}share-access' => new ShareAccess($this->access),
+ ]);
+ switch ($this->inviteStatus) {
+ case Plugin::INVITE_NORESPONSE :
+ $writer->writeElement('{DAV:}invite-noresponse');
+ break;
+ case Plugin::INVITE_ACCEPTED :
+ $writer->writeElement('{DAV:}invite-accepted');
+ break;
+ case Plugin::INVITE_DECLINED :
+ $writer->writeElement('{DAV:}invite-declined');
+ break;
+ case Plugin::INVITE_INVALID :
+ $writer->writeElement('{DAV:}invite-invalid');
+ break;
+ }
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ // Temporarily override configuration
+ $reader->pushContext();
+ $reader->elementMap['{DAV:}share-access'] = 'Sabre\DAV\Xml\Property\ShareAccess';
+ $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\keyValue';
+
+ $elems = Deserializer\keyValue($reader, 'DAV:');
+
+ // Restore previous configuration
+ $reader->popContext();
+
+ $sharee = new self();
+ if (!isset($elems['href'])) {
+ throw new BadRequest('Every {DAV:}sharee must have a {DAV:}href child-element');
+ }
+ $sharee->href = $elems['href'];
+
+ if (isset($elems['prop'])) {
+ $sharee->properties = $elems['prop'];
+ }
+ if (isset($elems['comment'])) {
+ $sharee->comment = $elems['comment'];
+ }
+ if (!isset($elems['share-access'])) {
+ throw new BadRequest('Every {DAV:}sharee must have a {DAV:}share-access child element');
+ }
+ $sharee->access = $elems['share-access']->getValue();
+ return $sharee;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php b/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php
index 538e98d0f..0027f72e1 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/Href.php
@@ -7,6 +7,7 @@ use Sabre\DAV\Browser\HtmlOutputHelper;
use Sabre\Xml\Element;
use Sabre\Xml\Reader;
use Sabre\Xml\Writer;
+use Sabre\Uri;
/**
* Href property
@@ -32,13 +33,6 @@ class Href implements Element, HtmlOutput {
protected $hrefs;
/**
- * Automatically prefix the url with the server base directory
- *
- * @var bool
- */
- protected $autoPrefix = true;
-
- /**
* Constructor
*
* You must either pass a string for a single href, or an array of hrefs.
@@ -47,16 +41,13 @@ class Href implements Element, HtmlOutput {
* and not relative to the servers base uri.
*
* @param string|string[] $href
- * @param bool $autoPrefix
*/
- function __construct($hrefs, $autoPrefix = true) {
+ function __construct($hrefs) {
if (is_string($hrefs)) {
$hrefs = [$hrefs];
}
$this->hrefs = $hrefs;
- $this->autoPrefix = $autoPrefix;
-
}
@@ -104,9 +95,7 @@ class Href implements Element, HtmlOutput {
function xmlSerialize(Writer $writer) {
foreach ($this->getHrefs() as $href) {
- if ($this->autoPrefix) {
- $href = $writer->contextUri . \Sabre\HTTP\encodePath($href);
- }
+ $href = Uri\resolve($writer->contextUri, $href);
$writer->writeElement('{DAV:}href', $href);
}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php b/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php
new file mode 100644
index 000000000..0616ff113
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/Invite.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Sabre\DAV\Xml\Property;
+
+use Sabre\DAV\Sharing\Sharee;
+use Sabre\Xml\XmlSerializable;
+use Sabre\Xml\Writer;
+
+/**
+ * This class represents the {DAV:}invite property.
+ *
+ * This property is defined here:
+ * https://tools.ietf.org/html/draft-pot-webdav-resource-sharing-03#section-4.4.2
+ *
+ * This property is used by clients to determine who currently has access to
+ * a shared resource, what their access level is and what their invite status
+ * is.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class Invite implements XmlSerializable {
+
+ /**
+ * A list of sharees
+ *
+ * @var Sharee[]
+ */
+ public $sharees = [];
+
+ /**
+ * Creates the property.
+ *
+ * @param Sharee[] $sharees
+ */
+ function __construct(array $sharees) {
+
+ $this->sharees = $sharees;
+
+ }
+
+ /**
+ * The xmlSerialize method is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ foreach ($this->sharees as $sharee) {
+ $writer->writeElement('{DAV:}sharee', $sharee);
+ }
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php b/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php
new file mode 100644
index 000000000..76a27b95d
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/LocalHref.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Sabre\DAV\Xml\Property;
+
+use Sabre\HTTP;
+
+/**
+ * LocalHref property
+ *
+ * Like the Href property, this element represents {DAV:}href. The difference
+ * is that this is used stricly for paths on the server. The LocalHref property
+ * will prepare the path so it's a valid URI.
+ *
+ * These two objects behave identically:
+ * new LocalHref($path)
+ * new Href(\Sabre\HTTP\encodePath($path))
+ *
+ * LocalPath basically ensures that your spaces are %20, and everything that
+ * needs to be is uri encoded.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class LocalHref extends Href {
+
+ /**
+ * Constructor
+ *
+ * You must either pass a string for a single href, or an array of hrefs.
+ *
+ * If auto-prefix is set to false, the hrefs will be treated as absolute
+ * and not relative to the servers base uri.
+ *
+ * @param string|string[] $href
+ */
+ function __construct($hrefs) {
+
+ parent::__construct(array_map(
+ function($href) {
+ return \Sabre\HTTP\encodePath($href);
+ },
+ (array)$hrefs
+ ));
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php b/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php
new file mode 100644
index 000000000..a3fc6b0e1
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/ShareAccess.php
@@ -0,0 +1,143 @@
+<?php
+
+namespace Sabre\DAV\Xml\Property;
+
+use Sabre\DAV\Sharing\Plugin as SharingPlugin;
+use Sabre\DAV\Exception\BadRequest;
+use Sabre\Xml\Element;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Writer;
+
+/**
+ * This class represents the {DAV:}share-access property.
+ *
+ * This property is defined here:
+ * https://tools.ietf.org/html/draft-pot-webdav-resource-sharing-03#section-4.4.1
+ *
+ * This property is used to indicate if a resource is a shared resource, and
+ * whether the instance of the shared resource is the original instance, or
+ * an instance belonging to a sharee.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class ShareAccess implements Element {
+
+ /**
+ * Either SHARED or SHAREDOWNER
+ *
+ * @var int
+ */
+ protected $value;
+
+ /**
+ * Creates the property.
+ *
+ * The constructor value must be one of the
+ * \Sabre\DAV\Sharing\Plugin::ACCESS_ constants.
+ *
+ * @param int $shareAccess
+ */
+ function __construct($shareAccess) {
+
+ $this->value = $shareAccess;
+
+ }
+
+ /**
+ * Returns the current value.
+ *
+ * @return int
+ */
+ function getValue() {
+
+ return $this->value;
+
+ }
+
+ /**
+ * The xmlSerialize method is called during xml writing.
+ *
+ * Use the $writer argument to write its own xml serialization.
+ *
+ * An important note: do _not_ create a parent element. Any element
+ * implementing XmlSerializble should only ever write what's considered
+ * its 'inner xml'.
+ *
+ * The parent of the current element is responsible for writing a
+ * containing element.
+ *
+ * This allows serializers to be re-used for different element names.
+ *
+ * If you are opening new elements, you must also close them again.
+ *
+ * @param Writer $writer
+ * @return void
+ */
+ function xmlSerialize(Writer $writer) {
+
+ switch ($this->value) {
+
+ case SharingPlugin::ACCESS_NOTSHARED :
+ $writer->writeElement('{DAV:}not-shared');
+ break;
+ case SharingPlugin::ACCESS_SHAREDOWNER :
+ $writer->writeElement('{DAV:}shared-owner');
+ break;
+ case SharingPlugin::ACCESS_READ :
+ $writer->writeElement('{DAV:}read');
+ break;
+ case SharingPlugin::ACCESS_READWRITE :
+ $writer->writeElement('{DAV:}read-write');
+ break;
+ case SharingPlugin::ACCESS_NOACCESS :
+ $writer->writeElement('{DAV:}no-access');
+ break;
+
+ }
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $elems = $reader->parseInnerTree();
+ foreach ($elems as $elem) {
+ switch ($elem['name']) {
+ case '{DAV:}not-shared' :
+ return new self(SharingPlugin::ACCESS_NOTSHARED);
+ case '{DAV:}shared-owner' :
+ return new self(SharingPlugin::ACCESS_SHAREDOWNER);
+ case '{DAV:}read' :
+ return new self(SharingPlugin::ACCESS_READ);
+ case '{DAV:}read-write' :
+ return new self(SharingPlugin::ACCESS_READWRITE);
+ case '{DAV:}no-access' :
+ return new self(SharingPlugin::ACCESS_NOACCESS);
+ }
+ }
+ throw new BadRequest('Invalid value for {DAV:}share-access element');
+
+ }
+}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php
index 56b418db6..7641f3739 100644
--- a/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php
+++ b/vendor/sabre/dav/lib/DAV/Xml/Property/SupportedMethodSet.php
@@ -32,16 +32,11 @@ class SupportedMethodSet implements XmlSerializable, HtmlOutput {
/**
* Creates the property
*
- * Any reports passed in the constructor
- * should be valid report-types in clark-notation.
- *
- * Either a string or an array of strings must be passed.
- *
- * @param string|string[] $methods
+ * @param string[] $methods
*/
- function __construct($methods = null) {
+ function __construct(array $methods) {
- $this->methods = (array)$methods;
+ $this->methods = $methods;
}
diff --git a/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php b/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php
new file mode 100644
index 000000000..965e5857c
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAV/Xml/Request/ShareResource.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Sabre\DAV\Xml\Request;
+
+use Sabre\Xml\Reader;
+use Sabre\Xml\XmlDeserializable;
+use Sabre\DAV\Xml\Element\Sharee;
+
+/**
+ * ShareResource request parser.
+ *
+ * This class parses the {DAV:}share-resource POST request as defined in:
+ *
+ * https://tools.ietf.org/html/draft-pot-webdav-resource-sharing-01#section-5.3.2.1
+ *
+ * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/).
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class ShareResource implements XmlDeserializable {
+
+ /**
+ * The list of new people added or updated or removed from the share.
+ *
+ * @var Sharee[]
+ */
+ public $sharees = [];
+
+ /**
+ * Constructor
+ *
+ * @param Sharee[] $sharees
+ */
+ function __construct(array $sharees) {
+
+ $this->sharees = $sharees;
+
+ }
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $elems = $reader->parseInnerTree([
+ '{DAV:}sharee' => 'Sabre\DAV\Xml\Element\Sharee',
+ '{DAV:}share-access' => 'Sabre\DAV\Xml\Property\ShareAccess',
+ '{DAV:}prop' => 'Sabre\Xml\Deserializer\keyValue',
+ ]);
+
+ $sharees = [];
+
+ foreach ($elems as $elem) {
+ if ($elem['name'] !== '{DAV:}sharee') continue;
+ $sharees[] = $elem['value'];
+
+ }
+
+ return new self($sharees);
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/ACLTrait.php b/vendor/sabre/dav/lib/DAVACL/ACLTrait.php
new file mode 100644
index 000000000..602654a2e
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/ACLTrait.php
@@ -0,0 +1,100 @@
+<?php
+
+namespace Sabre\DAVACL;
+
+/**
+ * This trait is a default implementation of the IACL interface.
+ *
+ * In many cases you only want to implement 1 or to of the IACL functions,
+ * this trait allows you to be a bit lazier.
+ *
+ * By default this trait grants all privileges to the owner of the resource.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (https://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+trait ACLTrait {
+
+ /**
+ * Returns the owner principal
+ *
+ * This must be a url to a principal, or null if there's no owner
+ *
+ * @return string|null
+ */
+ function getOwner() {
+
+ return null;
+
+ }
+
+ /**
+ * Returns a group principal
+ *
+ * This must be a url to a principal, or null if there's no owner
+ *
+ * @return string|null
+ */
+ function getGroup() {
+
+ return null;
+
+ }
+
+ /**
+ * Returns a list of ACE's for this node.
+ *
+ * Each ACE has the following properties:
+ * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
+ * currently the only supported privileges
+ * * 'principal', a url to the principal who owns the node
+ * * 'protected' (optional), indicating that this ACE is not allowed to
+ * be updated.
+ *
+ * @return array
+ */
+ function getACL() {
+
+ return [
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
+ 'protected' => true,
+ ]
+ ];
+
+ }
+
+ /**
+ * Updates the ACL
+ *
+ * This method will receive a list of new ACE's as an array argument.
+ *
+ * @param array $acl
+ * @return void
+ */
+ function setACL(array $acl) {
+
+ throw new \Sabre\DAV\Exception\Forbidden('Setting ACL is not supported on this node');
+ }
+
+ /**
+ * Returns the list of supported privileges for this node.
+ *
+ * The returned data structure is a list of nested privileges.
+ * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
+ * standard structure.
+ *
+ * If null is returned from this method, the default privilege set is used,
+ * which is fine for most common usecases.
+ *
+ * @return array|null
+ */
+ function getSupportedPrivilegeSet() {
+
+ return null;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php b/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php
index 460f78981..9d2026380 100644
--- a/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php
+++ b/vendor/sabre/dav/lib/DAVACL/AbstractPrincipalCollection.php
@@ -110,7 +110,7 @@ abstract class AbstractPrincipalCollection extends DAV\Collection implements IPr
*
* @param string $name
* @throws DAV\Exception\NotFound
- * @return IPrincipal
+ * @return DAV\INode
*/
function getChild($name) {
diff --git a/vendor/sabre/dav/lib/DAVACL/FS/Collection.php b/vendor/sabre/dav/lib/DAVACL/FS/Collection.php
index 5fab4768c..1c08b43b1 100644
--- a/vendor/sabre/dav/lib/DAVACL/FS/Collection.php
+++ b/vendor/sabre/dav/lib/DAVACL/FS/Collection.php
@@ -3,6 +3,7 @@
namespace Sabre\DAVACL\FS;
use Sabre\DAV\FSExt\Directory as BaseCollection;
+use Sabre\DAVACL\ACLTrait;
use Sabre\DAVACL\IACL;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
@@ -16,6 +17,8 @@ use Sabre\DAV\Exception\NotFound;
*/
class Collection extends BaseCollection implements IACL {
+ use ACLTrait;
+
/**
* A list of ACL rules.
*
@@ -52,8 +55,8 @@ class Collection extends BaseCollection implements IACL {
* exist.
*
* @param string $name
- * @throws DAV\Exception\NotFound
- * @return DAV\INode
+ * @throws NotFound
+ * @return \Sabre\DAV\INode
*/
function getChild($name) {
@@ -88,19 +91,6 @@ class Collection extends BaseCollection implements IACL {
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -118,36 +108,4 @@ class Collection extends BaseCollection implements IACL {
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's as an array argument.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new Forbidden('Setting ACL is not allowed here');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/DAVACL/FS/File.php b/vendor/sabre/dav/lib/DAVACL/FS/File.php
index 0d549528b..387597bf7 100644
--- a/vendor/sabre/dav/lib/DAVACL/FS/File.php
+++ b/vendor/sabre/dav/lib/DAVACL/FS/File.php
@@ -4,7 +4,7 @@ namespace Sabre\DAVACL\FS;
use Sabre\DAV\FSExt\File as BaseFile;
use Sabre\DAVACL\IACL;
-use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAVACL\ACLTrait;
/**
* This is an ACL-enabled file node.
@@ -15,6 +15,8 @@ use Sabre\DAV\Exception\Forbidden;
*/
class File extends BaseFile implements IACL {
+ use ACLTrait;
+
/**
* A list of ACL rules.
*
@@ -58,19 +60,6 @@ class File extends BaseFile implements IACL {
}
/**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -88,36 +77,4 @@ class File extends BaseFile implements IACL {
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's as an array argument.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new Forbidden('Setting ACL is not allowed here');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php b/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php
index c27616770..9e21353ea 100644
--- a/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php
+++ b/vendor/sabre/dav/lib/DAVACL/FS/HomeCollection.php
@@ -2,8 +2,8 @@
namespace Sabre\DAVACL\FS;
-use Sabre\DAV\Exception\Forbidden;
use Sabre\DAVACL\AbstractPrincipalCollection;
+use Sabre\DAVACL\ACLTrait;
use Sabre\DAVACL\IACL;
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
use Sabre\Uri;
@@ -21,6 +21,8 @@ use Sabre\Uri;
*/
class HomeCollection extends AbstractPrincipalCollection implements IACL {
+ use ACLTrait;
+
/**
* Name of this collection.
*
@@ -70,20 +72,15 @@ class HomeCollection extends AbstractPrincipalCollection implements IACL {
* supplied by the authentication backend.
*
* @param array $principalInfo
- * @return void
+ * @return \Sabre\DAVACL\INode
*/
function getChildForPrincipal(array $principalInfo) {
$owner = $principalInfo['uri'];
$acl = [
[
- 'privilege' => '{DAV:}read',
- 'principal' => $owner,
- 'protected' => true,
- ],
- [
- 'privilege' => '{DAV:}write',
- 'principal' => $owner,
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
],
];
@@ -103,31 +100,6 @@ class HomeCollection extends AbstractPrincipalCollection implements IACL {
}
- /**
- * Returns the owner principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getOwner() {
-
- return null;
-
- }
-
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
/**
* Returns a list of ACE's for this node.
@@ -153,36 +125,4 @@ class HomeCollection extends AbstractPrincipalCollection implements IACL {
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's as an array argument.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new Forbidden('Setting ACL is not allowed here');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/DAVACL/IACL.php b/vendor/sabre/dav/lib/DAVACL/IACL.php
index 81908d08f..f7a138665 100644
--- a/vendor/sabre/dav/lib/DAVACL/IACL.php
+++ b/vendor/sabre/dav/lib/DAVACL/IACL.php
@@ -71,5 +71,4 @@ interface IACL extends DAV\INode {
*/
function getSupportedPrivilegeSet();
-
}
diff --git a/vendor/sabre/dav/lib/DAVACL/Plugin.php b/vendor/sabre/dav/lib/DAVACL/Plugin.php
index 601dffecc..8e912309e 100644
--- a/vendor/sabre/dav/lib/DAVACL/Plugin.php
+++ b/vendor/sabre/dav/lib/DAVACL/Plugin.php
@@ -4,7 +4,11 @@ namespace Sabre\DAVACL;
use Sabre\DAV;
use Sabre\DAV\INode;
+use Sabre\DAV\Xml\Property\Href;
use Sabre\DAV\Exception\BadRequest;
+use Sabre\DAV\Exception\NotFound;
+use Sabre\DAV\Exception\NotAuthenticated;
+use Sabre\DAVACL\Exception\NeedPrivileges;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
use Sabre\Uri;
@@ -64,18 +68,6 @@ class Plugin extends DAV\ServerPlugin {
];
/**
- * By default ACL is only enforced for nodes that have ACL support (the
- * ones that implement IACL). For any other node, access is
- * always granted.
- *
- * To override this behaviour you can turn this setting off. This is useful
- * if you plan to fully support ACL in the entire tree.
- *
- * @var bool
- */
- public $allowAccessToNodesWithoutACL = true;
-
- /**
* By default nodes that are inaccessible by the user, can still be seen
* in directory listings (PROPFIND on parent with Depth: 1)
*
@@ -109,6 +101,18 @@ class Plugin extends DAV\ServerPlugin {
public $adminPrincipals = [];
/**
+ * The ACL plugin allows privileges to be assigned to users that are not
+ * logged in. To facilitate that, it modifies the auth plugin's behavior
+ * to only require login when a privileged operation was denied.
+ *
+ * Unauthenticated access can be considered a security concern, so it's
+ * possible to turn this feature off to harden the server's security.
+ *
+ * @var bool
+ */
+ public $allowUnauthenticatedAccess = true;
+
+ /**
* Returns a list of features added by this plugin.
*
* This list is used in the response of a HTTP OPTIONS request.
@@ -161,6 +165,7 @@ class Plugin extends DAV\ServerPlugin {
return [
'{DAV:}expand-property',
+ '{DAV:}principal-match',
'{DAV:}principal-property-search',
'{DAV:}principal-search-property-set',
];
@@ -179,7 +184,8 @@ class Plugin extends DAV\ServerPlugin {
* @param array|string $privileges
* @param int $recursion
* @param bool $throwExceptions if set to false, this method won't throw exceptions.
- * @throws Sabre\DAVACL\Exception\NeedPrivileges
+ * @throws NeedPrivileges
+ * @throws NotAuthenticated
* @return bool
*/
function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
@@ -188,18 +194,6 @@ class Plugin extends DAV\ServerPlugin {
$acl = $this->getCurrentUserPrivilegeSet($uri);
- if (is_null($acl)) {
- if ($this->allowAccessToNodesWithoutACL) {
- return true;
- } else {
- if ($throwExceptions)
- throw new Exception\NeedPrivileges($uri, $privileges);
- else
- return false;
-
- }
- }
-
$failed = [];
foreach ($privileges as $priv) {
@@ -210,10 +204,22 @@ class Plugin extends DAV\ServerPlugin {
}
if ($failed) {
- if ($throwExceptions)
- throw new Exception\NeedPrivileges($uri, $failed);
- else
+ if ($this->allowUnauthenticatedAccess && is_null($this->getCurrentUserPrincipal())) {
+ // We are not authenticated. Kicking in the Auth plugin.
+ $authPlugin = $this->server->getPlugin('auth');
+ $reasons = $authPlugin->getLoginFailedReasons();
+ $authPlugin->challenge(
+ $this->server->httpRequest,
+ $this->server->httpResponse
+ );
+ throw new notAuthenticated(implode(', ', $reasons) . '. Login was needed for privilege: ' . implode(', ', $failed) . ' on ' . $uri);
+ }
+ if ($throwExceptions) {
+
+ throw new NeedPrivileges($uri, $failed);
+ } else {
return false;
+ }
}
return true;
@@ -229,10 +235,11 @@ class Plugin extends DAV\ServerPlugin {
*/
function getCurrentUserPrincipal() {
- $authPlugin = $this->server->getPlugin('auth');
- if (is_null($authPlugin)) return null;
/** @var $authPlugin Sabre\DAV\Auth\Plugin */
-
+ $authPlugin = $this->server->getPlugin('auth');
+ if (!$authPlugin) {
+ return null;
+ }
return $authPlugin->getCurrentPrincipal();
}
@@ -258,6 +265,51 @@ class Plugin extends DAV\ServerPlugin {
}
/**
+ * Sets the default ACL rules.
+ *
+ * These rules are used for all nodes that don't implement the IACL interface.
+ *
+ * @param array $acl
+ * @return void
+ */
+ function setDefaultAcl(array $acl) {
+
+ $this->defaultAcl = $acl;
+
+ }
+
+ /**
+ * Returns the default ACL rules.
+ *
+ * These rules are used for all nodes that don't implement the IACL interface.
+ *
+ * @param array $acl
+ * @return void
+ */
+ function getDefaultAcl() {
+
+ return $this->defaultAcl;
+
+ }
+
+ /**
+ * The default ACL rules.
+ *
+ * These rules are used for nodes that don't implement IACL. These default
+ * set of rules allow anyone to do anything, as long as they are
+ * authenticated.
+ *
+ * var array
+ */
+ protected $defaultAcl = [
+ [
+ 'principal' => '{DAV:}authenticated',
+ 'protected' => true,
+ 'privilege' => '{DAV:}all',
+ ],
+ ];
+
+ /**
* This array holds a cache for all the principals that are associated with
* a single principal.
*
@@ -311,13 +363,77 @@ class Plugin extends DAV\ServerPlugin {
}
/**
- * Returns the supported privilege structure for this ACL plugin.
+ * Find out of a principal equals another principal.
+ *
+ * This is a quick way to find out wether a principal URI is part of a
+ * group, or any subgroups.
*
- * See RFC3744 for more details. Currently we default on a simple,
- * standard structure.
+ * The first argument is the principal URI you want to check against. For
+ * example the principal group, and the second argument is the principal of
+ * which you want to find out of it is the same as the first principal, or
+ * in a member of the first principal's group or subgroups.
*
- * You can either get the list of privileges by a uri (path) or by
- * specifying a Node.
+ * So the arguments are not interchangable. If principal A is in group B,
+ * passing 'B', 'A' will yield true, but 'A', 'B' is false.
+ *
+ * If the sceond argument is not passed, we will use the current user
+ * principal.
+ *
+ * @param string $checkPrincipal
+ * @param string $currentPrincipal
+ * @return bool
+ */
+ function principalMatchesPrincipal($checkPrincipal, $currentPrincipal = null) {
+
+ if (is_null($currentPrincipal)) {
+ $currentPrincipal = $this->getCurrentUserPrincipal();
+ }
+ if ($currentPrincipal === $checkPrincipal) {
+ return true;
+ }
+ return in_array(
+ $checkPrincipal,
+ $this->getPrincipalMembership($currentPrincipal)
+ );
+
+ }
+
+
+ /**
+ * Returns a tree of supported privileges for a resource.
+ *
+ * The returned array structure should be in this form:
+ *
+ * [
+ * [
+ * 'privilege' => '{DAV:}read',
+ * 'abstract' => false,
+ * 'aggregates' => []
+ * ]
+ * ]
+ *
+ * Privileges can be nested using "aggregrates". Doing so means that
+ * if you assign someone the aggregrating privilege, all the
+ * sub-privileges will automatically be granted.
+ *
+ * Marking a privilege as abstract means that the privilege cannot be
+ * directly assigned, but must be assigned via the parent privilege.
+ *
+ * So a more complex version might look like this:
+ *
+ * [
+ * [
+ * 'privilege' => '{DAV:}read',
+ * 'abstract' => false,
+ * 'aggregates' => [
+ * [
+ * 'privilege' => '{DAV:}read-acl',
+ * 'abstract' => false,
+ * 'aggregates' => [],
+ * ]
+ * ]
+ * ]
+ * ]
*
* @param string|INode $node
* @return array
@@ -328,73 +444,71 @@ class Plugin extends DAV\ServerPlugin {
$node = $this->server->tree->getNodeForPath($node);
}
+ $supportedPrivileges = null;
if ($node instanceof IACL) {
- $result = $node->getSupportedPrivilegeSet();
-
- if ($result)
- return $result;
+ $supportedPrivileges = $node->getSupportedPrivilegeSet();
}
- return self::getDefaultSupportedPrivilegeSet();
+ if (is_null($supportedPrivileges)) {
- }
-
- /**
- * Returns a fairly standard set of privileges, which may be useful for
- * other systems to use as a basis.
- *
- * @return array
- */
- static function getDefaultSupportedPrivilegeSet() {
-
- return [
- 'privilege' => '{DAV:}all',
- 'abstract' => true,
- 'aggregates' => [
- [
- 'privilege' => '{DAV:}read',
+ // Default
+ $supportedPrivileges = [
+ '{DAV:}read' => [
+ 'abstract' => false,
'aggregates' => [
- [
- 'privilege' => '{DAV:}read-acl',
- 'abstract' => false,
+ '{DAV:}read-acl' => [
+ 'abstract' => false,
+ 'aggregates' => [],
],
- [
- 'privilege' => '{DAV:}read-current-user-privilege-set',
- 'abstract' => false,
+ '{DAV:}read-current-user-privilege-set' => [
+ 'abstract' => false,
+ 'aggregates' => [],
],
],
- ], // {DAV:}read
- [
- 'privilege' => '{DAV:}write',
+ ],
+ '{DAV:}write' => [
+ 'abstract' => false,
'aggregates' => [
- [
- 'privilege' => '{DAV:}write-acl',
- 'abstract' => false,
- ],
- [
- 'privilege' => '{DAV:}write-properties',
- 'abstract' => false,
- ],
- [
- 'privilege' => '{DAV:}write-content',
- 'abstract' => false,
+ '{DAV:}write-properties' => [
+ 'abstract' => false,
+ 'aggregates' => [],
],
- [
- 'privilege' => '{DAV:}bind',
- 'abstract' => false,
+ '{DAV:}write-content' => [
+ 'abstract' => false,
+ 'aggregates' => [],
],
- [
- 'privilege' => '{DAV:}unbind',
- 'abstract' => false,
- ],
- [
- 'privilege' => '{DAV:}unlock',
- 'abstract' => false,
+ '{DAV:}unlock' => [
+ 'abstract' => false,
+ 'aggregates' => [],
],
],
- ], // {DAV:}write
- ],
- ]; // {DAV:}all
+ ],
+ ];
+ if ($node instanceof \Sabre\DAV\ICollection) {
+ $supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}bind'] = [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ];
+ $supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}unbind'] = [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ];
+ }
+ if ($node instanceof \Sabre\DAVACL\IACL) {
+ $supportedPrivileges['{DAV:}write']['aggregates']['{DAV:}write-acl'] = [
+ 'abstract' => false,
+ 'aggregates' => [],
+ ];
+ }
+
+ }
+
+ $this->server->emit(
+ 'getSupportedPrivilegeSet',
+ [$node, &$supportedPrivileges]
+ );
+
+ return $supportedPrivileges;
}
@@ -414,35 +528,38 @@ class Plugin extends DAV\ServerPlugin {
*/
final function getFlatPrivilegeSet($node) {
- $privs = $this->getSupportedPrivilegeSet($node);
+ $privs = [
+ 'abstract' => false,
+ 'aggregates' => $this->getSupportedPrivilegeSet($node)
+ ];
$fpsTraverse = null;
- $fpsTraverse = function($priv, $concrete, &$flat) use (&$fpsTraverse) {
+ $fpsTraverse = function($privName, $privInfo, $concrete, &$flat) use (&$fpsTraverse) {
$myPriv = [
- 'privilege' => $priv['privilege'],
- 'abstract' => isset($priv['abstract']) && $priv['abstract'],
+ 'privilege' => $privName,
+ 'abstract' => isset($privInfo['abstract']) && $privInfo['abstract'],
'aggregates' => [],
- 'concrete' => isset($priv['abstract']) && $priv['abstract'] ? $concrete : $priv['privilege'],
+ 'concrete' => isset($privInfo['abstract']) && $privInfo['abstract'] ? $concrete : $privName,
];
- if (isset($priv['aggregates'])) {
+ if (isset($privInfo['aggregates'])) {
- foreach ($priv['aggregates'] as $subPriv) {
+ foreach ($privInfo['aggregates'] as $subPrivName => $subPrivInfo) {
- $myPriv['aggregates'][] = $subPriv['privilege'];
+ $myPriv['aggregates'][] = $subPrivName;
}
}
- $flat[$priv['privilege']] = $myPriv;
+ $flat[$privName] = $myPriv;
- if (isset($priv['aggregates'])) {
+ if (isset($privInfo['aggregates'])) {
- foreach ($priv['aggregates'] as $subPriv) {
+ foreach ($privInfo['aggregates'] as $subPrivName => $subPrivInfo) {
- $fpsTraverse($subPriv, $myPriv['concrete'], $flat);
+ $fpsTraverse($subPrivName, $subPrivInfo, $myPriv['concrete'], $flat);
}
@@ -451,7 +568,7 @@ class Plugin extends DAV\ServerPlugin {
};
$flat = [];
- $fpsTraverse($privs, null, $flat);
+ $fpsTraverse('{DAV:}all', $privs, null, $flat);
return $flat;
@@ -467,13 +584,13 @@ class Plugin extends DAV\ServerPlugin {
* @param string|DAV\INode $node
* @return array
*/
- function getACL($node) {
+ function getAcl($node) {
if (is_string($node)) {
$node = $this->server->tree->getNodeForPath($node);
}
if (!$node instanceof IACL) {
- return null;
+ return $this->getDefaultAcl();
}
$acl = $node->getACL();
foreach ($this->adminPrincipals as $adminPrincipal) {
@@ -506,12 +623,10 @@ class Plugin extends DAV\ServerPlugin {
$acl = $this->getACL($node);
- if (is_null($acl)) return null;
-
- $principals = $this->getCurrentUserPrincipals();
-
$collected = [];
+ $isAuthenticated = $this->getCurrentUserPrincipal() !== null;
+
foreach ($acl as $ace) {
$principal = $ace['principal'];
@@ -520,7 +635,7 @@ class Plugin extends DAV\ServerPlugin {
case '{DAV:}owner' :
$owner = $node->getOwner();
- if ($owner && in_array($owner, $principals)) {
+ if ($owner && $this->principalMatchesPrincipal($owner)) {
$collected[] = $ace;
}
break;
@@ -528,21 +643,25 @@ class Plugin extends DAV\ServerPlugin {
// 'all' matches for every user
case '{DAV:}all' :
+ $collected[] = $ace;
+ break;
- // 'authenticated' matched for every user that's logged in.
- // Since it's not possible to use ACL while not being logged
- // in, this is also always true.
case '{DAV:}authenticated' :
- $collected[] = $ace;
+ // Authenticated users only
+ if ($isAuthenticated) {
+ $collected[] = $ace;
+ }
break;
- // 'unauthenticated' can never occur either, so we simply
- // ignore these.
case '{DAV:}unauthenticated' :
+ // Unauthenticated users only
+ if (!$isAuthenticated) {
+ $collected[] = $ace;
+ }
break;
default :
- if (in_array($ace['principal'], $principals)) {
+ if ($this->principalMatchesPrincipal($ace['principal'])) {
$collected[] = $ace;
}
break;
@@ -561,6 +680,11 @@ class Plugin extends DAV\ServerPlugin {
$current = array_pop($collected);
$collected2[] = $current['privilege'];
+ if (!isset($flat[$current['privilege']])) {
+ // Ignoring privileges that are not in the supported-privileges list.
+ $this->server->getLogger()->debug('A node has the "' . $current['privilege'] . '" in its ACL list, but this privilege was not reported in the supportedPrivilegeSet list. This will be ignored.');
+ continue;
+ }
foreach ($flat[$current['privilege']]['aggregates'] as $subPriv) {
$collected2[] = $subPriv;
$collected[] = $flat[$subPriv];
@@ -587,7 +711,13 @@ class Plugin extends DAV\ServerPlugin {
$collections = $this->principalCollectionSet;
foreach ($collections as $collection) {
- $principalCollection = $this->server->tree->getNodeForPath($collection);
+ try {
+ $principalCollection = $this->server->tree->getNodeForPath($collection);
+ } catch (NotFound $e) {
+ // Ignore and move on
+ continue;
+ }
+
if (!$principalCollection instanceof IPrincipalCollection) {
// Not a principal collection, we're simply going to ignore
// this.
@@ -673,6 +803,14 @@ class Plugin extends DAV\ServerPlugin {
*/
function initialize(DAV\Server $server) {
+ if ($this->allowUnauthenticatedAccess) {
+ $authPlugin = $server->getPlugin('auth');
+ if (!$authPlugin) {
+ throw new \Exception('The Auth plugin must be loaded before the ACL plugin if you want to allow unauthenticated access.');
+ }
+ $authPlugin->autoRequireLogin = false;
+ }
+
$this->server = $server;
$server->on('propFind', [$this, 'propFind'], 20);
$server->on('beforeMethod', [$this, 'beforeMethod'], 20);
@@ -683,6 +821,14 @@ class Plugin extends DAV\ServerPlugin {
$server->on('report', [$this, 'report']);
$server->on('method:ACL', [$this, 'httpAcl']);
$server->on('onHTMLActionsPanel', [$this, 'htmlActionsPanel']);
+ $server->on('getPrincipalByUri', function($principal, &$uri) {
+
+ $uri = $this->getPrincipalByUri($principal);
+
+ // Break event chain
+ if ($uri) return false;
+
+ });
array_push($server->protectedProperties,
'{DAV:}alternate-URI-set',
@@ -707,9 +853,11 @@ class Plugin extends DAV\ServerPlugin {
// class.
$server->xml->elementMap['{DAV:}group-member-set'] = 'Sabre\\DAV\\Xml\\Property\\Href';
$server->xml->elementMap['{DAV:}acl'] = 'Sabre\\DAVACL\\Xml\\Property\\Acl';
+ $server->xml->elementMap['{DAV:}acl-principal-prop-set'] = 'Sabre\\DAVACL\\Xml\\Request\\AclPrincipalPropSetReport';
$server->xml->elementMap['{DAV:}expand-property'] = 'Sabre\\DAVACL\\Xml\\Request\\ExpandPropertyReport';
$server->xml->elementMap['{DAV:}principal-property-search'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalPropertySearchReport';
$server->xml->elementMap['{DAV:}principal-search-property-set'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalSearchPropertySetReport';
+ $server->xml->elementMap['{DAV:}principal-match'] = 'Sabre\\DAVACL\\Xml\\Request\\PrincipalMatchReport';
}
@@ -743,7 +891,6 @@ class Plugin extends DAV\ServerPlugin {
case 'PUT' :
case 'LOCK' :
- case 'UNLOCK' :
// This method requires the write-content priv if the node
// already exists, and bind on the parent if the node is being
// created.
@@ -751,6 +898,9 @@ class Plugin extends DAV\ServerPlugin {
$this->checkPrivileges($path, '{DAV:}write-content');
break;
+ case 'UNLOCK' :
+ // Unlock is always allowed at the moment.
+ break;
case 'PROPPATCH' :
$this->checkPrivileges($path, '{DAV:}write-properties');
@@ -774,7 +924,6 @@ class Plugin extends DAV\ServerPlugin {
// If MOVE is used beforeUnbind will also be used to check if
// the sourcenode can be deleted.
$this->checkPrivileges($path, '{DAV:}read', self::R_RECURSIVE);
-
break;
}
@@ -864,24 +1013,24 @@ class Plugin extends DAV\ServerPlugin {
if ($node instanceof IPrincipal) {
$propFind->handle('{DAV:}alternate-URI-set', function() use ($node) {
- return new DAV\Xml\Property\Href($node->getAlternateUriSet());
+ return new Href($node->getAlternateUriSet());
});
$propFind->handle('{DAV:}principal-URL', function() use ($node) {
- return new DAV\Xml\Property\Href($node->getPrincipalUrl() . '/');
+ return new Href($node->getPrincipalUrl() . '/');
});
$propFind->handle('{DAV:}group-member-set', function() use ($node) {
$members = $node->getGroupMemberSet();
foreach ($members as $k => $member) {
$members[$k] = rtrim($member, '/') . '/';
}
- return new DAV\Xml\Property\Href($members);
+ return new Href($members);
});
$propFind->handle('{DAV:}group-membership', function() use ($node) {
$members = $node->getGroupMembership();
foreach ($members as $k => $member) {
$members[$k] = rtrim($member, '/') . '/';
}
- return new DAV\Xml\Property\Href($members);
+ return new Href($members);
});
$propFind->handle('{DAV:}displayname', [$node, 'getDisplayName']);
@@ -892,7 +1041,7 @@ class Plugin extends DAV\ServerPlugin {
$val = $this->principalCollectionSet;
// Ensuring all collections end with a slash
foreach ($val as $k => $v) $val[$k] = $v . '/';
- return new DAV\Xml\Property\Href($val);
+ return new Href($val);
});
$propFind->handle('{DAV:}current-user-principal', function() {
@@ -910,9 +1059,7 @@ class Plugin extends DAV\ServerPlugin {
$propFind->set('{DAV:}current-user-privilege-set', null, 403);
} else {
$val = $this->getCurrentUserPrivilegeSet($node);
- if (!is_null($val)) {
- return new Xml\Property\CurrentUserPrivilegeSet($val);
- }
+ return new Xml\Property\CurrentUserPrivilegeSet($val);
}
});
$propFind->handle('{DAV:}acl', function() use ($node, $propFind, $path) {
@@ -921,9 +1068,7 @@ class Plugin extends DAV\ServerPlugin {
$propFind->set('{DAV:}acl', null, 403);
} else {
$acl = $this->getACL($node);
- if (!is_null($acl)) {
- return new Xml\Property\Acl($this->getACL($node));
- }
+ return new Xml\Property\Acl($this->getACL($node));
}
});
$propFind->handle('{DAV:}acl-restrictions', function() {
@@ -933,7 +1078,7 @@ class Plugin extends DAV\ServerPlugin {
/* Adding ACL properties */
if ($node instanceof IACL) {
$propFind->handle('{DAV:}owner', function() use ($node) {
- return new DAV\Xml\Property\Href($node->getOwner() . '/');
+ return new Href($node->getOwner() . '/');
});
}
@@ -952,7 +1097,7 @@ class Plugin extends DAV\ServerPlugin {
$propPatch->handle('{DAV:}group-member-set', function($value) use ($path) {
if (is_null($value)) {
$memberSet = [];
- } elseif ($value instanceof DAV\Xml\Property\Href) {
+ } elseif ($value instanceof Href) {
$memberSet = array_map(
[$this->server, 'calculateUri'],
$value->getHrefs()
@@ -990,15 +1135,23 @@ class Plugin extends DAV\ServerPlugin {
case '{DAV:}principal-property-search' :
$this->server->transactionType = 'report-principal-property-search';
- $this->principalPropertySearchReport($report);
+ $this->principalPropertySearchReport($path, $report);
return false;
case '{DAV:}principal-search-property-set' :
$this->server->transactionType = 'report-principal-search-property-set';
- $this->principalSearchPropertySetReport($report);
+ $this->principalSearchPropertySetReport($path, $report);
return false;
case '{DAV:}expand-property' :
$this->server->transactionType = 'report-expand-property';
- $this->expandPropertyReport($report);
+ $this->expandPropertyReport($path, $report);
+ return false;
+ case '{DAV:}principal-match' :
+ $this->server->transactionType = 'report-principal-match';
+ $this->principalMatchReport($path, $report);
+ return false;
+ case '{DAV:}acl-principal-prop-set' :
+ $this->server->transactionType = 'acl-principal-prop-set';
+ $this->aclPrincipalPropSetReport($path, $report);
return false;
}
@@ -1073,7 +1226,7 @@ class Plugin extends DAV\ServerPlugin {
// Looking up the principal
try {
$principal = $this->server->tree->getNodeForPath($newAce['principal']);
- } catch (DAV\Exception\NotFound $e) {
+ } catch (NotFound $e) {
throw new Exception\NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
}
if (!($principal instanceof IPrincipal)) {
@@ -1095,7 +1248,110 @@ class Plugin extends DAV\ServerPlugin {
/* Reports {{{ */
/**
- * The expand-property report is defined in RFC3253 section 3-8.
+ * The principal-match report is defined in RFC3744, section 9.3.
+ *
+ * This report allows a client to figure out based on the current user,
+ * or a principal URL, the principal URL and principal URLs of groups that
+ * principal belongs to.
+ *
+ * @param string $path
+ * @param Xml\Request\PrincipalMatchReport $report
+ * @return void
+ */
+ protected function principalMatchReport($path, Xml\Request\PrincipalMatchReport $report) {
+
+ $depth = $this->server->getHTTPDepth(0);
+ if ($depth !== 0) {
+ throw new BadRequest('The principal-match report is only defined on Depth: 0');
+ }
+
+ $currentPrincipals = $this->getCurrentUserPrincipals();
+
+ $result = [];
+
+ if ($report->type === Xml\Request\PrincipalMatchReport::SELF) {
+
+ // Finding all principals under the request uri that match the
+ // current principal.
+ foreach ($currentPrincipals as $currentPrincipal) {
+
+ if ($currentPrincipal === $path || strpos($currentPrincipal, $path . '/') === 0) {
+ $result[] = $currentPrincipal;
+ }
+
+ }
+
+ } else {
+
+ // We need to find all resources that have a property that matches
+ // one of the current principals.
+ $candidates = $this->server->getPropertiesForPath(
+ $path,
+ [$report->principalProperty],
+ 1
+ );
+
+ foreach ($candidates as $candidate) {
+
+ if (!isset($candidate[200][$report->principalProperty])) {
+ continue;
+ }
+
+ $hrefs = $candidate[200][$report->principalProperty];
+
+ if (!$hrefs instanceof Href) {
+ continue;
+ }
+
+ foreach ($hrefs->getHrefs() as $href) {
+ if (in_array(trim($href, '/'), $currentPrincipals)) {
+ $result[] = $candidate['href'];
+ continue 2;
+ }
+ }
+ }
+
+ }
+
+ $responses = [];
+
+ foreach ($result as $item) {
+
+ $properties = [];
+
+ if ($report->properties) {
+
+ $foo = $this->server->getPropertiesForPath($item, $report->properties);
+ $foo = $foo[0];
+ $item = $foo['href'];
+ unset($foo['href']);
+ $properties = $foo;
+
+ }
+
+ $responses[] = new DAV\Xml\Element\Response(
+ $item,
+ $properties,
+ '200'
+ );
+
+ }
+
+ $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
+ $this->server->httpResponse->setStatus(207);
+ $this->server->httpResponse->setBody(
+ $this->server->xml->write(
+ '{DAV:}multistatus',
+ $responses,
+ $this->server->getBaseUri()
+ )
+ );
+
+
+ }
+
+ /**
+ * The expand-property report is defined in RFC3253 section 3.8.
*
* This report is very similar to a standard PROPFIND. The difference is
* that it has the additional ability to look at properties containing a
@@ -1105,15 +1361,15 @@ class Plugin extends DAV\ServerPlugin {
* Other rfc's, such as ACL rely on this report, so it made sense to put
* it in this plugin.
*
+ * @param string $path
* @param Xml\Request\ExpandPropertyReport $report
* @return void
*/
- protected function expandPropertyReport($report) {
+ protected function expandPropertyReport($path, $report) {
$depth = $this->server->getHTTPDepth(0);
- $requestUri = $this->server->getRequestUri();
- $result = $this->expandProperties($requestUri, $report->properties, $depth);
+ $result = $this->expandProperties($path, $report->properties, $depth);
$xml = $this->server->xml->write(
'{DAV:}multistatus',
@@ -1187,10 +1443,11 @@ class Plugin extends DAV\ServerPlugin {
* of properties the client may search on, using the
* {DAV:}principal-property-search report.
*
+ * @param string $path
* @param Xml\Request\PrincipalSearchPropertySetReport $report
* @return void
*/
- protected function principalSearchPropertySetReport($report) {
+ protected function principalSearchPropertySetReport($path, $report) {
$httpDepth = $this->server->getHTTPDepth(0);
if ($httpDepth !== 0) {
@@ -1241,14 +1498,14 @@ class Plugin extends DAV\ServerPlugin {
* clients to search for groups of principals, based on the value of one
* or more properties.
*
+ * @param string $path
* @param Xml\Request\PrincipalPropertySearchReport $report
* @return void
*/
- protected function principalPropertySearchReport($report) {
+ protected function principalPropertySearchReport($path, Xml\Request\PrincipalPropertySearchReport $report) {
- $uri = null;
- if (!$report->applyToPrincipalCollectionSet) {
- $uri = $this->server->httpRequest->getPath();
+ if ($report->applyToPrincipalCollectionSet) {
+ $path = null;
}
if ($this->server->getHttpDepth('0') !== 0) {
throw new BadRequest('Depth must be 0');
@@ -1256,7 +1513,7 @@ class Plugin extends DAV\ServerPlugin {
$result = $this->principalSearch(
$report->searchProperties,
$report->properties,
- $uri,
+ $path,
$report->test
);
@@ -1269,6 +1526,64 @@ class Plugin extends DAV\ServerPlugin {
}
+ /**
+ * aclPrincipalPropSet REPORT
+ *
+ * This method is responsible for handling the {DAV:}acl-principal-prop-set
+ * REPORT, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc3744#section-9.2
+ *
+ * This REPORT allows a user to quickly fetch information about all
+ * principals specified in the access control list. Most commonly this
+ * is used to for example generate a UI with ACL rules, allowing you
+ * to show names for principals for every entry.
+ *
+ * @param string $path
+ * @param Xml\Request\AclPrincipalPropSetReport $report
+ * @return void
+ */
+ protected function aclPrincipalPropSetReport($path, Xml\Request\AclPrincipalPropSetReport $report) {
+
+ if ($this->server->getHTTPDepth(0) !== 0) {
+ throw new BadRequest('The {DAV:}acl-principal-prop-set REPORT only supports Depth 0');
+ }
+
+ // Fetching ACL rules for the given path. We're using the property
+ // API and not the local getACL, because it will ensure that all
+ // business rules and restrictions are applied.
+ $acl = $this->server->getProperties($path, '{DAV:}acl');
+
+ if (!$acl || !isset($acl['{DAV:}acl'])) {
+ throw new Forbidden('Could not fetch ACL rules for this path');
+ }
+
+ $principals = [];
+ foreach ($acl['{DAV:}acl']->getPrivileges() as $ace) {
+
+ if ($ace['principal'][0] === '{') {
+ // It's not a principal, it's one of the special rules such as {DAV:}authenticated
+ continue;
+ }
+
+ $principals[] = $ace['principal'];
+
+ }
+
+ $properties = $this->server->getPropertiesForMultiplePaths(
+ $principals,
+ $report->properties
+ );
+
+ $this->server->httpResponse->setStatus(207);
+ $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8');
+ $this->server->httpResponse->setBody(
+ $this->server->generateMultiStatus($properties)
+ );
+
+ }
+
+
/* }}} */
/**
diff --git a/vendor/sabre/dav/lib/DAVACL/Principal.php b/vendor/sabre/dav/lib/DAVACL/Principal.php
index 16375d3fc..6ebb30907 100644
--- a/vendor/sabre/dav/lib/DAVACL/Principal.php
+++ b/vendor/sabre/dav/lib/DAVACL/Principal.php
@@ -22,6 +22,8 @@ use Sabre\HTTP\URLUtil;
*/
class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL {
+ use ACLTrait;
+
/**
* Struct with principal information.
*
@@ -216,73 +218,4 @@ class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL {
}
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
-
- return null;
-
- }
-
- /**
- * Returns a list of ACE's for this node.
- *
- * Each ACE has the following properties:
- * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are
- * currently the only supported privileges
- * * 'principal', a url to the principal who owns the node
- * * 'protected' (optional), indicating that this ACE is not allowed to
- * be updated.
- *
- * @return array
- */
- function getACL() {
-
- return [
- [
- 'privilege' => '{DAV:}read',
- 'principal' => '{DAV:}authenticated',
- 'protected' => true,
- ],
- ];
-
- }
-
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new DAV\Exception\MethodNotAllowed('Updating ACLs is not allowed here');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php b/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php
index 01b7a175c..a491dc88f 100644
--- a/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php
+++ b/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php
@@ -300,7 +300,7 @@ class PDO extends AbstractBackend implements CreatePrincipalSupport {
$value = null;
$scheme = null;
list($scheme, $value) = explode(":", $uri, 2);
- if ($value == null) return null;
+ if (empty($value)) return null;
$uri = null;
switch ($scheme){
diff --git a/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php b/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php
index 54911e7b5..d8a90153a 100644
--- a/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php
+++ b/vendor/sabre/dav/lib/DAVACL/PrincipalCollection.php
@@ -3,7 +3,6 @@
namespace Sabre\DAVACL;
use Sabre\DAV\Exception\InvalidResourceType;
-use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\IExtendedCollection;
use Sabre\DAV\MkCol;
@@ -19,6 +18,8 @@ use Sabre\DAV\MkCol;
*/
class PrincipalCollection extends AbstractPrincipalCollection implements IExtendedCollection, IACL {
+ use ACLTrait;
+
/**
* This method returns a node for a principal.
*
@@ -73,28 +74,6 @@ class PrincipalCollection extends AbstractPrincipalCollection implements IExtend
}
/**
- * Returns the owner principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getOwner() {
- return null;
- }
-
- /**
- * Returns a group principal
- *
- * This must be a url to a principal, or null if there's no owner
- *
- * @return string|null
- */
- function getGroup() {
- return null;
- }
-
- /**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
@@ -116,36 +95,4 @@ class PrincipalCollection extends AbstractPrincipalCollection implements IExtend
];
}
- /**
- * Updates the ACL
- *
- * This method will receive a list of new ACE's as an array argument.
- *
- * @param array $acl
- * @return void
- */
- function setACL(array $acl) {
-
- throw new Forbidden('Updating ACLs is not allowed on this node');
-
- }
-
- /**
- * Returns the list of supported privileges for this node.
- *
- * The returned data structure is a list of nested privileges.
- * See Sabre\DAVACL\Plugin::getDefaultSupportedPrivilegeSet for a simple
- * standard structure.
- *
- * If null is returned from this method, the default privilege set is used,
- * which is fine for most common usecases.
- *
- * @return array|null
- */
- function getSupportedPrivilegeSet() {
-
- return null;
-
- }
-
}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php b/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
index 572bed4dd..55e7783ae 100644
--- a/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Property/SupportedPrivilegeSet.php
@@ -73,7 +73,7 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
*/
function xmlSerialize(Writer $writer) {
- $this->serializePriv($writer, $this->privileges);
+ $this->serializePriv($writer, '{DAV:}all', [ 'aggregates' => $this->privileges]);
}
@@ -93,9 +93,9 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
*/
function toHtml(HtmlOutputHelper $html) {
- $traverse = function($priv) use (&$traverse, $html) {
+ $traverse = function($privName, $priv) use (&$traverse, $html) {
echo "<li>";
- echo $html->xmlName($priv['privilege']);
+ echo $html->xmlName($privName);
if (isset($priv['abstract']) && $priv['abstract']) {
echo " <i>(abstract)</i>";
}
@@ -104,8 +104,8 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
}
if (isset($priv['aggregates'])) {
echo "\n<ul>\n";
- foreach ($priv['aggregates'] as $subPriv) {
- $traverse($subPriv);
+ foreach ($priv['aggregates'] as $subPrivName => $subPriv) {
+ $traverse($subPrivName, $subPriv);
}
echo "</ul>";
}
@@ -114,7 +114,7 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
ob_start();
echo "<ul class=\"tree\">";
- $traverse($this->getValue());
+ $traverse('{DAV:}all', [ 'aggregates' => $this->getValue() ]);
echo "</ul>\n";
return ob_get_clean();
@@ -132,12 +132,12 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
* @param array $privilege
* @return void
*/
- private function serializePriv(Writer $writer, $privilege) {
+ private function serializePriv(Writer $writer, $privName, $privilege) {
$writer->startElement('{DAV:}supported-privilege');
$writer->startElement('{DAV:}privilege');
- $writer->writeElement($privilege['privilege']);
+ $writer->writeElement($privName);
$writer->endElement(); // privilege
if (!empty($privilege['abstract'])) {
@@ -147,8 +147,8 @@ class SupportedPrivilegeSet implements XmlSerializable, HtmlOutput {
$writer->writeElement('{DAV:}description', $privilege['description']);
}
if (isset($privilege['aggregates'])) {
- foreach ($privilege['aggregates'] as $subPrivilege) {
- $this->serializePriv($writer, $subPrivilege);
+ foreach ($privilege['aggregates'] as $subPrivName => $subPrivilege) {
+ $this->serializePriv($writer, $subPrivName, $subPrivilege);
}
}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php b/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php
new file mode 100644
index 000000000..f01c1e6ab
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Request/AclPrincipalPropSetReport.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Request;
+
+use Sabre\Xml\XmlDeserializable;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Deserializer;
+
+/**
+ * AclPrincipalPropSet request parser.
+ *
+ * This class parses the {DAV:}acl-principal-prop-set REPORT, as defined in:
+ *
+ * https://tools.ietf.org/html/rfc3744#section-9.2
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (https://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class AclPrincipalPropSetReport implements XmlDeserializable {
+
+ public $properties = [];
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $reader->pushContext();
+ $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\enum';
+
+ $elems = Deserializer\keyValue(
+ $reader,
+ 'DAV:'
+ );
+
+ $reader->popContext();
+
+ $report = new self();
+
+ if (!empty($elems['prop'])) {
+ $report->properties = $elems['prop'];
+ }
+
+ return $report;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php b/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php
new file mode 100644
index 000000000..5c4e88189
--- /dev/null
+++ b/vendor/sabre/dav/lib/DAVACL/Xml/Request/PrincipalMatchReport.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace Sabre\DAVACL\Xml\Request;
+
+use Sabre\Xml\XmlDeserializable;
+use Sabre\Xml\Reader;
+use Sabre\Xml\Deserializer;
+
+/**
+ * PrincipalMatchReport request parser.
+ *
+ * This class parses the {DAV:}principal-match REPORT, as defined
+ * in:
+ *
+ * https://tools.ietf.org/html/rfc3744#section-9.3
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class PrincipalMatchReport implements XmlDeserializable {
+
+ /**
+ * Report on a list of principals that match the current principal.
+ */
+ const SELF = 1;
+
+ /**
+ * Report on a property on resources, such as {DAV:}owner, that match the current principal.
+ */
+ const PRINCIPAL_PROPERTY = 2;
+
+ /**
+ * Must be SELF or PRINCIPAL_PROPERTY
+ *
+ * @var int
+ */
+ public $type;
+
+ /**
+ * List of properties that are being requested for matching resources.
+ *
+ * @var string[]
+ */
+ public $properties = [];
+
+ /**
+ * If $type = PRINCIPAL_PROPERTY, which WebDAV property we should compare
+ * to the current principal.
+ *
+ * @var string
+ */
+ public $principalProperty;
+
+ /**
+ * The deserialize method is called during xml parsing.
+ *
+ * This method is called statictly, this is because in theory this method
+ * may be used as a type of constructor, or factory method.
+ *
+ * Often you want to return an instance of the current class, but you are
+ * free to return other data as well.
+ *
+ * You are responsible for advancing the reader to the next element. Not
+ * doing anything will result in a never-ending loop.
+ *
+ * If you just want to skip parsing for this element altogether, you can
+ * just call $reader->next();
+ *
+ * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
+ * the next element.
+ *
+ * @param Reader $reader
+ * @return mixed
+ */
+ static function xmlDeserialize(Reader $reader) {
+
+ $reader->pushContext();
+ $reader->elementMap['{DAV:}prop'] = 'Sabre\Xml\Deserializer\enum';
+
+ $elems = Deserializer\keyValue(
+ $reader,
+ 'DAV:'
+ );
+
+ $reader->popContext();
+
+ $principalMatch = new self();
+
+ if (array_key_exists('self', $elems)) {
+ $principalMatch->type = self::SELF;
+ }
+
+ if (array_key_exists('principal-property', $elems)) {
+ $principalMatch->type = self::PRINCIPAL_PROPERTY;
+ $principalMatch->principalProperty = $elems['principal-property'][0]['name'];
+ }
+
+ if (!empty($elems['prop'])) {
+ $principalMatch->properties = $elems['prop'];
+ }
+
+ return $principalMatch;
+
+ }
+
+}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
index 25f8b1794..2a00f7925 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/AbstractPDOTest.php
@@ -5,11 +5,30 @@ namespace Sabre\CalDAV\Backend;
use Sabre\CalDAV;
use Sabre\DAV;
use Sabre\DAV\PropPatch;
+use Sabre\DAV\Xml\Element\Sharee;
abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+ use DAV\DbTestHelperTrait;
+
protected $pdo;
+ function setUp() {
+
+ $this->dropTables([
+ 'calendarobjects',
+ 'calendars',
+ 'calendarinstances',
+ 'calendarchanges',
+ 'calendarsubscriptions',
+ 'schedulingobjects',
+ ]);
+ $this->createSchema('calendars');
+
+ $this->pdo = $this->getDb();
+
+ }
+
function testConstruct() {
$backend = new PDO($this->pdo);
@@ -42,11 +61,11 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$calendars = $backend->getCalendarsForUser('principals/user2');
$elementCheck = [
- 'id' => $returnedId,
'uri' => 'somerandomid',
'{DAV:}displayname' => 'Hello!',
'{urn:ietf:params:xml:ns:caldav}calendar-description' => '',
'{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
+ 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
];
$this->assertInternalType('array', $calendars);
@@ -110,6 +129,27 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
}
/**
+ * @depends testConstruct
+ * @expectedException \InvalidArgumentException
+ */
+ function testUpdateCalendarBadId() {
+
+ $backend = new PDO($this->pdo);
+
+ //Creating a new calendar
+ $newId = $backend->createCalendar('principals/user2', 'somerandomid', []);
+
+ $propPatch = new PropPatch([
+ '{DAV:}displayname' => 'myCalendar',
+ '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp('transparent'),
+ ]);
+
+ // Updating the calendar
+ $backend->updateCalendar('raaaa', $propPatch);
+
+ }
+
+ /**
* @depends testUpdateCalendarAndFetch
*/
function testUpdateCalendarUnknownProperty() {
@@ -156,6 +196,22 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
/**
* @depends testCreateCalendarAndFetch
+ * @expectedException \InvalidArgumentException
+ */
+ function testDeleteCalendarBadID() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', [
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VEVENT']),
+ '{DAV:}displayname' => 'Hello!',
+ ]);
+
+ $backend->deleteCalendar('bad-id');
+
+ }
+
+ /**
+ * @depends testCreateCalendarAndFetch
* @expectedException \Sabre\DAV\Exception
*/
function testCreateCalendarIncorrectComponentSet() {;
@@ -178,7 +234,13 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -186,7 +248,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => strtotime('20120101'),
'lastoccurence' => strtotime('20120101') + (3600 * 24),
'componenttype' => 'VEVENT',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
}
function testGetMultipleObjects() {
@@ -207,7 +269,6 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'size' => strlen($object),
'calendardata' => $object,
'lastmodified' => null,
- 'calendarid' => $returnedId,
],
[
'id' => 2,
@@ -216,7 +277,6 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'size' => strlen($object),
'calendardata' => $object,
'lastmodified' => null,
- 'calendarid' => $returnedId,
],
];
@@ -224,12 +284,22 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
foreach ($check as $index => $props) {
- foreach ($props as $key => $value) {
+ foreach ($props as $key => $expected) {
+
+ $actual = $result[$index][$key];
+
+ switch ($key) {
+ case 'lastmodified' :
+ $this->assertInternalType('int', $actual);
+ break;
+ case 'calendardata' :
+ if (is_resource($actual)) {
+ $actual = stream_get_contents($actual);
+ }
+ // no break intentional
+ default :
+ $this->assertEquals($expected, $actual);
- if ($key !== 'lastmodified') {
- $this->assertEquals($value, $result[$index][$key]);
- } else {
- $this->assertTrue(isset($result[$index][$key]));
}
}
@@ -239,6 +309,17 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
}
/**
+ * @depends testGetMultipleObjects
+ * @expectedException \InvalidArgumentException
+ */
+ function testGetMultipleObjectsBadId() {
+
+ $backend = new PDO($this->pdo);
+ $backend->getMultipleCalendarObjects('bad-id', ['foo-bar']);
+
+ }
+
+ /**
* @expectedException Sabre\DAV\Exception\BadRequest
* @depends testCreateCalendarObject
*/
@@ -265,7 +346,13 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -273,10 +360,26 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => strtotime('20120101'),
'lastoccurence' => strtotime('20120101') + (3600 * 48),
'componenttype' => 'VEVENT',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
+
+ }
+
+ /**
+ * @depends testCreateCalendarObject
+ * @expectedException \InvalidArgumentException
+ */
+ function testCreateCalendarObjectBadId() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nDURATION:P2D\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+
+ $backend->createCalendarObject('bad-id', 'random-id', $object);
}
+
/**
* @depends testCreateCalendarObject
*/
@@ -289,7 +392,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -297,7 +405,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => strtotime('2012-01-01 10:00:00'),
'lastoccurence' => strtotime('2012-01-01 10:00:00'),
'componenttype' => 'VEVENT',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
}
@@ -313,7 +421,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -321,7 +434,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => strtotime('2012-01-01 10:00:00'),
'lastoccurence' => strtotime('2012-01-01 11:00:00'),
'componenttype' => 'VEVENT',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
}
@@ -337,7 +450,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -345,7 +463,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => strtotime('2012-01-01 10:00:00'),
'lastoccurence' => strtotime(PDO::MAX_DATE),
'componenttype' => 'VEVENT',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
}
@@ -361,7 +479,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -369,7 +492,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => strtotime('2012-01-01 10:00:00'),
'lastoccurence' => strtotime('2012-01-01 11:00:00') + (3600 * 24 * 999),
'componenttype' => 'VEVENT',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
}
@@ -385,7 +508,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = "random-id"');
+ $result = $this->pdo->query('SELECT etag, size, calendardata, firstoccurence, lastoccurence, componenttype FROM calendarobjects WHERE uri = \'random-id\'');
+ $row = $result->fetch(\PDO::FETCH_ASSOC);
+ if (is_resource($row['calendardata'])) {
+ $row['calendardata'] = stream_get_contents($row['calendardata']);
+ }
+
$this->assertEquals([
'etag' => md5($object),
'size' => strlen($object),
@@ -393,7 +521,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'firstoccurence' => null,
'lastoccurence' => null,
'componenttype' => 'VTODO',
- ], $result->fetch(\PDO::FETCH_ASSOC));
+ ], $row);
}
@@ -408,17 +536,38 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
$backend->createCalendarObject($returnedId, 'random-id', $object);
- $data = $backend->getCalendarObjects($returnedId, 'random-id');
+ $data = $backend->getCalendarObjects($returnedId);
$this->assertEquals(1, count($data));
$data = $data[0];
- $this->assertEquals($returnedId, $data['calendarid']);
$this->assertEquals('random-id', $data['uri']);
$this->assertEquals(strlen($object), $data['size']);
+ }
+
+ /**
+ * @depends testGetCalendarObjects
+ * @expectedException \InvalidArgumentException
+ */
+ function testGetCalendarObjectsBadId() {
+
+ $backend = new PDO($this->pdo);
+ $backend->getCalendarObjects('bad-id');
}
+
+ /**
+ * @depends testGetCalendarObjects
+ * @expectedException \InvalidArgumentException
+ */
+ function testGetCalendarObjectBadId() {
+
+ $backend = new PDO($this->pdo);
+ $backend->getCalendarObject('bad-id', 'foo-bar');
+
+ }
+
/**
* @depends testCreateCalendarObject
*/
@@ -455,14 +604,28 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$data = $backend->getCalendarObject($returnedId, 'random-id');
+ if (is_resource($data['calendardata'])) {
+ $data['calendardata'] = stream_get_contents($data['calendardata']);
+ }
+
$this->assertEquals($object2, $data['calendardata']);
- $this->assertEquals($returnedId, $data['calendarid']);
$this->assertEquals('random-id', $data['uri']);
}
/**
+ * @depends testUpdateCalendarObject
+ * @expectedException \InvalidArgumentException
+ */
+ function testUpdateCalendarObjectBadId() {
+
+ $backend = new PDO($this->pdo);
+ $backend->updateCalendarObject('bad-id', 'object-id', 'objectdata');
+
+ }
+
+ /**
* @depends testCreateCalendarObject
*/
function testDeleteCalendarObject() {
@@ -479,6 +642,21 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
}
+ /**
+ * @depends testDeleteCalendarObject
+ * @expectedException \InvalidArgumentException
+ */
+ function testDeleteCalendarObjectBadId() {
+
+ $backend = new PDO($this->pdo);
+ $returnedId = $backend->createCalendar('principals/user2', 'somerandomid', []);
+
+ $object = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
+ $backend->createCalendarObject($returnedId, 'random-id', $object);
+ $backend->deleteCalendarObject('bad-id', 'random-id');
+
+ }
+
function testCalendarQueryNoResult() {
$abstract = new PDO($this->pdo);
@@ -499,15 +677,42 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
];
$this->assertEquals([
- ], $abstract->calendarQuery(1, $filters));
+ ], $abstract->calendarQuery([1, 1], $filters));
+
+ }
+
+ /**
+ * @expectedException \InvalidArgumentException
+ * @depends testCalendarQueryNoResult
+ */
+ function testCalendarQueryBadId() {
+
+ $abstract = new PDO($this->pdo);
+ $filters = [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [
+ [
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ],
+ ],
+ 'prop-filters' => [],
+ 'is-not-defined' => false,
+ 'time-range' => null,
+ ];
+
+ $abstract->calendarQuery('bad-id', $filters);
}
function testCalendarQueryTodo() {
$backend = new PDO($this->pdo);
- $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
@@ -527,14 +732,14 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals([
"todo",
- ], $backend->calendarQuery(1, $filters));
+ ], $backend->calendarQuery([1, 1], $filters));
}
function testCalendarQueryTodoNotMatch() {
$backend = new PDO($this->pdo);
- $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
@@ -561,15 +766,15 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
];
$this->assertEquals([
- ], $backend->calendarQuery(1, $filters));
+ ], $backend->calendarQuery([1, 1], $filters));
}
function testCalendarQueryNoFilter() {
$backend = new PDO($this->pdo);
- $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
@@ -579,7 +784,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
'time-range' => null,
];
- $result = $backend->calendarQuery(1, $filters);
+ $result = $backend->calendarQuery([1, 1], $filters);
$this->assertTrue(in_array('todo', $result));
$this->assertTrue(in_array('event', $result));
@@ -588,9 +793,9 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
function testCalendarQueryTimeRange() {
$backend = new PDO($this->pdo);
- $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART;VALUE=DATE:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
@@ -613,15 +818,15 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals([
"event2",
- ], $backend->calendarQuery(1, $filters));
+ ], $backend->calendarQuery([1, 1], $filters));
}
function testCalendarQueryTimeRangeNoEnd() {
$backend = new PDO($this->pdo);
- $backend->createCalendarObject(1, "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
- $backend->createCalendarObject(1, "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "todo", "BEGIN:VCALENDAR\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120101\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $backend->createCalendarObject([1, 1], "event2", "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nDTSTART:20120103\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$filters = [
'name' => 'VCALENDAR',
@@ -644,7 +849,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals([
"event2",
- ], $backend->calendarQuery(1, $filters));
+ ], $backend->calendarQuery([1, 1], $filters));
}
@@ -694,6 +899,22 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
], $result);
}
+ /**
+ * @depends testGetChanges
+ * @expectedException \InvalidArgumentException
+ */
+ function testGetChangesBadId() {
+
+ $backend = new PDO($this->pdo);
+ $id = $backend->createCalendar(
+ 'principals/user1',
+ 'bla',
+ []
+ );
+ $backend->getChangesForCalendar('bad-id', null, 1);
+
+ }
+
function testCreateSubscriptions() {
$props = [
@@ -862,6 +1083,9 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$result = $backend->getSchedulingObject('principals/user1', 'schedule1.ics');
foreach ($expected as $k => $v) {
$this->assertArrayHasKey($k, $result);
+ if (is_resource($result[$k])) {
+ $result[$k] = stream_get_contents($result[$k]);
+ }
$this->assertEquals($v, $result[$k]);
}
@@ -870,6 +1094,9 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals(1, count($results));
$result = $results[0];
foreach ($expected as $k => $v) {
+ if (is_resource($result[$k])) {
+ $result[$k] = stream_get_contents($result[$k]);
+ }
$this->assertEquals($v, $result[$k]);
}
@@ -880,4 +1107,325 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
}
+ function testGetInvites() {
+
+ $backend = new PDO($this->pdo);
+
+ // creating a new calendar
+ $backend->createCalendar('principals/user1', 'somerandomid', []);
+ $calendar = $backend->getCalendarsForUser('principals/user1')[0];
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ new Sharee([
+ 'href' => 'principals/user1',
+ 'principal' => 'principals/user1',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ])
+ ];
+
+ $this->assertEquals($expected, $result);
+
+ }
+
+ /**
+ * @depends testGetInvites
+ * @expectedException \InvalidArgumentException
+ */
+ function testGetInvitesBadId() {
+
+ $backend = new PDO($this->pdo);
+
+ // creating a new calendar
+ $backend->createCalendar('principals/user1', 'somerandomid', []);
+ $calendar = $backend->getCalendarsForUser('principals/user1')[0];
+
+ $backend->getInvites('bad-id');
+
+ }
+
+ /**
+ * @depends testCreateCalendarAndFetch
+ */
+ function testUpdateInvites() {
+
+ $backend = new PDO($this->pdo);
+
+ // creating a new calendar
+ $backend->createCalendar('principals/user1', 'somerandomid', []);
+ $calendar = $backend->getCalendarsForUser('principals/user1')[0];
+
+ $ownerSharee = new Sharee([
+ 'href' => 'principals/user1',
+ 'principal' => 'principals/user1',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ]);
+
+ // Add a new invite
+ $backend->updateInvites(
+ $calendar['id'],
+ [
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => 'principals/user2',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ 'properties' => ['{DAV:}displayname' => 'User 2'],
+ ])
+ ]
+ );
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ $ownerSharee,
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => 'principals/user2',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ 'properties' => [
+ '{DAV:}displayname' => 'User 2',
+ ],
+ ])
+ ];
+ $this->assertEquals($expected, $result);
+
+ // Checking calendar_instances too
+ $expectedCalendar = [
+ 'id' => [1,2],
+ 'principaluri' => 'principals/user2',
+ '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/1',
+ '{http://sabredav.org/ns}sync-token' => '1',
+ 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'read-only' => true,
+ 'share-resource-uri' => '/ns/share/1',
+ ];
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+
+ foreach ($expectedCalendar as $k => $v) {
+ $this->assertEquals(
+ $v,
+ $calendars[0][$k],
+ "Key " . $k . " in calendars array did not have the expected value."
+ );
+ }
+
+
+ // Updating an invite
+ $backend->updateInvites(
+ $calendar['id'],
+ [
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => 'principals/user2',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ])
+ ]
+ );
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ $ownerSharee,
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => 'principals/user2',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ 'properties' => [
+ '{DAV:}displayname' => 'User 2',
+ ],
+ ])
+ ];
+ $this->assertEquals($expected, $result);
+
+ // Removing an invite
+ $backend->updateInvites(
+ $calendar['id'],
+ [
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS,
+ ])
+ ]
+ );
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ $ownerSharee
+ ];
+ $this->assertEquals($expected, $result);
+
+ // Preventing the owner share from being removed
+ $backend->updateInvites(
+ $calendar['id'],
+ [
+ new Sharee([
+ 'href' => 'principals/user2',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS,
+ ])
+ ]
+ );
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ new Sharee([
+ 'href' => 'principals/user1',
+ 'principal' => 'principals/user1',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ]),
+ ];
+ $this->assertEquals($expected, $result);
+
+ }
+
+ /**
+ * @depends testUpdateInvites
+ * @expectedException \InvalidArgumentException
+ */
+ function testUpdateInvitesBadId() {
+
+ $backend = new PDO($this->pdo);
+ // Add a new invite
+ $backend->updateInvites(
+ 'bad-id',
+ []
+ );
+
+ }
+
+ /**
+ * @depends testUpdateInvites
+ */
+ function testUpdateInvitesNoPrincipal() {
+
+ $backend = new PDO($this->pdo);
+
+ // creating a new calendar
+ $backend->createCalendar('principals/user1', 'somerandomid', []);
+ $calendar = $backend->getCalendarsForUser('principals/user1')[0];
+
+ $ownerSharee = new Sharee([
+ 'href' => 'principals/user1',
+ 'principal' => 'principals/user1',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ]);
+
+ // Add a new invite
+ $backend->updateInvites(
+ $calendar['id'],
+ [
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => null,
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ 'properties' => ['{DAV:}displayname' => 'User 2'],
+ ])
+ ]
+ );
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ $ownerSharee,
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => null,
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_INVALID,
+ 'properties' => [
+ '{DAV:}displayname' => 'User 2',
+ ],
+ ])
+ ];
+ $this->assertEquals($expected, $result, null, 0.0, 10, true); // Last argument is $canonicalize = true, which allows us to compare, ignoring the order, because it's different between MySQL and Sqlite.
+
+ }
+
+ /**
+ * @depends testUpdateInvites
+ */
+ function testDeleteSharedCalendar() {
+
+ $backend = new PDO($this->pdo);
+
+ // creating a new calendar
+ $backend->createCalendar('principals/user1', 'somerandomid', []);
+ $calendar = $backend->getCalendarsForUser('principals/user1')[0];
+
+ $ownerSharee = new Sharee([
+ 'href' => 'principals/user1',
+ 'principal' => 'principals/user1',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ]);
+
+ // Add a new invite
+ $backend->updateInvites(
+ $calendar['id'],
+ [
+ new Sharee([
+ 'href' => 'mailto:user@example.org',
+ 'principal' => 'principals/user2',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ 'properties' => ['{DAV:}displayname' => 'User 2'],
+ ])
+ ]
+ );
+
+ $expectedCalendar = [
+ 'id' => [1,2],
+ 'principaluri' => 'principals/user2',
+ '{http://calendarserver.org/ns/}getctag' => 'http://sabre.io/ns/sync/1',
+ '{http://sabredav.org/ns}sync-token' => '1',
+ 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READ,
+ 'read-only' => true,
+ 'share-resource-uri' => '/ns/share/1',
+ ];
+ $calendars = $backend->getCalendarsForUser('principals/user2');
+
+ foreach ($expectedCalendar as $k => $v) {
+ $this->assertEquals(
+ $v,
+ $calendars[0][$k],
+ "Key " . $k . " in calendars array did not have the expected value."
+ );
+ }
+
+ // Removing the shared calendar.
+ $backend->deleteCalendar($calendars[0]['id']);
+
+ $this->assertEquals(
+ [],
+ $backend->getCalendarsForUser('principals/user2')
+ );
+
+ $result = $backend->getInvites($calendar['id']);
+ $expected = [
+ new Sharee([
+ 'href' => 'principals/user1',
+ 'principal' => 'principals/user1',
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED,
+ ]),
+ ];
+ $this->assertEquals($expected, $result);
+
+ }
+
+ /**
+ * @expectedException \Sabre\DAV\Exception\NotImplemented
+ */
+ function testSetPublishStatus() {
+
+ $backend = new PDO($this->pdo);
+ $backend->setPublishStatus([1, 1], true);
+
+ }
+
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
index 4412e5531..d4dcc07dc 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/Mock.php
@@ -82,6 +82,46 @@ class Mock extends AbstractBackend {
}
/**
+ * Updates properties for a calendar.
+ *
+ * The list of mutations is stored in a Sabre\DAV\PropPatch object.
+ * To do the actual updates, you must tell this object which properties
+ * you're going to process with the handle() method.
+ *
+ * Calling the handle method is like telling the PropPatch object "I
+ * promise I can handle updating this property".
+ *
+ * Read the PropPatch documentation for more info and examples.
+ *
+ * @param mixed $calendarId
+ * @param \Sabre\DAV\PropPatch $propPatch
+ * @return void
+ */
+ function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) {
+
+ $propPatch->handleRemaining(function($props) use ($calendarId) {
+
+ foreach ($this->calendars as $k => $calendar) {
+
+ if ($calendar['id'] === $calendarId) {
+ foreach ($props as $propName => $propValue) {
+ if (is_null($propValue)) {
+ unset($this->calendars[$k][$propName]);
+ } else {
+ $this->calendars[$k][$propName] = $propValue;
+ }
+ }
+ return true;
+
+ }
+
+ }
+
+ });
+
+ }
+
+ /**
* Delete a calendar and all it's objects
*
* @param string $calendarId
@@ -139,18 +179,22 @@ class Mock extends AbstractBackend {
* Returns information from a single calendar object, based on it's object
* uri.
*
+ * The object uri is only the basename, or filename and not a full path.
+ *
* The returned array must have the same keys as getCalendarObjects. The
* 'calendardata' object is required here though, while it's not required
* for getCalendarObjects.
*
- * @param string $calendarId
+ * This method must return null if the object did not exist.
+ *
+ * @param mixed $calendarId
* @param string $objectUri
- * @return array
+ * @return array|null
*/
function getCalendarObject($calendarId, $objectUri) {
if (!isset($this->calendarData[$calendarId][$objectUri])) {
- throw new DAV\Exception\NotFound('Object could not be found');
+ return null;
}
$object = $this->calendarData[$calendarId][$objectUri];
$object['calendarid'] = $calendarId;
@@ -207,8 +251,7 @@ class Mock extends AbstractBackend {
*/
function deleteCalendarObject($calendarId, $objectUri) {
- throw new Exception('Not implemented');
-
+ unset($this->calendarData[$calendarId][$objectUri]);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
index c215ca171..e068ff1e7 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOMySQLTest.php
@@ -2,38 +2,8 @@
namespace Sabre\CalDAV\Backend;
-require_once 'Sabre/TestUtil.php';
-require_once 'Sabre/CalDAV/TestUtil.php';
-require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
-
class PDOMySQLTest extends AbstractPDOTest {
- function setup() {
-
- if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
- $pdo = \Sabre\TestUtil::getMySQLDB();
- if (!$pdo) $this->markTestSkipped('Could not connect to mysql database');
-
- $pdo->query('DROP TABLE IF EXISTS calendarobjects, calendars, calendarchanges, calendarsubscriptions, schedulingobjects');
-
- $queries = explode(
- ';',
- file_get_contents(__DIR__ . '/../../../../examples/sql/mysql.calendars.sql')
- );
-
- foreach ($queries as $query) {
- $query = trim($query, " \r\n\t");
- if ($query)
- $pdo->exec($query);
- }
- $this->pdo = $pdo;
-
- }
-
- function teardown() {
-
- $this->pdo = null;
-
- }
+ public $driver = 'mysql';
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
index 4074259f2..90ad5a171 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Backend/PDOSqliteTest.php
@@ -2,36 +2,8 @@
namespace Sabre\CalDAV\Backend;
-use Sabre\CalDAV;
-
-require_once 'Sabre/CalDAV/Backend/AbstractPDOTest.php';
-
class PDOSqliteTest extends AbstractPDOTest {
- function setup() {
-
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
-
- if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite'))
- unlink(SABRE_TEMPDIR . '/testdb.sqlite');
-
- $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
-
- // Yup this is definitely not 'fool proof', but good enough for now.
- $queries = explode(';', file_get_contents(__DIR__ . '/../../../../examples/sql/sqlite.calendars.sql'));
- foreach ($queries as $query) {
- $pdo->exec($query);
- }
- $this->pdo = $pdo;
-
- }
-
- function teardown() {
-
- $this->pdo = null;
- unlink(SABRE_TEMPDIR . '/testdb.sqlite');
-
- }
+ public $driver = 'sqlite';
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
index 9fc1eee4c..0d98922ff 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarObjectTest.php
@@ -1,7 +1,6 @@
<?php
namespace Sabre\CalDAV;
-use Sabre\DAVACL;
require_once 'Sabre/CalDAV/TestUtil.php';
@@ -19,11 +18,10 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
function setup() {
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
$this->backend = TestUtil::getBackend();
$calendars = $this->backend->getCalendarsForUser('principals/user1');
- $this->assertEquals(2,count($calendars));
+ $this->assertEquals(2, count($calendars));
$this->calendar = new Calendar($this->backend, $calendars[0]);
}
@@ -40,10 +38,10 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
- $this->assertInternalType('string',$children[0]->getName());
- $this->assertInternalType('string',$children[0]->get());
- $this->assertInternalType('string',$children[0]->getETag());
- $this->assertEquals('text/calendar; charset=utf-8; component=vevent', $children[0]->getContentType());
+ $this->assertInternalType('string', $children[0]->getName());
+ $this->assertInternalType('string', $children[0]->get());
+ $this->assertInternalType('string', $children[0]->getETag());
+ $this->assertEquals('text/calendar; charset=utf-8', $children[0]->getContentType());
}
@@ -53,9 +51,9 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
function testInvalidArg1() {
$obj = new CalendarObject(
- new Backend\Mock(array(),array()),
- array(),
- array()
+ new Backend\Mock([], []),
+ [],
+ []
);
}
@@ -66,9 +64,9 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
function testInvalidArg2() {
$obj = new CalendarObject(
- new Backend\Mock(array(),array()),
- array(),
- array('calendarid' => '1')
+ new Backend\Mock([], []),
+ [],
+ ['calendarid' => '1']
);
}
@@ -96,7 +94,7 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
$this->assertTrue($children[0] instanceof CalendarObject);
$newData = TestUtil::getTestCalendarData();
- $stream = fopen('php://temp','r+');
+ $stream = fopen('php://temp', 'r+');
fwrite($stream, $newData);
rewind($stream);
$children[0]->put($stream);
@@ -117,7 +115,7 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
$obj->delete();
$children2 = $this->calendar->getChildren();
- $this->assertEquals(count($children)-1, count($children2));
+ $this->assertEquals(count($children) - 1, count($children2));
}
@@ -132,7 +130,7 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
$obj = $children[0];
$lastMod = $obj->getLastModified();
- $this->assertTrue(is_int($lastMod) || ctype_digit($lastMod));
+ $this->assertTrue(is_int($lastMod) || ctype_digit($lastMod) || is_null($lastMod));
}
@@ -173,33 +171,33 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
function testGetACL() {
- $expected = array(
- array(
+ $expected = [
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}write',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}write',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- );
+ ],
+ ];
$children = $this->calendar->getChildren();
$this->assertTrue($children[0] instanceof CalendarObject);
@@ -213,40 +211,30 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
$backend = new Backend\Mock([], []);
$calendarObject = new CalendarObject($backend, ['principaluri' => 'principals/user1'], ['calendarid' => 1, 'uri' => 'foo']);
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/user1',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
+ $expected = [
+ [
+ 'privilege' => '{DAV:}all',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
+ ],
+ [
+ 'privilege' => '{DAV:}all',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/user1/calendar-proxy-write',
- 'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
- ),
- );
+ ],
+ ];
$this->assertEquals($expected, $calendarObject->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
@@ -254,7 +242,7 @@ class CalendarObjectTest extends \PHPUnit_Framework_TestCase {
$this->assertTrue($children[0] instanceof CalendarObject);
$obj = $children[0];
- $obj->setACL(array());
+ $obj->setACL([]);
}
@@ -306,15 +294,15 @@ END:VCALENDAR";
function testGetRefetch() {
- $backend = new Backend\Mock(array(), array(
- 1 => array(
- 'foo' => array(
+ $backend = new Backend\Mock([], [
+ 1 => [
+ 'foo' => [
'calendardata' => 'foo',
- 'uri' => 'foo'
- ),
- )
- ));
- $obj = new CalendarObject($backend, array('id' => 1), array('uri' => 'foo'));
+ 'uri' => 'foo'
+ ],
+ ]
+ ]);
+ $obj = new CalendarObject($backend, ['id' => 1], ['uri' => 'foo']);
$this->assertEquals('foo', $obj->get());
@@ -322,15 +310,15 @@ END:VCALENDAR";
function testGetEtag1() {
- $objectInfo = array(
+ $objectInfo = [
'calendardata' => 'foo',
- 'uri' => 'foo',
- 'etag' => 'bar',
- 'calendarid' => 1
- );
+ 'uri' => 'foo',
+ 'etag' => 'bar',
+ 'calendarid' => 1
+ ];
- $backend = new Backend\Mock(array(), array());
- $obj = new CalendarObject($backend, array(), $objectInfo);
+ $backend = new Backend\Mock([], []);
+ $obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals('bar', $obj->getETag());
@@ -338,14 +326,14 @@ END:VCALENDAR";
function testGetEtag2() {
- $objectInfo = array(
+ $objectInfo = [
'calendardata' => 'foo',
- 'uri' => 'foo',
- 'calendarid' => 1
- );
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ ];
- $backend = new Backend\Mock(array(), array());
- $obj = new CalendarObject($backend, array(), $objectInfo);
+ $backend = new Backend\Mock([], []);
+ $obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals('"' . md5('foo') . '"', $obj->getETag());
@@ -353,42 +341,42 @@ END:VCALENDAR";
function testGetSupportedPrivilegesSet() {
- $objectInfo = array(
+ $objectInfo = [
'calendardata' => 'foo',
- 'uri' => 'foo',
- 'calendarid' => 1
- );
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ ];
- $backend = new Backend\Mock(array(), array());
- $obj = new CalendarObject($backend, array(), $objectInfo);
+ $backend = new Backend\Mock([], []);
+ $obj = new CalendarObject($backend, [], $objectInfo);
$this->assertNull($obj->getSupportedPrivilegeSet());
}
function testGetSize1() {
- $objectInfo = array(
+ $objectInfo = [
'calendardata' => 'foo',
- 'uri' => 'foo',
- 'calendarid' => 1
- );
+ 'uri' => 'foo',
+ 'calendarid' => 1
+ ];
- $backend = new Backend\Mock(array(), array());
- $obj = new CalendarObject($backend, array(), $objectInfo);
+ $backend = new Backend\Mock([], []);
+ $obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals(3, $obj->getSize());
}
function testGetSize2() {
- $objectInfo = array(
- 'uri' => 'foo',
+ $objectInfo = [
+ 'uri' => 'foo',
'calendarid' => 1,
- 'size' => 4,
- );
+ 'size' => 4,
+ ];
- $backend = new Backend\Mock(array(), array());
- $obj = new CalendarObject($backend, array(), $objectInfo);
+ $backend = new Backend\Mock([], []);
+ $obj = new CalendarObject($backend, [], $objectInfo);
$this->assertEquals(4, $obj->getSize());
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
index 9de24d3aa..ca06d8ffa 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
@@ -26,32 +26,32 @@ class CalendarQueryVAlarmTest extends \PHPUnit_Framework_TestCase {
$vcalendar->add($vevent);
- $filter = array(
- 'name' => 'VCALENDAR',
+ $filter = [
+ 'name' => 'VCALENDAR',
'is-not-defined' => false,
- 'time-range' => null,
- 'prop-filters' => array(),
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
+ 'time-range' => null,
+ 'prop-filters' => [],
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
'is-not-defined' => false,
- 'time-range' => null,
- 'prop-filters' => array(),
- 'comp-filters' => array(
- array(
- 'name' => 'VALARM',
+ 'time-range' => null,
+ 'prop-filters' => [],
+ 'comp-filters' => [
+ [
+ 'name' => 'VALARM',
'is-not-defined' => false,
- 'prop-filters' => array(),
- 'comp-filters' => array(),
- 'time-range' => array(
+ 'prop-filters' => [],
+ 'comp-filters' => [],
+ 'time-range' => [
'start' => new \DateTime('2012-05-10'),
- 'end' => new \DateTime('2012-05-20'),
- ),
- ),
- ),
- ),
- ),
- );
+ 'end' => new \DateTime('2012-05-20'),
+ ],
+ ],
+ ],
+ ],
+ ],
+ ];
$validator = new CalendarQueryValidator();
$this->assertTrue($validator->validate($vcalendar, $filter));
@@ -87,32 +87,32 @@ class CalendarQueryVAlarmTest extends \PHPUnit_Framework_TestCase {
$vcalendar->add($vevent);
- $filter = array(
- 'name' => 'VCALENDAR',
+ $filter = [
+ 'name' => 'VCALENDAR',
'is-not-defined' => false,
- 'time-range' => null,
- 'prop-filters' => array(),
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
+ 'time-range' => null,
+ 'prop-filters' => [],
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
'is-not-defined' => false,
- 'time-range' => null,
- 'prop-filters' => array(),
- 'comp-filters' => array(
- array(
- 'name' => 'VALARM',
+ 'time-range' => null,
+ 'prop-filters' => [],
+ 'comp-filters' => [
+ [
+ 'name' => 'VALARM',
'is-not-defined' => false,
- 'prop-filters' => array(),
- 'comp-filters' => array(),
- 'time-range' => array(
+ 'prop-filters' => [],
+ 'comp-filters' => [],
+ 'time-range' => [
'start' => new \DateTime('2011-12-10'),
- 'end' => new \DateTime('2011-12-20'),
- ),
- ),
- ),
- ),
- ),
- );
+ 'end' => new \DateTime('2011-12-20'),
+ ],
+ ],
+ ],
+ ],
+ ],
+ ];
$validator = new CalendarQueryValidator();
$this->assertTrue($validator->validate($vcalendar, $filter));
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
index 9822e82e2..4c2558a9b 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
@@ -1,8 +1,8 @@
<?php
namespace Sabre\CalDAV;
+
use Sabre\VObject;
-use Sabre\DAV;
class CalendarQueryValidatorTest extends \PHPUnit_Framework_TestCase {
@@ -29,17 +29,17 @@ ICS;
// Wrapping filter in a VCALENDAR component filter, as this is always
// there anyway.
- $filters = array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array($filters),
- 'prop-filters' => array(),
+ $filters = [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [$filters],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
$vObject = VObject\Reader::read($icalObject);
- switch($outcome) {
+ switch ($outcome) {
case 0 :
$this->assertFalse($validator->validate($vObject, $filters));
break;
@@ -392,13 +392,13 @@ END:VEVENT
END:VCALENDAR
yow;
- $filter1 = array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filter1 = [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
$filter2 = $filter1;
$filter2['name'] = 'VTODO';
@@ -410,25 +410,25 @@ yow;
$filter4['is-not-defined'] = true;
$filter5 = $filter1;
- $filter5['comp-filters'] = array(
- array(
- 'name' => 'VALARM',
+ $filter5['comp-filters'] = [
+ [
+ 'name' => 'VALARM',
'is-not-defined' => false,
- 'comp-filters' => array(),
- 'prop-filters' => array(),
- 'time-range' => null,
- ),
- );
+ 'comp-filters' => [],
+ 'prop-filters' => [],
+ 'time-range' => null,
+ ],
+ ];
$filter6 = $filter1;
- $filter6['prop-filters'] = array(
- array(
- 'name' => 'SUMMARY',
+ $filter6['prop-filters'] = [
+ [
+ 'name' => 'SUMMARY',
'is-not-defined' => false,
- 'param-filters' => array(),
- 'time-range' => null,
- 'text-match' => null,
- ),
- );
+ 'param-filters' => [],
+ 'time-range' => null,
+ 'text-match' => null,
+ ],
+ ];
$filter7 = $filter6;
$filter7['prop-filters'][0]['name'] = 'DESCRIPTION';
@@ -443,21 +443,21 @@ yow;
// Param filters
$filter11 = $filter1;
- $filter11['prop-filters'] = array(
- array(
- 'name' => 'DTSTART',
+ $filter11['prop-filters'] = [
+ [
+ 'name' => 'DTSTART',
'is-not-defined' => false,
- 'param-filters' => array(
- array(
- 'name' => 'VALUE',
+ 'param-filters' => [
+ [
+ 'name' => 'VALUE',
'is-not-defined' => false,
- 'text-match' => null,
- ),
- ),
+ 'text-match' => null,
+ ],
+ ],
'time-range' => null,
'text-match' => null,
- ),
- );
+ ],
+ ];
$filter12 = $filter11;
$filter12['prop-filters'][0]['param-filters'][0]['name'] = 'TZID';
@@ -470,11 +470,11 @@ yow;
// Param text filter
$filter15 = $filter11;
- $filter15['prop-filters'][0]['param-filters'][0]['text-match'] = array(
- 'collation' => 'i;ascii-casemap',
- 'value' => 'dAtE',
+ $filter15['prop-filters'][0]['param-filters'][0]['text-match'] = [
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'dAtE',
'negate-condition' => false,
- );
+ ];
$filter16 = $filter15;
$filter16['prop-filters'][0]['param-filters'][0]['text-match']['collation'] = 'i;octet';
@@ -487,31 +487,31 @@ yow;
// prop + text
$filter19 = $filter5;
- $filter19['comp-filters'][0]['prop-filters'] = array(
- array(
- 'name' => 'action',
+ $filter19['comp-filters'][0]['prop-filters'] = [
+ [
+ 'name' => 'action',
'is-not-defined' => false,
- 'time-range' => null,
- 'param-filters' => array(),
- 'text-match' => array(
- 'collation' => 'i;ascii-casemap',
- 'value' => 'display',
+ 'time-range' => null,
+ 'param-filters' => [],
+ 'text-match' => [
+ 'collation' => 'i;ascii-casemap',
+ 'value' => 'display',
'negate-condition' => false,
- ),
- ),
- );
+ ],
+ ],
+ ];
// Time range
- $filter20 = array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filter20 = [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
- ),
- );
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ],
+ ];
// Time range, no end date
$filter21 = $filter20;
$filter21['time-range']['end'] = null;
@@ -522,105 +522,105 @@ yow;
// Time range, other dates
$filter23 = $filter20;
- $filter23['time-range'] = array(
+ $filter23['time-range'] = [
'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
- );
+ 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
+ ];
// Time range
- $filter24 = array(
- 'name' => 'VTODO',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filter24 = [
+ 'name' => 'VTODO',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
- ),
- );
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ],
+ ];
// Time range, other dates (1 month in the future)
$filter25 = $filter24;
- $filter25['time-range'] = array(
+ $filter25['time-range'] = [
'start' => new \DateTime('2011-02-01 10:00:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
- );
+ 'end' => new \DateTime('2011-02-01 13:00:00', new \DateTimeZone('GMT')),
+ ];
$filter26 = $filter24;
- $filter26['time-range'] = array(
+ $filter26['time-range'] = [
'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
- );
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ ];
// Time range for VJOURNAL
- $filter27 = array(
- 'name' => 'VJOURNAL',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filter27 = [
+ 'name' => 'VJOURNAL',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
- ),
- );
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ],
+ ];
$filter28 = $filter27;
- $filter28['time-range'] = array(
+ $filter28['time-range'] = [
'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
- );
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ ];
// Time range for VFREEBUSY
- $filter29 = array(
- 'name' => 'VFREEBUSY',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filter29 = [
+ 'name' => 'VFREEBUSY',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 12:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
- ),
- );
+ 'end' => new \DateTime('2011-01-01 13:15:00', new \DateTimeZone('GMT')),
+ ],
+ ];
// Time range filter on property
- $filter30 = array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(
- array(
- 'name' => 'DTSTART',
+ $filter30 = [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [
+ [
+ 'name' => 'DTSTART',
'is-not-defined' => false,
- 'param-filters' => array(),
- 'time-range' => array(
+ 'param-filters' => [],
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
- ),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ],
'text-match' => null,
- ),
- ),
+ ],
+ ],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
// Time range for alarm
- $filter31 = array(
- 'name' => 'VEVENT',
- 'prop-filters' => array(),
- 'comp-filters' => array(
- array(
- 'name' => 'VALARM',
+ $filter31 = [
+ 'name' => 'VEVENT',
+ 'prop-filters' => [],
+ 'comp-filters' => [
+ [
+ 'name' => 'VALARM',
'is-not-defined' => false,
- 'comp-filters' => array(),
- 'prop-filters' => array(),
- 'time-range' => array(
+ 'comp-filters' => [],
+ 'prop-filters' => [],
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 10:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 11:15:00', new \DateTimeZone('GMT')),
- ),
+ 'end' => new \DateTime('2011-01-01 11:15:00', new \DateTimeZone('GMT')),
+ ],
'text-match' => null,
- ),
- ),
+ ],
+ ],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
$filter32 = $filter31;
- $filter32['comp-filters'][0]['time-range'] = array(
+ $filter32['comp-filters'][0]['time-range'] = [
'start' => new \DateTime('2011-01-01 11:45:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
- );
+ 'end' => new \DateTime('2011-01-01 12:15:00', new \DateTimeZone('GMT')),
+ ];
$filter33 = $filter31;
$filter33['name'] = 'VTODO';
@@ -632,194 +632,194 @@ yow;
$filter36['name'] = 'VJOURNAL';
// Time range filter on non-datetime property
- $filter37 = array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(
- array(
- 'name' => 'SUMMARY',
+ $filter37 = [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [
+ [
+ 'name' => 'SUMMARY',
'is-not-defined' => false,
- 'param-filters' => array(),
- 'time-range' => array(
+ 'param-filters' => [],
+ 'time-range' => [
'start' => new \DateTime('2011-01-01 10:00:00', new \DateTimeZone('GMT')),
- 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
- ),
+ 'end' => new \DateTime('2011-01-01 13:00:00', new \DateTimeZone('GMT')),
+ ],
'text-match' => null,
- ),
- ),
+ ],
+ ],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
- $filter38 = array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filter38 = [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2012-07-01 00:00:00', new \DateTimeZone('UTC')),
- 'end' => new \DateTime('2012-08-01 00:00:00', new \DateTimeZone('UTC')),
- )
- );
- $filter39 = array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(
- array(
- 'name' => 'VALARM',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ 'end' => new \DateTime('2012-08-01 00:00:00', new \DateTimeZone('UTC')),
+ ]
+ ];
+ $filter39 = [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [
+ [
+ 'name' => 'VALARM',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2012-09-01 00:00:00', new \DateTimeZone('UTC')),
- 'end' => new \DateTime('2012-10-01 00:00:00', new \DateTimeZone('UTC')),
- )
- ),
- ),
- 'prop-filters' => array(),
+ 'end' => new \DateTime('2012-10-01 00:00:00', new \DateTimeZone('UTC')),
+ ]
+ ],
+ ],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
- return array(
+ return [
// Component check
- array($blob1, $filter1, 1),
- array($blob1, $filter2, 0),
- array($blob1, $filter3, 0),
- array($blob1, $filter4, 1),
+ [$blob1, $filter1, 1],
+ [$blob1, $filter2, 0],
+ [$blob1, $filter3, 0],
+ [$blob1, $filter4, 1],
// Subcomponent check (4)
- array($blob1, $filter5, 0),
- array($blob2, $filter5, 1),
+ [$blob1, $filter5, 0],
+ [$blob2, $filter5, 1],
// Property checki (6)
- array($blob1, $filter6, 1),
- array($blob1, $filter7, 0),
- array($blob1, $filter8, 0),
- array($blob1, $filter9, 1),
+ [$blob1, $filter6, 1],
+ [$blob1, $filter7, 0],
+ [$blob1, $filter8, 0],
+ [$blob1, $filter9, 1],
// Subcomponent + property (10)
- array($blob2, $filter10, 1),
+ [$blob2, $filter10, 1],
// Param filter (11)
- array($blob3, $filter11, 1),
- array($blob3, $filter12, 0),
- array($blob3, $filter13, 0),
- array($blob3, $filter14, 1),
+ [$blob3, $filter11, 1],
+ [$blob3, $filter12, 0],
+ [$blob3, $filter13, 0],
+ [$blob3, $filter14, 1],
// Param + text (15)
- array($blob3, $filter15, 1),
- array($blob3, $filter16, 0),
- array($blob3, $filter17, 0),
- array($blob3, $filter18, 1),
+ [$blob3, $filter15, 1],
+ [$blob3, $filter16, 0],
+ [$blob3, $filter17, 0],
+ [$blob3, $filter18, 1],
// Prop + text (19)
- array($blob2, $filter19, 1),
+ [$blob2, $filter19, 1],
// Incorrect object (vcard) (20)
- array($blob4, $filter1, -1),
+ [$blob4, $filter1, -1],
// Time-range for event (21)
- array($blob5, $filter20, 1),
- array($blob6, $filter20, 1),
- array($blob7, $filter20, 1),
- array($blob8, $filter20, 1),
+ [$blob5, $filter20, 1],
+ [$blob6, $filter20, 1],
+ [$blob7, $filter20, 1],
+ [$blob8, $filter20, 1],
- array($blob5, $filter21, 1),
- array($blob5, $filter22, 1),
+ [$blob5, $filter21, 1],
+ [$blob5, $filter22, 1],
- array($blob5, $filter23, 0),
- array($blob6, $filter23, 0),
- array($blob7, $filter23, 0),
- array($blob8, $filter23, 0),
+ [$blob5, $filter23, 0],
+ [$blob6, $filter23, 0],
+ [$blob7, $filter23, 0],
+ [$blob8, $filter23, 0],
// Time-range for todo (31)
- array($blob9, $filter24, 1),
- array($blob9, $filter25, 0),
- array($blob9, $filter26, 1),
- array($blob10, $filter24, 1),
- array($blob10, $filter25, 0),
- array($blob10, $filter26, 1),
+ [$blob9, $filter24, 1],
+ [$blob9, $filter25, 0],
+ [$blob9, $filter26, 1],
+ [$blob10, $filter24, 1],
+ [$blob10, $filter25, 0],
+ [$blob10, $filter26, 1],
- array($blob11, $filter24, 0),
- array($blob11, $filter25, 0),
- array($blob11, $filter26, 1),
+ [$blob11, $filter24, 0],
+ [$blob11, $filter25, 0],
+ [$blob11, $filter26, 1],
- array($blob12, $filter24, 1),
- array($blob12, $filter25, 0),
- array($blob12, $filter26, 0),
+ [$blob12, $filter24, 1],
+ [$blob12, $filter25, 0],
+ [$blob12, $filter26, 0],
- array($blob13, $filter24, 1),
- array($blob13, $filter25, 0),
- array($blob13, $filter26, 1),
+ [$blob13, $filter24, 1],
+ [$blob13, $filter25, 0],
+ [$blob13, $filter26, 1],
- array($blob14, $filter24, 1),
- array($blob14, $filter25, 0),
- array($blob14, $filter26, 0),
+ [$blob14, $filter24, 1],
+ [$blob14, $filter25, 0],
+ [$blob14, $filter26, 0],
- array($blob15, $filter24, 1),
- array($blob15, $filter25, 1),
- array($blob15, $filter26, 1),
+ [$blob15, $filter24, 1],
+ [$blob15, $filter25, 1],
+ [$blob15, $filter26, 1],
- array($blob16, $filter24, 1),
- array($blob16, $filter25, 1),
- array($blob16, $filter26, 1),
+ [$blob16, $filter24, 1],
+ [$blob16, $filter25, 1],
+ [$blob16, $filter26, 1],
// Time-range for journals (55)
- array($blob17, $filter27, 0),
- array($blob17, $filter28, 0),
- array($blob18, $filter27, 0),
- array($blob18, $filter28, 1),
- array($blob19, $filter27, 1),
- array($blob19, $filter28, 1),
+ [$blob17, $filter27, 0],
+ [$blob17, $filter28, 0],
+ [$blob18, $filter27, 0],
+ [$blob18, $filter28, 1],
+ [$blob19, $filter27, 1],
+ [$blob19, $filter28, 1],
// Time-range for free-busy (61)
- array($blob20, $filter29, -1),
+ [$blob20, $filter29, -1],
// Time-range on property (62)
- array($blob5, $filter30, 1),
- array($blob3, $filter37, -1),
- array($blob3, $filter30, 0),
+ [$blob5, $filter30, 1],
+ [$blob3, $filter37, -1],
+ [$blob3, $filter30, 0],
// Time-range on alarm in vevent (65)
- array($blob21, $filter31, 1),
- array($blob21, $filter32, 0),
- array($blob22, $filter31, 1),
- array($blob22, $filter32, 0),
- array($blob23, $filter31, 1),
- array($blob23, $filter32, 0),
- array($blob24, $filter31, 1),
- array($blob24, $filter32, 0),
- array($blob25, $filter31, 1),
- array($blob25, $filter32, 0),
- array($blob26, $filter31, 1),
- array($blob26, $filter32, 0),
+ [$blob21, $filter31, 1],
+ [$blob21, $filter32, 0],
+ [$blob22, $filter31, 1],
+ [$blob22, $filter32, 0],
+ [$blob23, $filter31, 1],
+ [$blob23, $filter32, 0],
+ [$blob24, $filter31, 1],
+ [$blob24, $filter32, 0],
+ [$blob25, $filter31, 1],
+ [$blob25, $filter32, 0],
+ [$blob26, $filter31, 1],
+ [$blob26, $filter32, 0],
// Time-range on alarm for vtodo (77)
- array($blob27, $filter33, 1),
- array($blob27, $filter34, 0),
+ [$blob27, $filter33, 1],
+ [$blob27, $filter34, 0],
// Time-range on alarm for vjournal (79)
- array($blob28, $filter35, -1),
- array($blob28, $filter36, -1),
+ [$blob28, $filter35, -1],
+ [$blob28, $filter36, -1],
// Time-range on alarm with duration (81)
- array($blob29, $filter31, 1),
- array($blob29, $filter32, 0),
- array($blob30, $filter31, 0),
- array($blob30, $filter32, 0),
+ [$blob29, $filter31, 1],
+ [$blob29, $filter32, 0],
+ [$blob30, $filter31, 0],
+ [$blob30, $filter32, 0],
// Time-range with RRULE (85)
- array($blob31, $filter20, 1),
- array($blob32, $filter20, 0),
+ [$blob31, $filter20, 1],
+ [$blob32, $filter20, 0],
// Bug reported on mailing list, related to all-day events (87)
//array($blob33, $filter38, 1),
// Event in timerange, but filtered alarm is in the far future (88).
- array($blob34, $filter39, 0),
- );
+ [$blob34, $filter39, 0],
+ ];
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
index ea744d2cf..df85b6ded 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/CalendarTest.php
@@ -3,7 +3,6 @@
namespace Sabre\CalDAV;
use Sabre\DAV\PropPatch;
-use Sabre\DAVACL;
require_once 'Sabre/CalDAV/TestUtil.php';
@@ -25,8 +24,6 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
function setup() {
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
-
$this->backend = TestUtil::getBackend();
$this->calendars = $this->backend->getCalendarsForUser('principals/user1');
@@ -63,7 +60,7 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals(true, $result);
$calendars2 = $this->backend->getCalendarsForUser('principals/user1');
- $this->assertEquals('NewName',$calendars2[0]['{DAV:}displayname']);
+ $this->assertEquals('NewName', $calendars2[0]['{DAV:}displayname']);
}
@@ -72,15 +69,15 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
*/
function testGetProperties() {
- $question = array(
+ $question = [
'{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set',
- );
+ ];
$result = $this->calendar->getProperties($question);
- foreach($question as $q) $this->assertArrayHasKey($q,$result);
+ foreach ($question as $q) $this->assertArrayHasKey($q, $result);
- $this->assertEquals(array('VEVENT','VTODO'), $result['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue());
+ $this->assertEquals(['VEVENT', 'VTODO'], $result['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue());
}
@@ -100,7 +97,7 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
function testGetChildren() {
$children = $this->calendar->getChildren();
- $this->assertEquals(1,count($children));
+ $this->assertEquals(1, count($children));
$this->assertTrue($children[0] instanceof CalendarObject);
@@ -145,11 +142,11 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
function testCreateFile() {
- $file = fopen('php://memory','r+');
- fwrite($file,TestUtil::getTestCalendarData());
+ $file = fopen('php://memory', 'r+');
+ fwrite($file, TestUtil::getTestCalendarData());
rewind($file);
- $this->calendar->createFile('hello',$file);
+ $this->calendar->createFile('hello', $file);
$file = $this->calendar->getChild('hello');
$this->assertTrue($file instanceof CalendarObject);
@@ -158,12 +155,12 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
function testCreateFileNoSupportedComponents() {
- $file = fopen('php://memory','r+');
- fwrite($file,TestUtil::getTestCalendarData());
+ $file = fopen('php://memory', 'r+');
+ fwrite($file, TestUtil::getTestCalendarData());
rewind($file);
$calendar = new Calendar($this->backend, $this->calendars[1]);
- $calendar->createFile('hello',$file);
+ $calendar->createFile('hello', $file);
$file = $calendar->getChild('hello');
$this->assertTrue($file instanceof CalendarObject);
@@ -180,7 +177,7 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
function testGetOwner() {
- $this->assertEquals('principals/user1',$this->calendar->getOwner());
+ $this->assertEquals('principals/user1', $this->calendar->getOwner());
}
@@ -192,98 +189,68 @@ class CalendarTest extends \PHPUnit_Framework_TestCase {
function testGetACL() {
- $expected = array(
- array(
+ $expected = [
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
'principal' => '{DAV:}authenticated',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}write',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}write',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- );
+ ],
+ ];
$this->assertEquals($expected, $this->calendar->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
- $this->calendar->setACL(array());
-
- }
-
- function testGetSupportedPrivilegesSet() {
-
- $result = $this->calendar->getSupportedPrivilegeSet();
-
- $this->assertEquals(
- '{' . Plugin::NS_CALDAV . '}read-free-busy',
- $result['aggregates'][0]['aggregates'][2]['privilege']
- );
+ $this->calendar->setACL([]);
}
function testGetSyncToken() {
- $this->assertEquals(2, $this->calendar->getSyncToken());
-
- }
- function testGetSyncToken2() {
-
- $calendar = new Calendar(new Backend\Mock([],[]), [
- '{DAV:}sync-token' => 2
- ]);
- $this->assertEquals(2, $this->calendar->getSyncToken());
+ $this->assertNull($this->calendar->getSyncToken());
}
function testGetSyncTokenNoSyncSupport() {
- $calendar = new Calendar(new Backend\Mock([],[]), []);
+ $calendar = new Calendar(new Backend\Mock([], []), []);
$this->assertNull($calendar->getSyncToken());
}
function testGetChanges() {
- $this->assertEquals([
- 'syncToken' => 2,
- 'modified' => [],
- 'deleted' => [],
- 'added' => ['UUID-2345'],
- ], $this->calendar->getChanges(1, 1));
+ $this->assertNull($this->calendar->getChanges(1, 1));
}
- function testGetChangesNoSyncSupport() {
-
- $calendar = new Calendar(new Backend\Mock([],[]), []);
- $this->assertNull($calendar->getChanges(1,null));
-
- }
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
index b64fb122a..3a22e03d4 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
@@ -19,18 +19,18 @@ class ExpandEventsDoubleEventsTest extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
- protected $caldavCalendars = array(
- array(
- 'id' => 1,
- 'name' => 'Calendar',
+ protected $caldavCalendars = [
+ [
+ 'id' => 1,
+ 'name' => 'Calendar',
'principaluri' => 'principals/user1',
- 'uri' => 'calendar1',
- )
- );
+ 'uri' => 'calendar1',
+ ]
+ ];
- protected $caldavCalendarObjects = array(
- 1 => array(
- 'event.ics' => array(
+ protected $caldavCalendarObjects = [
+ 1 => [
+ 'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
@@ -50,17 +50,17 @@ RECURRENCE-ID;TZID=Europe/Berlin:20120208T181500
END:VEVENT
END:VCALENDAR
',
- ),
- ),
- );
+ ],
+ ],
+ ];
function testExpand() {
$request = HTTP\Sapi::createFromServerArray([
- 'REQUEST_METHOD' => 'REPORT',
+ 'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
- 'REQUEST_URI' => '/calendars/user1/calendar1',
- 'HTTP_DEPTH' => '1',
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
@@ -88,12 +88,12 @@ END:VCALENDAR
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
- $body = str_replace('&#13;','',$body);
+ $body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
// We only expect 3 events
- $this->assertEquals(3, count($vObject->VEVENT),'We got 6 events instead of 3. Output: ' . $body);
+ $this->assertEquals(3, count($vObject->VEVENT), 'We got 6 events instead of 3. Output: ' . $body);
// TZID should be gone
$this->assertFalse(isset($vObject->VEVENT->DTSTART['TZID']));
@@ -101,4 +101,3 @@ END:VCALENDAR
}
}
-
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
index 84f05f3c0..7a756774f 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/FreeBusyReportTest.php
@@ -3,7 +3,6 @@
namespace Sabre\CalDAV;
use Sabre\DAV;
-use Sabre\DAVACL;
use Sabre\HTTP;
require_once 'Sabre/CalDAV/Backend/Mock.php';
@@ -31,8 +30,8 @@ END:VEVENT
END:VCALENDAR
ics;
- $obj2 = fopen('php://memory','r+');
- fwrite($obj2,<<<ics
+ $obj2 = fopen('php://memory', 'r+');
+ fwrite($obj2, <<<ics
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20121005T120000Z
@@ -55,18 +54,18 @@ ics;
$calendarData = [
1 => [
'obj1' => [
- 'calendarid' => 1,
- 'uri' => 'event1.ics',
+ 'calendarid' => 1,
+ 'uri' => 'event1.ics',
'calendardata' => $obj1,
],
'obj2' => [
- 'calendarid' => 1,
- 'uri' => 'event2.ics',
+ 'calendarid' => 1,
+ 'uri' => 'event2.ics',
'calendardata' => $obj2
],
'obj3' => [
- 'calendarid' => 1,
- 'uri' => 'event3.ics',
+ 'calendarid' => 1,
+ 'uri' => 'event3.ics',
'calendardata' => $obj3
]
],
@@ -76,9 +75,9 @@ ics;
$caldavBackend = new Backend\Mock([], $calendarData);
$calendar = new Calendar($caldavBackend, [
- 'id' => 1,
- 'uri' => 'calendar',
- 'principaluri' => 'principals/user1',
+ 'id' => 1,
+ 'uri' => 'calendar',
+ 'principaluri' => 'principals/user1',
'{' . Plugin::NS_CALDAV . '}calendar-timezone' => "BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nEND:VTIMEZONE\r\nEND:VCALENDAR",
]);
@@ -105,13 +104,13 @@ ics;
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
- $this->plugin->report($rootElem, $report);
+ $this->plugin->report($rootElem, $report, null);
$this->assertEquals(200, $this->server->httpResponse->status);
$this->assertEquals('text/calendar', $this->server->httpResponse->getHeader('Content-Type'));
- $this->assertTrue(strpos($this->server->httpResponse->body, 'BEGIN:VFREEBUSY')!==false);
- $this->assertTrue(strpos($this->server->httpResponse->body, '20111005T120000Z/20111005T130000Z')!==false);
- $this->assertTrue(strpos($this->server->httpResponse->body, '20111006T100000Z/20111006T110000Z')!==false);
+ $this->assertTrue(strpos($this->server->httpResponse->body, 'BEGIN:VFREEBUSY') !== false);
+ $this->assertTrue(strpos($this->server->httpResponse->body, '20111005T120000Z/20111005T130000Z') !== false);
+ $this->assertTrue(strpos($this->server->httpResponse->body, '20111006T100000Z/20111006T110000Z') !== false);
}
@@ -127,7 +126,6 @@ XML;
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
- $this->plugin->report($rootElem, $report);
}
@@ -136,9 +134,9 @@ XML;
*/
function testFreeBusyReportWrongNode() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_URI' => '/',
- ));
+ ]);
$this->server->httpRequest = $request;
$reportXML = <<<XML
@@ -149,7 +147,7 @@ XML;
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
- $this->plugin->report($rootElem, $report);
+ $this->plugin->report($rootElem, $report, null);
}
@@ -170,7 +168,7 @@ XML;
XML;
$report = $this->server->xml->parse($reportXML, null, $rootElem);
- $this->plugin->report($rootElem, $report);
+ $this->plugin->report($rootElem, $report, null);
}
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
index c3c97e8f6..5fd8d29a1 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
@@ -75,7 +75,7 @@ END:VCALENDAR
$response = $this->request($request);
- $this->assertTrue(strpos($response->body, 'BEGIN:VCALENDAR')!==false);
+ $this->assertTrue(strpos($response->body, 'BEGIN:VCALENDAR') !== false);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
index c123bd0c1..9719529fb 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ICSExportPluginTest.php
@@ -7,657 +7,380 @@ use Sabre\HTTP;
use Sabre\VObject;
use Sabre\DAVACL;
-require_once 'Sabre/CalDAV/TestUtil.php';
-require_once 'Sabre/HTTP/ResponseMock.php';
+class ICSExportPluginTest extends \Sabre\DAVServerTest {
-class ICSExportPluginTest extends \PHPUnit_Framework_TestCase {
+ protected $setupCalDAV = true;
+
+ protected $icsExportPlugin;
function setUp() {
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
+ parent::setUp();
+ $this->icsExportPlugin = new ICSExportPlugin();
+ $this->server->addPlugin(
+ $this->icsExportPlugin
+ );
- }
+ $id = $this->caldavBackend->createCalendar(
+ 'principals/admin',
+ 'UUID-123467',
+ [
+ '{DAV:}displayname' => 'Hello!',
+ '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
+ ]
+ );
- function testInit() {
+ $this->caldavBackend->createCalendarObject(
+ $id,
+ 'event-1',
+ <<<ICS
+BEGIN:VCALENDAR
+BEGIN:VTIMEZONE
+TZID:Europe/Amsterdam
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:event-1
+DTSTART;TZID=Europe/Amsterdam:20151020T000000
+END:VEVENT
+END:VCALENDAR
+ICS
+ );
+ $this->caldavBackend->createCalendarObject(
+ $id,
+ 'todo-1',
+ <<<ICS
+BEGIN:VCALENDAR
+BEGIN:VTODO
+UID:todo-1
+END:VTODO
+END:VCALENDAR
+ICS
+ );
- $p = new ICSExportPlugin();
- $s = new DAV\Server();
- $s->addPlugin($p);
- $this->assertEquals($p, $s->getPlugin('ics-export'));
- $this->assertEquals('ics-export', $p->getPluginInfo()['name']);
}
- function testBeforeMethod() {
+ function testInit() {
- $cbackend = TestUtil::getBackend();
-
- $props = [
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- '{DAV:}displayname' => 'Hello!',
- '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
- ];
- $tree = [
- new Calendar($cbackend,$props),
- ];
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $this->assertFalse($p->httpGet($h, $s->httpResponse));
-
- $this->assertEquals(200, $s->httpResponse->status);
- $this->assertEquals([
- 'Content-Type' => ['text/calendar'],
- ], $s->httpResponse->getHeaders());
-
- $obj = VObject\Reader::read($s->httpResponse->body);
-
- $this->assertEquals(7,count($obj->children()));
- $this->assertEquals(1,count($obj->VERSION));
- $this->assertEquals(1,count($obj->CALSCALE));
- $this->assertEquals(1,count($obj->PRODID));
- $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false);
- $this->assertEquals(1,count($obj->VTIMEZONE));
- $this->assertEquals(1,count($obj->VEVENT));
- $this->assertEquals("Hello!", $obj->{"X-WR-CALNAME"});
- $this->assertEquals("#AA0000FF", $obj->{"X-APPLE-CALENDAR-COLOR"});
+ $this->assertEquals(
+ $this->icsExportPlugin,
+ $this->server->getPlugin('ics-export')
+ );
+ $this->assertEquals($this->icsExportPlugin, $this->server->getPlugin('ics-export'));
+ $this->assertEquals('ics-export', $this->icsExportPlugin->getPluginInfo()['name']);
}
- function testBeforeMethodNoVersion() {
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
- $cbackend = TestUtil::getBackend();
+ function testBeforeMethod() {
- $props = [
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- ];
- $tree = [
- new Calendar($cbackend,$props),
- ];
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export'
+ );
- $p = new ICSExportPlugin();
+ $response = $this->request($request);
- $s = new DAV\Server($tree);
+ $this->assertEquals(200, $response->getStatus());
+ $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
+ $obj = VObject\Reader::read($response->body);
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export',
- 'REQUEST_METHOD' => 'GET',
- ]);
+ $this->assertEquals(8, count($obj->children()));
+ $this->assertEquals(1, count($obj->VERSION));
+ $this->assertEquals(1, count($obj->CALSCALE));
+ $this->assertEquals(1, count($obj->PRODID));
+ $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
+ $this->assertEquals(1, count($obj->VTIMEZONE));
+ $this->assertEquals(1, count($obj->VEVENT));
+ $this->assertEquals("Hello!", $obj->{"X-WR-CALNAME"});
+ $this->assertEquals("#AA0000FF", $obj->{"X-APPLE-CALENDAR-COLOR"});
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
+ }
+ function testBeforeMethodNoVersion() {
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export'
+ );
DAV\Server::$exposeVersion = false;
- $this->assertFalse($p->httpGet($h, $s->httpResponse));
+ $response = $this->request($request);
DAV\Server::$exposeVersion = true;
- $this->assertEquals(200, $s->httpResponse->status);
- $this->assertEquals([
- 'Content-Type' => ['text/calendar'],
- ], $s->httpResponse->getHeaders());
+ $this->assertEquals(200, $response->getStatus());
+ $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
- $obj = VObject\Reader::read($s->httpResponse->body);
+ $obj = VObject\Reader::read($response->body);
- $this->assertEquals(5,count($obj->children()));
- $this->assertEquals(1,count($obj->VERSION));
- $this->assertEquals(1,count($obj->CALSCALE));
- $this->assertEquals(1,count($obj->PRODID));
- $this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION)!==false);
- $this->assertEquals(1,count($obj->VTIMEZONE));
- $this->assertEquals(1,count($obj->VEVENT));
+ $this->assertEquals(8, count($obj->children()));
+ $this->assertEquals(1, count($obj->VERSION));
+ $this->assertEquals(1, count($obj->CALSCALE));
+ $this->assertEquals(1, count($obj->PRODID));
+ $this->assertFalse(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
+ $this->assertEquals(1, count($obj->VTIMEZONE));
+ $this->assertEquals(1, count($obj->VEVENT));
}
function testBeforeMethodNoExport() {
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server();
- $s->addPlugin($p);
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467',
- 'REQUEST_METHOD' => 'GET',
- ]);
- $this->assertNull($p->httpGet($h, $s->httpResponse));
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467'
+ );
+ $response = new HTTP\Response();
+ $this->assertNull($this->icsExportPlugin->httpGet($request, $response));
}
function testACLIntegrationBlocked() {
- $cbackend = TestUtil::getBackend();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $aclPlugin = new DAVACL\Plugin();
+ $aclPlugin->allowUnauthenticatedAccess = false;
+ $this->server->addPlugin(
+ $aclPlugin
);
- $tree = array(
- new Calendar($cbackend,$props),
- );
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
- $s->addPlugin(new DAVACL\Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export',
- ]);
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $p->httpGet($h, $s->httpResponse);
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export'
+ );
- // If the ACL system blocked this request, the effect will be that
- // there's no response, because the calendar information could not be
- // fetched.
- $this->assertNull($s->httpResponse->getStatus());
+ $this->request($request, 403);
}
function testACLIntegrationNotBlocked() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $aclPlugin = new DAVACL\Plugin();
+ $aclPlugin->allowUnauthenticatedAccess = false;
+ $this->server->addPlugin(
+ $aclPlugin
);
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
+ $this->server->addPlugin(
+ new Plugin()
);
- $p = new ICSExportPlugin();
+ $this->autoLogin('admin');
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
- $s->addPlugin(new DAVACL\Plugin());
- $s->addPlugin(new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock(),'SabreDAV'));
-
- // Forcing login
- $s->getPlugin('acl')->adminPrincipals = array('principals/admin');
-
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export'
+ );
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $this->assertEquals(array(
- 'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['text/calendar'],
- ), $s->httpResponse->getHeaders());
+ $response = $this->request($request, 200);
+ $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
- $obj = VObject\Reader::read($s->httpResponse->body);
+ $obj = VObject\Reader::read($response->body);
- $this->assertEquals(5,count($obj->children()));
- $this->assertEquals(1,count($obj->VERSION));
- $this->assertEquals(1,count($obj->CALSCALE));
- $this->assertEquals(1,count($obj->PRODID));
- $this->assertEquals(1,count($obj->VTIMEZONE));
- $this->assertEquals(1,count($obj->VEVENT));
+ $this->assertEquals(8, count($obj->children()));
+ $this->assertEquals(1, count($obj->VERSION));
+ $this->assertEquals(1, count($obj->CALSCALE));
+ $this->assertEquals(1, count($obj->PRODID));
+ $this->assertTrue(strpos((string)$obj->PRODID, DAV\Version::VERSION) !== false);
+ $this->assertEquals(1, count($obj->VTIMEZONE));
+ $this->assertEquals(1, count($obj->VEVENT));
}
function testBadStartParam() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- );
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&start=foo'
);
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&start=foo',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
+ $this->request($request, 400);
}
function testBadEndParam() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&end=foo'
);
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- );
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&end=foo',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
+ $this->request($request, 400);
}
function testFilterStartEnd() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&start=1&end=2'
);
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- );
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&start=1&end=2',
- 'REQUEST_METHOD' => 'GET',
- ]);
+ $response = $this->request($request, 200);
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
+ $obj = VObject\Reader::read($response->getBody());
- $s->exec();
-
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $obj = VObject\Reader::read($s->httpResponse->body);
-
- $this->assertEquals(0,count($obj->VTIMEZONE));
- $this->assertEquals(0,count($obj->VEVENT));
+ $this->assertEquals(0, count($obj->VTIMEZONE));
+ $this->assertEquals(0, count($obj->VEVENT));
}
function testExpandNoStart() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&expand=1&end=2'
);
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- );
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&expand=1&end=1',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
+ $this->request($request, 400);
}
function testExpand() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&start=1&end=2000000000&expand=1'
);
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- );
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&start=1&end=2000000000&expand=1',
- 'REQUEST_METHOD' => 'GET',
- ]);
+ $response = $this->request($request, 200);
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
+ $obj = VObject\Reader::read($response->getBody());
- $s->exec();
-
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $obj = VObject\Reader::read($s->httpResponse->body);
-
- $this->assertEquals(0,count($obj->VTIMEZONE));
- $this->assertEquals(1,count($obj->VEVENT));
+ $this->assertEquals(0, count($obj->VTIMEZONE));
+ $this->assertEquals(1, count($obj->VEVENT));
}
function testJCal() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export',
+ ['Accept' => 'application/calendar+json']
);
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- );
-
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export',
- 'REQUEST_METHOD' => 'GET',
- 'HTTP_ACCEPT' => 'application/calendar+json',
- ]);
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $this->assertEquals('application/calendar+json', $s->httpResponse->getHeader('Content-Type'));
+ $response = $this->request($request, 200);
+ $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
}
function testJCalInUrl() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- );
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&accept=jcal'
);
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&accept=jcal',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $this->assertEquals('application/calendar+json', $s->httpResponse->getHeader('Content-Type'));
+ $response = $this->request($request, 200);
+ $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
}
function testNegotiateDefault() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- );
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export',
+ ['Accept' => 'text/plain']
);
- $p = new ICSExportPlugin();
-
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export',
- 'REQUEST_METHOD' => 'GET',
- 'HTTP_ACCEPT' => 'text/plain',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $this->assertEquals('text/calendar', $s->httpResponse->getHeader('Content-Type'));
+ $response = $this->request($request, 200);
+ $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
}
function testFilterComponentVEVENT() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
-
- $props = array(
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- );
- // add a todo to the calendar (see /tests/Sabre/TestUtil)
- $cbackend->createCalendarObject(1, 'UUID-3456', TestUtil::getTestTODO());
-
- $tree = array(
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&componentType=VEVENT'
);
- $p = new ICSExportPlugin();
+ $response = $this->request($request, 200);
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
-
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&componentType=VEVENT',
- 'REQUEST_METHOD' => 'GET',
- ]);
-
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
-
- $s->exec();
-
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $obj = VObject\Reader::read($s->httpResponse->body);
-
- $this->assertEquals(1,count($obj->VTIMEZONE));
- $this->assertEquals(1,count($obj->VEVENT));
- $this->assertEquals(0,count($obj->VTODO));
+ $obj = VObject\Reader::read($response->body);
+ $this->assertEquals(1, count($obj->VTIMEZONE));
+ $this->assertEquals(1, count($obj->VEVENT));
+ $this->assertEquals(0, count($obj->VTODO));
}
function testFilterComponentVTODO() {
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&componentType=VTODO'
+ );
- $props = [
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- ];
- // add a todo to the calendar (see /tests/Sabre/TestUtil)
- $cbackend->createCalendarObject(1, 'UUID-3456', TestUtil::getTestTODO());
+ $response = $this->request($request, 200);
- $tree = [
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- ];
+ $obj = VObject\Reader::read($response->body);
- $p = new ICSExportPlugin();
+ $this->assertEquals(0, count($obj->VTIMEZONE));
+ $this->assertEquals(0, count($obj->VEVENT));
+ $this->assertEquals(1, count($obj->VTODO));
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
+ }
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&componentType=VTODO',
- 'REQUEST_METHOD' => 'GET',
- ]);
+ function testFilterComponentBadComponent() {
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export&componentType=VVOODOO'
+ );
- $s->exec();
+ $response = $this->request($request, 400);
- $this->assertEquals(200, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
- $obj = VObject\Reader::read($s->httpResponse->body);
+ }
- $this->assertEquals(0,count($obj->VTIMEZONE));
- $this->assertEquals(0,count($obj->VEVENT));
- $this->assertEquals(1,count($obj->VTODO));
+ function testContentDisposition() {
- }
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export'
+ );
- function testFilterComponentBadComponent() {
+ $response = $this->request($request, 200);
+ $this->assertEquals('text/calendar', $response->getHeader('Content-Type'));
+ $this->assertEquals(
+ 'attachment; filename="UUID-123467-' . date('Y-m-d') . '.ics"',
+ $response->getHeader('Content-Disposition')
+ );
- $cbackend = TestUtil::getBackend();
- $pbackend = new DAVACL\PrincipalBackend\Mock();
+ }
- $props = [
- 'uri'=>'UUID-123467',
- 'principaluri' => 'admin',
- 'id' => 1,
- ];
- // add a todo to the calendar (see /tests/Sabre/TestUtil)
- $cbackend->createCalendarObject(1, 'UUID-3456', TestUtil::getTestTODO());
+ function testContentDispositionJson() {
- $tree = [
- new Calendar($cbackend,$props),
- new DAVACL\PrincipalCollection($pbackend),
- ];
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-123467?export',
+ ['Accept' => 'application/calendar+json']
+ );
- $p = new ICSExportPlugin();
+ $response = $this->request($request, 200);
+ $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
+ $this->assertEquals(
+ 'attachment; filename="UUID-123467-' . date('Y-m-d') . '.json"',
+ $response->getHeader('Content-Disposition')
+ );
- $s = new DAV\Server($tree);
- $s->sapi = new HTTP\SapiMock();
- $s->addPlugin($p);
- $s->addPlugin(new Plugin());
+ }
- $h = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/UUID-123467?export&componentType=VVOODOO',
- 'REQUEST_METHOD' => 'GET',
- ]);
+ function testContentDispositionBadChars() {
- $s->httpRequest = $h;
- $s->httpResponse = new HTTP\ResponseMock();
+ $this->caldavBackend->createCalendar(
+ 'principals/admin',
+ 'UUID-b_ad"(ch)ars',
+ [
+ '{DAV:}displayname' => 'Test bad characters',
+ '{http://apple.com/ns/ical/}calendar-color' => '#AA0000FF',
+ ]
+ );
- $s->exec();
+ $request = new HTTP\Request(
+ 'GET',
+ '/calendars/admin/UUID-b_ad"(ch)ars?export',
+ ['Accept' => 'application/calendar+json']
+ );
- $this->assertEquals(400, $s->httpResponse->status,'Invalid status received. Response body: '. $s->httpResponse->body);
+ $response = $this->request($request, 200);
+ $this->assertEquals('application/calendar+json', $response->getHeader('Content-Type'));
+ $this->assertEquals(
+ 'attachment; filename="UUID-b_adchars-' . date('Y-m-d') . '.json"',
+ $response->getHeader('Content-Disposition')
+ );
}
+
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
index f925224f2..a1a9b7c04 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue166Test.php
@@ -1,8 +1,8 @@
<?php
namespace Sabre\CalDAV;
+
use Sabre\VObject;
-use Sabre\DAV;
class Issue166Test extends \PHPUnit_Framework_TestCase {
@@ -37,26 +37,26 @@ HI;
$validator = new CalendarQueryValidator();
- $filters = array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filters = [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2011-12-01'),
'end' => new \DateTime('2012-02-01'),
- ),
- ),
- ),
- 'prop-filters' => array(),
+ ],
+ ],
+ ],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => null,
- );
+ 'time-range' => null,
+ ];
$input = VObject\Reader::read($input);
- $this->assertTrue($validator->validate($input,$filters));
+ $this->assertTrue($validator->validate($input, $filters));
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
index ce6d364f6..e2b85c2bc 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue172Test.php
@@ -1,8 +1,8 @@
<?php
namespace Sabre\CalDAV;
+
use Sabre\VObject;
-use Sabre\DAV;
class Issue172Test extends \PHPUnit_Framework_TestCase {
@@ -18,24 +18,24 @@ END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
- $filters = array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filters = [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
'end' => new \DateTime('2012-01-18 21:00:00 GMT-08:00'),
- ),
- ),
- ),
- 'prop-filters' => array(),
- );
+ ],
+ ],
+ ],
+ 'prop-filters' => [],
+ ];
$input = VObject\Reader::read($input);
- $this->assertTrue($validator->validate($input,$filters));
+ $this->assertTrue($validator->validate($input, $filters));
}
// Pacific Standard Time, translates to America/Los_Angeles (GMT-8 in January)
@@ -65,24 +65,24 @@ END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
- $filters = array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filters = [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
- ),
- ),
- ),
- 'prop-filters' => array(),
- );
+ ],
+ ],
+ ],
+ 'prop-filters' => [],
+ ];
$input = VObject\Reader::read($input);
- $this->assertTrue($validator->validate($input,$filters));
+ $this->assertTrue($validator->validate($input, $filters));
}
// X-LIC-LOCATION, translates to America/Los_Angeles (GMT-8 in January)
@@ -113,23 +113,23 @@ END:VEVENT
END:VCALENDAR
HI;
$validator = new CalendarQueryValidator();
- $filters = array(
- 'name' => 'VCALENDAR',
- 'comp-filters' => array(
- array(
- 'name' => 'VEVENT',
- 'comp-filters' => array(),
- 'prop-filters' => array(),
+ $filters = [
+ 'name' => 'VCALENDAR',
+ 'comp-filters' => [
+ [
+ 'name' => 'VEVENT',
+ 'comp-filters' => [],
+ 'prop-filters' => [],
'is-not-defined' => false,
- 'time-range' => array(
+ 'time-range' => [
'start' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
'end' => new \DateTime('2012-01-13 10:30:00 GMT-08:00'),
- ),
- ),
- ),
- 'prop-filters' => array(),
- );
+ ],
+ ],
+ ],
+ 'prop-filters' => [],
+ ];
$input = VObject\Reader::read($input);
- $this->assertTrue($validator->validate($input,$filters));
+ $this->assertTrue($validator->validate($input, $filters));
}
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
index 4a53fcbe2..ce40a90b0 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue205Test.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV;
+
use Sabre\HTTP;
use Sabre\VObject;
@@ -15,18 +16,18 @@ class Issue205Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
- protected $caldavCalendars = array(
- array(
- 'id' => 1,
- 'name' => 'Calendar',
+ protected $caldavCalendars = [
+ [
+ 'id' => 1,
+ 'name' => 'Calendar',
'principaluri' => 'principals/user1',
- 'uri' => 'calendar1',
- )
- );
+ 'uri' => 'calendar1',
+ ]
+ ];
- protected $caldavCalendarObjects = array(
- 1 => array(
- 'event.ics' => array(
+ protected $caldavCalendarObjects = [
+ 1 => [
+ 'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
@@ -44,18 +45,18 @@ END:VALARM
END:VEVENT
END:VCALENDAR
',
- ),
- ),
- );
+ ],
+ ],
+ ];
function testIssue205() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
+ $request = HTTP\Sapi::createFromServerArray([
+ 'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
- 'REQUEST_URI' => '/calendars/user1/calendar1',
- 'HTTP_DEPTH' => '1',
- ));
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
@@ -87,7 +88,7 @@ END:VCALENDAR
$start = strpos($response->body, 'BEGIN:VCALENDAR'),
strpos($response->body, 'END:VCALENDAR') - $start + 13
);
- $body = str_replace('&#13;','',$body);
+ $body = str_replace('&#13;', '', $body);
$vObject = VObject\Reader::read($body);
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
index f291e5e57..950629fd8 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue211Test.php
@@ -1,8 +1,8 @@
<?php
namespace Sabre\CalDAV;
+
use Sabre\HTTP;
-use Sabre\VObject;
/**
* This unittest is created to check for an endless loop in Sabre\CalDAV\CalendarQueryValidator
@@ -15,18 +15,18 @@ class Issue211Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
- protected $caldavCalendars = array(
- array(
- 'id' => 1,
- 'name' => 'Calendar',
+ protected $caldavCalendars = [
+ [
+ 'id' => 1,
+ 'name' => 'Calendar',
'principaluri' => 'principals/user1',
- 'uri' => 'calendar1',
- )
- );
+ 'uri' => 'calendar1',
+ ]
+ ];
- protected $caldavCalendarObjects = array(
- 1 => array(
- 'event.ics' => array(
+ protected $caldavCalendarObjects = [
+ 1 => [
+ 'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
@@ -49,18 +49,18 @@ END:VALARM
END:VEVENT
END:VCALENDAR
',
- ),
- ),
- );
+ ],
+ ],
+ ];
function testIssue211() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
+ $request = HTTP\Sapi::createFromServerArray([
+ 'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
- 'REQUEST_URI' => '/calendars/user1/calendar1',
- 'HTTP_DEPTH' => '1',
- ));
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
index 7b5dbfe63..c3c0b5b48 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue220Test.php
@@ -15,18 +15,18 @@ class Issue220Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
- protected $caldavCalendars = array(
- array(
- 'id' => 1,
- 'name' => 'Calendar',
+ protected $caldavCalendars = [
+ [
+ 'id' => 1,
+ 'name' => 'Calendar',
'principaluri' => 'principals/user1',
- 'uri' => 'calendar1',
- )
- );
+ 'uri' => 'calendar1',
+ ]
+ ];
- protected $caldavCalendarObjects = array(
- 1 => array(
- 'event.ics' => array(
+ protected $caldavCalendarObjects = [
+ 1 => [
+ 'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
@@ -59,18 +59,18 @@ UID:b64f14c5-dccc-4eda-947f-bdb1f763fbcd
END:VEVENT
END:VCALENDAR
',
- ),
- ),
- );
+ ],
+ ],
+ ];
function testIssue220() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
+ $request = HTTP\Sapi::createFromServerArray([
+ 'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
- 'REQUEST_URI' => '/calendars/user1/calendar1',
- 'HTTP_DEPTH' => '1',
- ));
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
index ccc6b303a..d0783701d 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Issue228Test.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV;
+
use Sabre\HTTP;
/**
@@ -14,18 +15,18 @@ class Issue228Test extends \Sabre\DAVServerTest {
protected $setupCalDAV = true;
- protected $caldavCalendars = array(
- array(
- 'id' => 1,
- 'name' => 'Calendar',
+ protected $caldavCalendars = [
+ [
+ 'id' => 1,
+ 'name' => 'Calendar',
'principaluri' => 'principals/user1',
- 'uri' => 'calendar1',
- )
- );
+ 'uri' => 'calendar1',
+ ]
+ ];
- protected $caldavCalendarObjects = array(
- 1 => array(
- 'event.ics' => array(
+ protected $caldavCalendarObjects = [
+ 1 => [
+ 'event.ics' => [
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
@@ -38,18 +39,18 @@ TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
',
- ),
- ),
- );
+ ],
+ ],
+ ];
function testIssue228() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
+ $request = HTTP\Sapi::createFromServerArray([
+ 'REQUEST_METHOD' => 'REPORT',
'HTTP_CONTENT_TYPE' => 'application/xml',
- 'REQUEST_URI' => '/calendars/user1/calendar1',
- 'HTTP_DEPTH' => '1',
- ));
+ 'REQUEST_URI' => '/calendars/user1/calendar1',
+ 'HTTP_DEPTH' => '1',
+ ]);
$request->setBody('<?xml version="1.0" encoding="utf-8" ?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
index 68035184f..6585f85c3 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/CollectionTest.php
@@ -14,13 +14,13 @@ class CollectionTest extends \PHPUnit_Framework_TestCase {
$this->principalUri = 'principals/user1';
- $this->notification = new CalDAV\Xml\Notification\SystemStatus(1,'"1"');
+ $this->notification = new CalDAV\Xml\Notification\SystemStatus(1, '"1"');
- $this->caldavBackend = new CalDAV\Backend\MockSharing(array(),array(), array(
- 'principals/user1' => array(
+ $this->caldavBackend = new CalDAV\Backend\MockSharing([], [], [
+ 'principals/user1' => [
$this->notification
- )
- ));
+ ]
+ ]);
return new Collection($this->caldavBackend, $this->principalUri);
@@ -31,9 +31,9 @@ class CollectionTest extends \PHPUnit_Framework_TestCase {
$col = $this->getInstance();
$this->assertEquals('notifications', $col->getName());
- $this->assertEquals(array(
+ $this->assertEquals([
new Node($this->caldavBackend, $this->principalUri, $this->notification)
- ), $col->getChildren());
+ ], $col->getChildren());
}
@@ -54,30 +54,25 @@ class CollectionTest extends \PHPUnit_Framework_TestCase {
function testGetACL() {
$col = $this->getInstance();
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => $this->principalUri,
+ $expected = [
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => $this->principalUri,
- 'protected' => true,
- ),
- );
+ ],
+ ];
$this->assertEquals($expected, $col->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\NotImplemented
+ * @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$col = $this->getInstance();
- $col->setACL(array());
+ $col->setACL([]);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
index d546116fc..6c6e02da8 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Notifications/NodeTest.php
@@ -13,7 +13,7 @@ class NodeTest extends \PHPUnit_Framework_TestCase {
$principalUri = 'principals/user1';
- $this->systemStatus = new CalDAV\Xml\Notification\SystemStatus(1,'"1"');
+ $this->systemStatus = new CalDAV\Xml\Notification\SystemStatus(1, '"1"');
$this->caldavBackend = new CalDAV\Backend\MockSharing([], [], [
'principals/user1' => [
@@ -51,7 +51,7 @@ class NodeTest extends \PHPUnit_Framework_TestCase {
$node = $this->getInstance();
$node->delete();
- $this->assertEquals(array(), $this->caldavBackend->getNotificationsForPrincipal('principals/user1'));
+ $this->assertEquals([], $this->caldavBackend->getNotificationsForPrincipal('principals/user1'));
}
@@ -65,30 +65,25 @@ class NodeTest extends \PHPUnit_Framework_TestCase {
function testGetACL() {
$node = $this->getInstance();
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/user1',
+ $expected = [
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/user1',
- 'protected' => true,
- ),
- );
+ ],
+ ];
$this->assertEquals($expected, $node->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\NotImplemented
+ * @expectedException \Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
$node = $this->getInstance();
- $node->setACL(array());
+ $node->setACL([]);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
index 138012ffa..8d538dee5 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/PluginTest.php
@@ -81,12 +81,14 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
$this->server->addPlugin($this->plugin);
// Adding ACL plugin
- $this->server->addPlugin(new DAVACL\Plugin());
+ $aclPlugin = new DAVACL\Plugin();
+ $aclPlugin->allowUnauthenticatedAccess = false;
+ $this->server->addPlugin($aclPlugin);
// Adding Auth plugin, and ensuring that we are logged in.
$authBackend = new DAV\Auth\Backend\Mock();
$authBackend->setPrincipal('principals/user1');
- $authPlugin = new DAV\Auth\Plugin($authBackend, 'SabreDAV');
+ $authPlugin = new DAV\Auth\Plugin($authBackend);
$authPlugin->beforeMethod(new \Sabre\HTTP\Request(), new \Sabre\HTTP\Response());
$this->server->addPlugin($authPlugin);
@@ -480,8 +482,9 @@ END:VCALENDAR';
$this->assertInstanceOf('\\Sabre\\DAV\\Xml\\Property\\SupportedReportSet', $prop);
$value = [
'{DAV:}expand-property',
+ '{DAV:}principal-match',
'{DAV:}principal-property-search',
- '{DAV:}principal-search-property-set'
+ '{DAV:}principal-search-property-set',
];
$this->assertEquals($value, $prop->getValue());
@@ -508,6 +511,7 @@ END:VCALENDAR';
'{urn:ietf:params:xml:ns:caldav}calendar-query',
'{urn:ietf:params:xml:ns:caldav}free-busy-query',
'{DAV:}expand-property',
+ '{DAV:}principal-match',
'{DAV:}principal-property-search',
'{DAV:}principal-search-property-set'
];
@@ -533,6 +537,7 @@ END:VCALENDAR';
$value = [
'{DAV:}sync-collection',
'{DAV:}expand-property',
+ '{DAV:}principal-match',
'{DAV:}principal-property-search',
'{DAV:}principal-search-property-set',
];
@@ -719,7 +724,7 @@ XML;
'</c:calendar-query>';
$request = new HTTP\Request('REPORT', '/calendars/user1/UUID-123467', [
- 'Depth' => '0',
+ 'Depth' => '0',
'User-Agent' => 'MSFT-WP/8.10.14219 (gzip)',
]);
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
index 625f64211..23c248825 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/CollectionTest.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV\Principal;
+
use Sabre\DAVACL;
class CollectionTest extends \PHPUnit_Framework_TestCase {
@@ -9,9 +10,9 @@ class CollectionTest extends \PHPUnit_Framework_TestCase {
$back = new DAVACL\PrincipalBackend\Mock();
$col = new Collection($back);
- $r = $col->getChildForPrincipal(array(
+ $r = $col->getChildForPrincipal([
'uri' => 'principals/admin',
- ));
+ ]);
$this->assertInstanceOf('Sabre\\CalDAV\\Principal\\User', $r);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
index 1ee999a92..fe07f0131 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyReadTest.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV\Principal;
+
use Sabre\DAVACL;
class ProxyReadTest extends \PHPUnit_Framework_TestCase {
@@ -10,9 +11,9 @@ class ProxyReadTest extends \PHPUnit_Framework_TestCase {
function getInstance() {
$backend = new DAVACL\PrincipalBackend\Mock();
- $principal = new ProxyRead($backend, array(
+ $principal = new ProxyRead($backend, [
'uri' => 'principal/user',
- ));
+ ]);
$this->backend = $backend;
return $principal;
@@ -61,7 +62,7 @@ class ProxyReadTest extends \PHPUnit_Framework_TestCase {
function testGetAlternateUriSet() {
$i = $this->getInstance();
- $this->assertEquals(array(), $i->getAlternateUriSet());
+ $this->assertEquals([], $i->getAlternateUriSet());
}
@@ -75,25 +76,25 @@ class ProxyReadTest extends \PHPUnit_Framework_TestCase {
function testGetGroupMemberSet() {
$i = $this->getInstance();
- $this->assertEquals(array(), $i->getGroupMemberSet());
+ $this->assertEquals([], $i->getGroupMemberSet());
}
function testGetGroupMembership() {
$i = $this->getInstance();
- $this->assertEquals(array(), $i->getGroupMembership());
+ $this->assertEquals([], $i->getGroupMembership());
}
function testSetGroupMemberSet() {
$i = $this->getInstance();
- $i->setGroupMemberSet(array('principals/foo'));
+ $i->setGroupMemberSet(['principals/foo']);
- $expected = array(
- $i->getPrincipalUrl() => array('principals/foo')
- );
+ $expected = [
+ $i->getPrincipalUrl() => ['principals/foo']
+ ];
$this->assertEquals($expected, $this->backend->groupMembers);
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
index c0186ff0d..6cdb9b30e 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/ProxyWriteTest.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV\Principal;
+
use Sabre\DAVACL;
class ProxyWriteTest extends ProxyReadTest {
@@ -8,9 +9,9 @@ class ProxyWriteTest extends ProxyReadTest {
function getInstance() {
$backend = new DAVACL\PrincipalBackend\Mock();
- $principal = new ProxyWrite($backend, array(
+ $principal = new ProxyWrite($backend, [
'uri' => 'principal/user',
- ));
+ ]);
$this->backend = $backend;
return $principal;
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
index 37b5eae97..420bb3b1a 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Principal/UserTest.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV\Principal;
+
use Sabre\DAVACL;
class UserTest extends \PHPUnit_Framework_TestCase {
@@ -8,18 +9,18 @@ class UserTest extends \PHPUnit_Framework_TestCase {
function getInstance() {
$backend = new DAVACL\PrincipalBackend\Mock();
- $backend->addPrincipal(array(
+ $backend->addPrincipal([
'uri' => 'principals/user/calendar-proxy-read',
- ));
- $backend->addPrincipal(array(
+ ]);
+ $backend->addPrincipal([
'uri' => 'principals/user/calendar-proxy-write',
- ));
- $backend->addPrincipal(array(
+ ]);
+ $backend->addPrincipal([
'uri' => 'principals/user/random',
- ));
- return new User($backend, array(
+ ]);
+ return new User($backend, [
'uri' => 'principals/user',
- ));
+ ]);
}
@@ -100,23 +101,23 @@ class UserTest extends \PHPUnit_Framework_TestCase {
function testGetACL() {
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => '{DAV:}authenticated',
+ $expected = [
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user/calendar-proxy-read',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user/calendar-proxy-write',
'protected' => true,
- ),
- );
+ ],
+ ];
$u = $this->getInstance();
$this->assertEquals($expected, $u->getACL());
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
index 933c7157b..04d4b1237 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/Schedule/OutboxTest.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\CalDAV\Schedule;
+
use Sabre\CalDAV;
use Sabre\DAV;
@@ -10,80 +11,38 @@ class OutboxTest extends \PHPUnit_Framework_TestCase {
$outbox = new Outbox('principals/user1');
$this->assertEquals('outbox', $outbox->getName());
- $this->assertEquals(array(), $outbox->getChildren());
+ $this->assertEquals([], $outbox->getChildren());
$this->assertEquals('principals/user1', $outbox->getOwner());
$this->assertEquals(null, $outbox->getGroup());
- $this->assertEquals(array(
- array(
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
- 'principal' => 'principals/user1',
- 'protected' => true,
- ),
-
- array(
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
+ $this->assertEquals([
+ [
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
- ),
- array(
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy',
+ ],
+ [
+ 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-send',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- array(
- 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent',
- 'principal' => 'principals/user1/calendar-proxy-write',
- 'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-read',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1/calendar-proxy-write',
'protected' => true,
- ),
- ), $outbox->getACL());
-
- $ok = false;
- try {
- $outbox->setACL(array());
- } catch (DAV\Exception\MethodNotAllowed $e) {
- $ok = true;
- }
- if (!$ok) {
- $this->fail('Exception was not emitted');
- }
-
- }
-
- function testGetSupportedPrivilegeSet() {
-
- $outbox = new Outbox('principals/user1');
- $r = $outbox->getSupportedPrivilegeSet();
-
- $ok = 0;
- foreach($r['aggregates'] as $priv) {
-
- if ($priv['privilege'] == '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy') {
- $ok++;
- }
- if ($priv['privilege'] == '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-post-vevent') {
- $ok++;
- }
- }
-
- $this->assertEquals(2, $ok, "We're missing one or more privileges");
+ ],
+ ], $outbox->getACL());
}
-
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php
deleted file mode 100644
index 15b869d50..000000000
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/ShareableCalendarTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-
-namespace Sabre\CalDAV;
-
-use Sabre\DAVACL;
-
-class ShareableCalendarTest extends \PHPUnit_Framework_TestCase {
-
- protected $backend;
- protected $instance;
-
- function setUp() {
-
- $props = array(
- 'id' => 1,
- );
-
- $this->backend = new Backend\MockSharing(
- array($props)
- );
- $this->backend->updateShares(1, array(
- array(
- 'href' => 'mailto:removeme@example.org',
- 'commonName' => 'To be removed',
- 'readOnly' => true,
- ),
- ), array());
-
- $this->instance = new ShareableCalendar($this->backend, $props);
-
- }
-
- function testUpdateShares() {
-
- $this->instance->updateShares(array(
- array(
- 'href' => 'mailto:test@example.org',
- 'commonName' => 'Foo Bar',
- 'summary' => 'Booh',
- 'readOnly' => false,
- ),
- ), array('mailto:removeme@example.org'));
-
- $this->assertEquals(array(array(
- 'href' => 'mailto:test@example.org',
- 'commonName' => 'Foo Bar',
- 'summary' => 'Booh',
- 'readOnly' => false,
- 'status' => SharingPlugin::STATUS_NORESPONSE,
- )), $this->instance->getShares());
-
- }
-
- function testPublish() {
-
- $this->assertNull($this->instance->setPublishStatus(true));
- $this->assertNull($this->instance->setPublishStatus(false));
-
- }
-}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
index 337b658f4..f71c19523 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/SharedCalendarTest.php
@@ -2,7 +2,8 @@
namespace Sabre\CalDAV;
-use Sabre\DAVACL;
+use Sabre\DAV\Sharing;
+use Sabre\DAV\Xml\Element\Sharee;
class SharedCalendarTest extends \PHPUnit_Framework_TestCase {
@@ -11,96 +12,95 @@ class SharedCalendarTest extends \PHPUnit_Framework_TestCase {
function getInstance(array $props = null) {
if (is_null($props)) {
- $props = array(
- 'id' => 1,
+ $props = [
+ 'id' => 1,
'{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
- '{http://sabredav.org/ns}owner-principal' => 'principals/owner',
- '{http://sabredav.org/ns}read-only' => false,
- 'principaluri' => 'principals/sharee',
- );
+ '{http://sabredav.org/ns}owner-principal' => 'principals/owner',
+ '{http://sabredav.org/ns}read-only' => false,
+ 'share-access' => Sharing\Plugin::ACCESS_READWRITE,
+ 'principaluri' => 'principals/sharee',
+ ];
}
$this->backend = new Backend\MockSharing(
- array($props),
- array(),
- array()
+ [$props],
+ [],
+ []
);
- $this->backend->updateShares(1, array(
- array(
- 'href' => 'mailto:removeme@example.org',
- 'commonName' => 'To be removed',
- 'readOnly' => true,
- ),
- ), array());
+
+ $sharee = new Sharee();
+ $sharee->href = 'mailto:removeme@example.org';
+ $sharee->properties['{DAV:}displayname'] = 'To be removed';
+ $sharee->access = Sharing\Plugin::ACCESS_READ;
+ $this->backend->updateInvites(1, [$sharee]);
return new SharedCalendar($this->backend, $props);
}
- function testGetSharedUrl() {
- $this->assertEquals('calendars/owner/original', $this->getInstance()->getSharedUrl());
- }
+ function testGetInvites() {
- function testGetShares() {
+ $sharee = new Sharee();
+ $sharee->href = 'mailto:removeme@example.org';
+ $sharee->properties['{DAV:}displayname'] = 'To be removed';
+ $sharee->access = Sharing\Plugin::ACCESS_READ;
+ $sharee->inviteStatus = Sharing\Plugin::INVITE_NORESPONSE;
- $this->assertEquals(array(array(
- 'href' => 'mailto:removeme@example.org',
- 'commonName' => 'To be removed',
- 'readOnly' => true,
- 'status' => SharingPlugin::STATUS_NORESPONSE,
- )), $this->getInstance()->getShares());
+ $this->assertEquals(
+ [$sharee],
+ $this->getInstance()->getInvites()
+ );
}
function testGetOwner() {
- $this->assertEquals('principals/owner', $this->getInstance()->getOwner());
+ $this->assertEquals('principals/sharee', $this->getInstance()->getOwner());
}
function testGetACL() {
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner',
+ $expected = [
+ [
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/sharee',
'protected' => true,
- ),
-
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner/calendar-proxy-write',
+ ],
+ [
+ 'privilege' => '{DAV:}write',
+ 'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner/calendar-proxy-read',
+ ],
+ [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => 'principals/sharee',
'protected' => true,
- ),
- array(
- 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
- 'principal' => '{DAV:}authenticated',
+ ],
+ [
+ 'privilege' => '{DAV:}write-properties',
+ 'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/owner',
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/sharee',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/owner/calendar-proxy-write',
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/sharee/calendar-proxy-read',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
- 'principal' => 'principals/sharee',
+ 'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/sharee',
+ ],
+ [
+ 'privilege' => '{' . Plugin::NS_CALDAV . '}read-free-busy',
+ 'principal' => '{DAV:}authenticated',
'protected' => true,
- ),
- );
+ ],
+ ];
$this->assertEquals($expected, $this->getInstance()->getACL());
@@ -108,96 +108,69 @@ class SharedCalendarTest extends \PHPUnit_Framework_TestCase {
function testGetChildACL() {
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner/calendar-proxy-write',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner/calendar-proxy-read',
- 'protected' => true,
- ),
- array(
+ $expected = [
+ [
'privilege' => '{DAV:}write',
- 'principal' => 'principals/owner',
+ 'principal' => 'principals/sharee',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}write',
- 'principal' => 'principals/owner/calendar-proxy-write',
+ 'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
- ),
- array(
+ ],
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/sharee',
'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/sharee',
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/sharee/calendar-proxy-write',
'protected' => true,
- ),
- );
+ ],
+ [
+ 'privilege' => '{DAV:}read',
+ 'principal' => 'principals/sharee/calendar-proxy-read',
+ 'protected' => true,
+ ],
+
+ ];
$this->assertEquals($expected, $this->getInstance()->getChildACL());
}
- function testGetChildACLReadOnly() {
+ function testUpdateInvites() {
- $expected = array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner/calendar-proxy-write',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/owner/calendar-proxy-read',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/sharee',
- 'protected' => true,
- ),
- );
+ $instance = $this->getInstance();
+ $newSharees = [
+ new Sharee(),
+ new Sharee()
+ ];
+ $newSharees[0]->href = 'mailto:test@example.org';
+ $newSharees[0]->properties['{DAV:}displayname'] = 'Foo Bar';
+ $newSharees[0]->comment = 'Booh';
+ $newSharees[0]->access = Sharing\Plugin::ACCESS_READWRITE;
- $props = array(
- 'id' => 1,
- '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
- '{http://sabredav.org/ns}owner-principal' => 'principals/owner',
- '{http://sabredav.org/ns}read-only' => true,
- 'principaluri' => 'principals/sharee',
- );
- $this->assertEquals($expected, $this->getInstance($props)->getChildACL());
+ $newSharees[1]->href = 'mailto:removeme@example.org';
+ $newSharees[1]->access = Sharing\Plugin::ACCESS_NOACCESS;
+
+ $instance->updateInvites($newSharees);
+
+ $expected = [
+ clone $newSharees[0]
+ ];
+ $expected[0]->inviteStatus = Sharing\Plugin::INVITE_NORESPONSE;
+ $this->assertEquals($expected, $instance->getInvites());
}
- /**
- * @expectedException InvalidArgumentException
- */
- public function testCreateInstanceMissingArg() {
+ function testPublish() {
- $this->getInstance(array(
- 'id' => 1,
- '{http://calendarserver.org/ns/}shared-url' => 'calendars/owner/original',
- '{http://sabredav.org/ns}read-only' => false,
- 'principaluri' => 'principals/sharee',
- ));
+ $instance = $this->getInstance();
+ $this->assertNull($instance->setPublishStatus(true));
+ $this->assertNull($instance->setPublishStatus(false));
}
-
}
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
index b4270da7d..6e9e88419 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/SharingPluginTest.php
@@ -3,6 +3,7 @@
namespace Sabre\CalDAV;
use Sabre\DAV;
+use Sabre\DAV\Xml\Element\Sharee;
use Sabre\HTTP;
class SharingPluginTest extends \Sabre\DAVServerTest {
@@ -14,31 +15,28 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
function setUp() {
- $this->caldavCalendars = array(
- array(
+ $this->caldavCalendars = [
+ [
'principaluri' => 'principals/user1',
- 'id' => 1,
- 'uri' => 'cal1',
- ),
- array(
+ 'id' => 1,
+ 'uri' => 'cal1',
+ ],
+ [
'principaluri' => 'principals/user1',
- 'id' => 2,
- 'uri' => 'cal2',
- '{' . Plugin::NS_CALENDARSERVER . '}shared-url' => 'calendars/user1/cal2',
- '{http://sabredav.org/ns}owner-principal' => 'principals/user2',
- '{http://sabredav.org/ns}read-only' => 'true',
- ),
- array(
+ 'id' => 2,
+ 'uri' => 'cal2',
+ 'share-access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
+ ],
+ [
'principaluri' => 'principals/user1',
- 'id' => 3,
- 'uri' => 'cal3',
- ),
- );
+ 'id' => 3,
+ 'uri' => 'cal3',
+ ],
+ ];
parent::setUp();
// Making the logged in user an admin, for full access:
- $this->aclPlugin->adminPrincipals[] = 'principals/user1';
$this->aclPlugin->adminPrincipals[] = 'principals/user2';
}
@@ -53,9 +51,21 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
}
+ /**
+ * @expectedException \LogicException
+ */
+ function testSetupWithoutCoreSharingPlugin() {
+
+ $server = new DAV\Server();
+ $server->addPlugin(
+ new SharingPlugin()
+ );
+
+ }
+
function testGetFeatures() {
- $this->assertEquals(array('calendarserver-sharing'), $this->caldavSharingPlugin->getFeatures());
+ $this->assertEquals(['calendarserver-sharing'], $this->caldavSharingPlugin->getFeatures());
}
@@ -63,10 +73,10 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
// Forcing the server to authenticate:
$this->authPlugin->beforeMethod(new HTTP\Request(), new HTTP\Response());
- $props = $this->server->getProperties('calendars/user1/cal1', array(
+ $props = $this->server->getProperties('calendars/user1/cal1', [
'{' . Plugin::NS_CALENDARSERVER . '}invite',
'{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes',
- ));
+ ]);
$this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
$this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\AllowedSharingModes', $props['{' . Plugin::NS_CALENDARSERVER . '}allowed-sharing-modes']);
@@ -75,56 +85,55 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
function testBeforeGetSharedCalendar() {
- $props = $this->server->getProperties('calendars/user1/cal2', array(
+ $props = $this->server->getProperties('calendars/user1/cal2', [
'{' . Plugin::NS_CALENDARSERVER . '}shared-url',
'{' . Plugin::NS_CALENDARSERVER . '}invite',
- ));
+ ]);
$this->assertInstanceOf('Sabre\\CalDAV\\Xml\\Property\\Invite', $props['{' . Plugin::NS_CALENDARSERVER . '}invite']);
- $this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $props['{' . Plugin::NS_CALENDARSERVER . '}shared-url']);
+ //$this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $props['{' . Plugin::NS_CALENDARSERVER . '}shared-url']);
}
- function testUpdateProperties() {
+ function testUpdateResourceType() {
- $this->caldavBackend->updateShares(1,
- array(
- array(
+ $this->caldavBackend->updateInvites(1,
+ [
+ new Sharee([
'href' => 'mailto:joe@example.org',
- ),
- ),
- array()
+ ])
+ ]
);
- $result = $this->server->updateProperties('calendars/user1/cal1', array(
+ $result = $this->server->updateProperties('calendars/user1/cal1', [
'{DAV:}resourcetype' => new DAV\Xml\Property\ResourceType(['{DAV:}collection'])
- ));
+ ]);
$this->assertEquals([
'{DAV:}resourcetype' => 200
], $result);
- $this->assertEquals(0, count($this->caldavBackend->getShares(1)));
+ $this->assertEquals(0, count($this->caldavBackend->getInvites(1)));
}
function testUpdatePropertiesPassThru() {
- $result = $this->server->updateProperties('calendars/user1/cal3', array(
+ $result = $this->server->updateProperties('calendars/user1/cal3', [
'{DAV:}foo' => 'bar',
- ));
+ ]);
- $this->assertEquals(array(
- '{DAV:}foo' => 403,
- ), $result);
+ $this->assertEquals([
+ '{DAV:}foo' => 200,
+ ], $result);
}
function testUnknownMethodNoPOST() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PATCH',
'REQUEST_URI' => '/',
- ));
+ ]);
$response = $this->request($request);
@@ -134,11 +143,11 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
function testUnknownMethodNoXML() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/',
'CONTENT_TYPE' => 'text/plain',
- ));
+ ]);
$response = $this->request($request);
@@ -148,11 +157,11 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
function testUnknownMethodNoNode() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/foo',
'CONTENT_TYPE' => 'text/xml',
- ));
+ ]);
$response = $this->request($request);
@@ -162,11 +171,7 @@ class SharingPluginTest extends \Sabre\DAVServerTest {
function testShareRequest() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal1',
- 'CONTENT_TYPE' => 'text/xml',
- ));
+ $request = new HTTP\Request('POST', '/calendars/user1/cal1', ['Content-Type' => 'text/xml']);
$xml = <<<RRR
<?xml version="1.0"?>
@@ -184,19 +189,28 @@ RRR;
$request->setBody($xml);
- $response = $this->request($request);
- $this->assertEquals(200, $response->status, $response->body);
+ $response = $this->request($request, 200);
+
+ $this->assertEquals(
+ [
+ new Sharee([
+ 'href' => 'mailto:joe@example.org',
+ 'properties' => [
+ '{DAV:}displayname' => 'Joe Shmoe',
+ ],
+ 'access' => \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE,
+ 'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE,
+ 'comment' => '',
+ ]),
+ ],
+ $this->caldavBackend->getInvites(1)
+ );
- $this->assertEquals(array(array(
- 'href' => 'mailto:joe@example.org',
- 'commonName' => 'Joe Shmoe',
- 'readOnly' => false,
- 'status' => SharingPlugin::STATUS_NORESPONSE,
- 'summary' => '',
- )), $this->caldavBackend->getShares(1));
+ // Wiping out tree cache
+ $this->server->tree->markDirty('');
// Verifying that the calendar is now marked shared.
- $props = $this->server->getProperties('calendars/user1/cal1', array('{DAV:}resourcetype'));
+ $props = $this->server->getProperties('calendars/user1/cal1', ['{DAV:}resourcetype']);
$this->assertTrue(
$props['{DAV:}resourcetype']->is('{http://calendarserver.org/ns/}shared-owner')
);
@@ -205,11 +219,11 @@ RRR;
function testShareRequestNoShareableCalendar() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal2',
- 'CONTENT_TYPE' => 'text/xml',
- ));
+ $request = new HTTP\Request(
+ 'POST',
+ '/calendars/user1/cal2',
+ ['Content-Type' => 'text/xml']
+ );
$xml = '<?xml version="1.0"?>
<cs:share xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
@@ -226,18 +240,17 @@ RRR;
$request->setBody($xml);
- $response = $this->request($request);
- $this->assertEquals(501, $response->status, $response->body);
+ $response = $this->request($request, 403);
}
function testInviteReply() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1',
'CONTENT_TYPE' => 'text/xml',
- ));
+ ]);
$xml = '<?xml version="1.0"?>
<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
@@ -254,11 +267,11 @@ RRR;
function testInviteBadXML() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1',
'CONTENT_TYPE' => 'text/xml',
- ));
+ ]);
$xml = '<?xml version="1.0"?>
<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
@@ -272,11 +285,11 @@ RRR;
function testInviteWrongUrl() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'POST',
'REQUEST_URI' => '/calendars/user1/cal1',
'CONTENT_TYPE' => 'text/xml',
- ));
+ ]);
$xml = '<?xml version="1.0"?>
<cs:invite-reply xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:">
@@ -295,11 +308,7 @@ RRR;
function testPublish() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal1',
- 'CONTENT_TYPE' => 'text/xml',
- ));
+ $request = new HTTP\Request('POST', '/calendars/user1/cal1', ['Content-Type' => 'text/xml']);
$xml = '<?xml version="1.0"?>
<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
@@ -312,13 +321,14 @@ RRR;
}
+
function testUnpublish() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal1',
- 'CONTENT_TYPE' => 'text/xml',
- ));
+ $request = new HTTP\Request(
+ 'POST',
+ '/calendars/user1/cal1',
+ ['Content-Type' => 'text/xml']
+ );
$xml = '<?xml version="1.0"?>
<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
@@ -333,49 +343,46 @@ RRR;
function testPublishWrongUrl() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal2',
- 'CONTENT_TYPE' => 'text/xml',
- ));
+ $request = new HTTP\Request(
+ 'POST',
+ '/calendars/user1',
+ ['Content-Type' => 'text/xml']
+ );
$xml = '<?xml version="1.0"?>
<cs:publish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
';
$request->setBody($xml);
-
- $response = $this->request($request);
- $this->assertEquals(501, $response->status, $response->body);
+ $this->request($request, 501);
}
function testUnpublishWrongUrl() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal2',
- 'CONTENT_TYPE' => 'text/xml',
- ));
-
+ $request = new HTTP\Request(
+ 'POST',
+ '/calendars/user1',
+ ['Content-Type' => 'text/xml']
+ );
$xml = '<?xml version="1.0"?>
<cs:unpublish-calendar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />
';
$request->setBody($xml);
- $response = $this->request($request);
- $this->assertEquals(501, $response->status, $response->body);
+ $this->request($request, 501);
}
function testUnknownXmlDoc() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'POST',
- 'REQUEST_URI' => '/calendars/user1/cal2',
- 'CONTENT_TYPE' => 'text/xml',
- ));
+
+ $request = new HTTP\Request(
+ 'POST',
+ '/calendars/user1/cal2',
+ ['Content-Type' => 'text/xml']
+ );
$xml = '<?xml version="1.0"?>
<cs:foo-bar xmlns:cs="' . Plugin::NS_CALENDARSERVER . '" xmlns:d="DAV:" />';
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
index 19acea200..673d39c0a 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/TestUtil.php
@@ -6,48 +6,29 @@ class TestUtil {
static function getBackend() {
- $backend = new Backend\PDO(self::getSQLiteDB());
- return $backend;
-
- }
-
- static function getSQLiteDB() {
-
- if (file_exists(SABRE_TEMPDIR . '/testdb.sqlite'))
- unlink(SABRE_TEMPDIR . '/testdb.sqlite');
-
- $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/testdb.sqlite');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
-
- // Yup this is definitely not 'fool proof', but good enough for now.
- $queries = explode(';', file_get_contents(__DIR__ . '/../../../examples/sql/sqlite.calendars.sql'));
- foreach($queries as $query) {
- $pdo->exec($query);
- }
- // Inserting events through a backend class.
- $backend = new Backend\PDO($pdo);
+ $backend = new Backend\Mock();
$calendarId = $backend->createCalendar(
'principals/user1',
'UUID-123467',
- array(
- '{DAV:}displayname' => 'user1 calendar',
+ [
+ '{DAV:}displayname' => 'user1 calendar',
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
- '{http://apple.com/ns/ical/}calendar-order' => '1',
- '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
- )
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ ]
);
$backend->createCalendar(
'principals/user1',
'UUID-123468',
- array(
- '{DAV:}displayname' => 'user1 calendar2',
+ [
+ '{DAV:}displayname' => 'user1 calendar2',
'{urn:ietf:params:xml:ns:caldav}calendar-description' => 'Calendar description',
- '{http://apple.com/ns/ical/}calendar-order' => '1',
- '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
- )
+ '{http://apple.com/ns/ical/}calendar-order' => '1',
+ '{http://apple.com/ns/ical/}calendar-color' => '#FF0000',
+ ]
);
$backend->createCalendarObject($calendarId, 'UUID-2345', self::getTestCalendarData());
- return $pdo;
+ return $backend;
}
@@ -80,37 +61,37 @@ TRANSP:TRANSPARENT
SUMMARY:Something here
DTSTAMP:20100228T130202Z';
- switch($type) {
+ switch ($type) {
case 1 :
- $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDTEND;TZID=Asia/Seoul:20100223T070000\n";
+ $calendarData .= "\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDTEND;TZID=Asia/Seoul:20100223T070000\n";
break;
case 2 :
- $calendarData.="\nDTSTART:20100223T060000\nDTEND:20100223T070000\n";
+ $calendarData .= "\nDTSTART:20100223T060000\nDTEND:20100223T070000\n";
break;
case 3 :
- $calendarData.="\nDTSTART;VALUE=DATE:20100223\nDTEND;VALUE=DATE:20100223\n";
+ $calendarData .= "\nDTSTART;VALUE=DATE:20100223\nDTEND;VALUE=DATE:20100223\n";
break;
case 4 :
- $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:PT1H\n";
+ $calendarData .= "\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:PT1H\n";
break;
case 5 :
- $calendarData.="\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:-P5D\n";
+ $calendarData .= "\nDTSTART;TZID=Asia/Seoul:20100223T060000\nDURATION:-P5D\n";
break;
case 6 :
- $calendarData.="\nDTSTART;VALUE=DATE:20100223\n";
+ $calendarData .= "\nDTSTART;VALUE=DATE:20100223\n";
break;
case 7 :
- $calendarData.="\nDTSTART;VALUE=DATETIME:20100223T060000\n";
+ $calendarData .= "\nDTSTART;VALUE=DATETIME:20100223T060000\n";
break;
// No DTSTART, so intentionally broken
case 'X' :
- $calendarData.="\n";
+ $calendarData .= "\n";
break;
}
- $calendarData.='ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
+ $calendarData .= 'ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:lisa@example.com
SEQUENCE:2
END:VEVENT
END:VCALENDAR';
@@ -121,7 +102,7 @@ END:VCALENDAR';
static function getTestTODO($type = 'due') {
- switch($type) {
+ switch ($type) {
case 'due' :
$extra = "DUE:20100104T000000Z";
diff --git a/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
index be166d9e6..629df90c1 100644
--- a/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CalDAV/ValidateICalTest.php
@@ -21,20 +21,20 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
function setUp() {
- $calendars = array(
- array(
- 'id' => 'calendar1',
- 'principaluri' => 'principals/admin',
- 'uri' => 'calendar1',
- '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet( ['VEVENT','VTODO','VJOURNAL'] ),
- ),
- array(
- 'id' => 'calendar2',
- 'principaluri' => 'principals/admin',
- 'uri' => 'calendar2',
- '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet( ['VTODO','VJOURNAL'] ),
- )
- );
+ $calendars = [
+ [
+ 'id' => 'calendar1',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'calendar1',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VEVENT', 'VTODO', 'VJOURNAL']),
+ ],
+ [
+ 'id' => 'calendar2',
+ 'principaluri' => 'principals/admin',
+ 'uri' => 'calendar2',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set' => new Xml\Property\SupportedCalendarComponentSet(['VTODO', 'VJOURNAL']),
+ ]
+ ];
$this->calBackend = new Backend\Mock($calendars, []);
$principalBackend = new DAVACL\PrincipalBackend\Mock();
@@ -66,10 +66,10 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
function testCreateFile() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$response = $this->request($request);
@@ -79,66 +79,168 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
function testCreateFileValid() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
- $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $request = new HTTP\Request(
+ 'PUT',
+ '/calendars/admin/calendar1/blabla.ics',
+ ['Prefer' => 'handling=strict']
+ );
+
+ $ics = <<<ICS
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:foo
+BEGIN:VEVENT
+UID:foo
+DTSTAMP:20160406T052348Z
+DTSTART:20160706T140000Z
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $request->setBody($ics);
$response = $this->request($request);
$this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n") . '"'],
- ), $response->getHeaders());
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5($ics) . '"'],
+ ], $response->getHeaders());
- $expected = array(
+ $expected = [
'uri' => 'blabla.ics',
- 'calendardata' => "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ 'calendardata' => $ics,
'calendarid' => 'calendar1',
'lastmodified' => null,
+ ];
+
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1', 'blabla.ics'));
+
+ }
+
+ function testCreateFileNoVersion() {
+
+ $request = new HTTP\Request(
+ 'PUT',
+ '/calendars/admin/calendar1/blabla.ics',
+ ['Prefer' => 'handling=strict']
);
- $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
+ $ics = <<<ICS
+BEGIN:VCALENDAR
+PRODID:foo
+BEGIN:VEVENT
+UID:foo
+DTSTAMP:20160406T052348Z
+DTSTART:20160706T140000Z
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $request->setBody($ics);
+
+ $response = $this->request($request);
+
+ $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
}
- function testCreateFileNoComponents() {
+ function testCreateFileNoVersionFixed() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
- $request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n");
+ $request = new HTTP\Request(
+ 'PUT',
+ '/calendars/admin/calendar1/blabla.ics',
+ ['Prefer' => 'handling=lenient']
+ );
+
+ $ics = <<<ICS
+BEGIN:VCALENDAR
+PRODID:foo
+BEGIN:VEVENT
+UID:foo
+DTSTAMP:20160406T052348Z
+DTSTART:20160706T140000Z
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $request->setBody($ics);
$response = $this->request($request);
- $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $this->assertEquals([
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ 'Content-Length' => ['0'],
+ 'X-Sabre-Ew-Gross' => ['iCalendar validation warning: VERSION MUST appear exactly once in a VCALENDAR component'],
+ ], $response->getHeaders());
+
+ $ics = <<<ICS
+BEGIN:VCALENDAR\r
+VERSION:2.0\r
+PRODID:foo\r
+BEGIN:VEVENT\r
+UID:foo\r
+DTSTAMP:20160406T052348Z\r
+DTSTART:20160706T140000Z\r
+END:VEVENT\r
+END:VCALENDAR\r
+
+ICS;
+
+ $expected = [
+ 'uri' => 'blabla.ics',
+ 'calendardata' => $ics,
+ 'calendarid' => 'calendar1',
+ 'lastmodified' => null,
+ ];
+
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1', 'blabla.ics'));
+
+ }
+
+ function testCreateFileNoComponents() {
+
+ $request = new HTTP\Request(
+ 'PUT',
+ '/calendars/admin/calendar1/blabla.ics',
+ ['Prefer' => 'handling=strict']
+ );
+ $ics = <<<ICS
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:foo
+END:VCALENDAR
+ICS;
+
+ $request->setBody($ics);
+
+ $response = $this->request($request);
+ $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
}
function testCreateFileNoUID() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
- $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
}
function testCreateFileVCard() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n");
$response = $this->request($request);
@@ -149,53 +251,53 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
function testCreateFile2Components() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VJOURNAL\r\nUID:foo\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
- $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
}
function testCreateFile2UIDS() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nBEGIN:VEVENT\r\nUID:bar\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
- $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $this->assertEquals(415, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
}
function testCreateFileWrongComponent() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VFREEBUSY\r\nUID:foo\r\nEND:VFREEBUSY\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
- $this->assertEquals(400, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $this->assertEquals(403, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
}
function testUpdateFile() {
- $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
- $request = HTTP\Sapi::createFromServerArray(array(
+ $this->calBackend->createCalendarObject('calendar1', 'blabla.ics', 'foo');
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
+ ]);
$response = $this->request($request);
@@ -205,35 +307,45 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
function testUpdateFileParsableBody() {
- $this->calBackend->createCalendarObject('calendar1','blabla.ics','foo');
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
- $body = "BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
- $request->setBody($body);
-
+ $this->calBackend->createCalendarObject('calendar1', 'blabla.ics', 'foo');
+ $request = new HTTP\Request(
+ 'PUT',
+ '/calendars/admin/calendar1/blabla.ics'
+ );
+ $ics = <<<ICS
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:foo
+BEGIN:VEVENT
+UID:foo
+DTSTAMP:20160406T052348Z
+DTSTART:20160706T140000Z
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $request->setBody($ics);
$response = $this->request($request);
$this->assertEquals(204, $response->status);
- $expected = array(
+ $expected = [
'uri' => 'blabla.ics',
- 'calendardata' => $body,
+ 'calendardata' => $ics,
'calendarid' => 'calendar1',
'lastmodified' => null,
- );
+ ];
- $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1','blabla.ics'));
+ $this->assertEquals($expected, $this->calBackend->getCalendarObject('calendar1', 'blabla.ics'));
}
function testCreateFileInvalidComponent() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
@@ -244,11 +356,11 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
function testUpdateFileInvalidComponent() {
- $this->calBackend->createCalendarObject('calendar2','blabla.ics','foo');
- $request = HTTP\Sapi::createFromServerArray(array(
+ $this->calBackend->createCalendarObject('calendar2', 'blabla.ics', 'foo');
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
- ));
+ 'REQUEST_URI' => '/calendars/admin/calendar2/blabla.ics',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nUID:foo\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
@@ -266,11 +378,24 @@ class ValidateICalTest extends \PHPUnit_Framework_TestCase {
*/
function testCreateFileModified() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/calendars/admin/calendar1/blabla.ics',
- ));
- $request->setBody("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nUID:foo\r\nSUMMARY:Meeting in M\xfcnster\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
+ $request = new HTTP\Request(
+ 'PUT',
+ '/calendars/admin/calendar1/blabla.ics'
+ );
+ $ics = <<<ICS
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:foo
+BEGIN:VEVENT
+UID:foo
+SUMMARY:Meeting in M\xfcnster
+DTSTAMP:20160406T052348Z
+DTSTART:20160706T140000Z
+END:VEVENT
+END:VCALENDAR
+ICS;
+
+ $request->setBody($ics);
$response = $this->request($request);
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php
index a123099a0..552e2ba77 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AbstractPluginTest.php
@@ -26,13 +26,13 @@ abstract class AbstractPluginTest extends \PHPUnit_Framework_TestCase {
$this->backend = new Backend\Mock();
$principalBackend = new DAVACL\PrincipalBackend\Mock();
- $tree = array(
+ $tree = [
new AddressBookRoot($principalBackend, $this->backend),
new DAVACL\PrincipalCollection($principalBackend)
- );
+ ];
$this->plugin = new Plugin();
- $this->plugin->directories = array('directory');
+ $this->plugin->directories = ['directory'];
$this->server = new DAV\Server($tree);
$this->server->sapi = new HTTP\SapiMock();
$this->server->addPlugin($this->plugin);
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php
index 478f6beb5..2c3171bf3 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookQueryTest.php
@@ -12,11 +12,11 @@ class AddressBookQueryTest extends AbstractPluginTest {
function testQuery() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
- 'REQUEST_URI' => '/addressbooks/user1/book1',
- 'HTTP_DEPTH' => '1',
- ));
+ $request = new HTTP\Request(
+ 'REPORT',
+ '/addressbooks/user1/book1',
+ ['Depth' => '1']
+ );
$request->setBody(
'<?xml version="1.0"?>
@@ -40,33 +40,33 @@ class AddressBookQueryTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
'{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
- ),
- ),
- '/addressbooks/user1/book1/card2' => array(
- 404 => array(
+ ],
+ ],
+ '/addressbooks/user1/book1/card2' => [
+ 404 => [
'{DAV:}getetag' => null,
- ),
- )
- ), $result);
+ ],
+ ]
+ ], $result);
}
function testQueryDepth0() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
- 'REQUEST_URI' => '/addressbooks/user1/book1/card1',
- 'HTTP_DEPTH' => '0',
- ));
+ $request = new HTTP\Request(
+ 'REPORT',
+ '/addressbooks/user1/book1/card1',
+ ['Depth' => '0']
+ );
$request->setBody(
'<?xml version="1.0"?>
@@ -90,28 +90,28 @@ class AddressBookQueryTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
'{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
- ),
- ),
- ), $result);
+ ],
+ ],
+ ], $result);
}
function testQueryNoMatch() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'REPORT',
- 'REQUEST_URI' => '/addressbooks/user1/book1',
- 'HTTP_DEPTH' => '1',
- ));
+ $request = new HTTP\Request(
+ 'REPORT',
+ '/addressbooks/user1/book1',
+ ['Depth' => '1']
+ );
$request->setBody(
'<?xml version="1.0"?>
@@ -135,21 +135,21 @@ class AddressBookQueryTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
- $this->assertEquals(array(), $result);
+ $this->assertEquals([], $result);
}
function testQueryLimit() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
- 'REQUEST_URI' => '/addressbooks/user1/book1',
- 'HTTP_DEPTH' => '1',
- ));
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ 'HTTP_DEPTH' => '1',
+ ]);
$request->setBody(
'<?xml version="1.0"?>
@@ -174,17 +174,17 @@ class AddressBookQueryTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
- '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD"). '"',
- ),
- ),
- ), $result);
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
+ ],
+ ],
+ ], $result);
}
@@ -217,20 +217,20 @@ class AddressBookQueryTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
$vobjVersion = \Sabre\VObject\Version::VERSION;
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
- '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD"). '"',
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
'{urn:ietf:params:xml:ns:carddav}address-data' => '["vcard",[["version",{},"text","4.0"],["prodid",{},"text","-\/\/Sabre\/\/Sabre VObject ' . $vobjVersion . '\/\/EN"],["uid",{},"text","12345"]]]',
- ),
- ),
- ), $result);
+ ],
+ ],
+ ], $result);
}
@@ -262,20 +262,20 @@ class AddressBookQueryTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
$vobjVersion = \Sabre\VObject\Version::VERSION;
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
- '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD"). '"',
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
'{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:4.0\r\nPRODID:-//Sabre//Sabre VObject $vobjVersion//EN\r\nUID:12345\r\nEND:VCARD\r\n",
- ),
- ),
- ), $result);
+ ],
+ ],
+ ], $result);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php
index fe8ba9025..1a36fd10c 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/AddressBookTest.php
@@ -4,10 +4,10 @@ namespace Sabre\CardDAV;
use Sabre\DAV\PropPatch;
-require_once 'Sabre/CardDAV/Backend/Mock.php';
-
class AddressBookTest extends \PHPUnit_Framework_TestCase {
+ use \Sabre\DAV\DbTestHelperTrait;
+
/**
* @var Sabre\CardDAV\AddressBook
*/
@@ -19,12 +19,12 @@ class AddressBookTest extends \PHPUnit_Framework_TestCase {
$this->backend = new Backend\Mock();
$this->ab = new AddressBook(
$this->backend,
- array(
- 'uri' => 'book1',
- 'id' => 'foo',
+ [
+ 'uri' => 'book1',
+ 'id' => 'foo',
'{DAV:}displayname' => 'd-name',
- 'principaluri' => 'principals/user1',
- )
+ 'principaluri' => 'principals/user1',
+ ]
);
}
@@ -73,10 +73,10 @@ class AddressBookTest extends \PHPUnit_Framework_TestCase {
function testCreateFile() {
- $file = fopen('php://memory','r+');
- fwrite($file,'foo');
+ $file = fopen('php://memory', 'r+');
+ fwrite($file, 'foo');
rewind($file);
- $this->ab->createFile('card2',$file);
+ $this->ab->createFile('card2', $file);
$this->assertEquals('foo', $this->backend->cards['foo']['card2']);
@@ -85,7 +85,7 @@ class AddressBookTest extends \PHPUnit_Framework_TestCase {
function testDelete() {
$this->ab->delete();
- $this->assertEquals(array(), $this->backend->addressBooks);
+ $this->assertEquals([], $this->backend->addressBooks);
}
@@ -118,10 +118,10 @@ class AddressBookTest extends \PHPUnit_Framework_TestCase {
function testGetProperties() {
- $props = $this->ab->getProperties(array('{DAV:}displayname'));
- $this->assertEquals(array(
+ $props = $this->ab->getProperties(['{DAV:}displayname']);
+ $this->assertEquals([
'{DAV:}displayname' => 'd-name',
- ), $props);
+ ], $props);
}
@@ -129,27 +129,22 @@ class AddressBookTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals('principals/user1', $this->ab->getOwner());
$this->assertNull($this->ab->getGroup());
- $this->assertEquals(array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/user1',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
- 'principal' => 'principals/user1',
+ $this->assertEquals([
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
- ),
- ), $this->ab->getACL());
+ ],
+ ], $this->ab->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @expectedException Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
- $this->ab->setACL(array());
+ $this->ab->setACL([]);
}
@@ -168,45 +163,32 @@ class AddressBookTest extends \PHPUnit_Framework_TestCase {
}
function testGetChangesNoSyncSupport() {
- $this->assertNull($this->ab->getChanges(1,null));
+ $this->assertNull($this->ab->getChanges(1, null));
}
function testGetSyncToken() {
- if (!SABRE_HASSQLITE) {
- $this->markTestSkipped('Sqlite is required for this test to run');
- }
- $ab = new AddressBook(TestUtil::getBackend(), [ 'id' => 1, '{DAV:}sync-token' => 2]);
+ $this->driver = 'sqlite';
+ $this->dropTables(['addressbooks', 'cards', 'addressbookchanges']);
+ $this->createSchema('addressbooks');
+ $backend = new Backend\PDO(
+ $this->getPDO()
+ );
+ $ab = new AddressBook($backend, [ 'id' => 1, '{DAV:}sync-token' => 2]);
$this->assertEquals(2, $ab->getSyncToken());
- TestUtil::deleteSQLiteDB();
}
function testGetSyncToken2() {
- if (!SABRE_HASSQLITE) {
- $this->markTestSkipped('Sqlite is required for this test to run');
- }
- $ab = new AddressBook(TestUtil::getBackend(), [ 'id' => 1, '{http://sabredav.org/ns}sync-token' => 2]);
+ $this->driver = 'sqlite';
+ $this->dropTables(['addressbooks', 'cards', 'addressbookchanges']);
+ $this->createSchema('addressbooks');
+ $backend = new Backend\PDO(
+ $this->getPDO()
+ );
+ $ab = new AddressBook($backend, [ 'id' => 1, '{http://sabredav.org/ns}sync-token' => 2]);
$this->assertEquals(2, $ab->getSyncToken());
- TestUtil::deleteSQLiteDB();
}
- function testGetChanges() {
-
- if (!SABRE_HASSQLITE) {
- $this->markTestSkipped('Sqlite is required for this test to run');
- }
- $ab = new AddressBook(TestUtil::getBackend(), [ 'id' => 1, '{DAV:}sync-token' => 2]);
- $this->assertEquals([
- 'syncToken' => 2,
- 'modified' => [],
- 'deleted' => [],
- 'added' => ['UUID-2345'],
- ], $ab->getChanges(1, 1));
- TestUtil::deleteSQLiteDB();
-
- }
-
-
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php
index d2ec278be..f62bfb1ae 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/AbstractPDOTest.php
@@ -7,52 +7,55 @@ use Sabre\DAV\PropPatch;
abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
+ use \Sabre\DAV\DbTestHelperTrait;
+
/**
* @var CardDAV\Backend\PDO
*/
protected $backend;
- /**
- * @abstract
- * @return PDO
- */
- abstract function getPDO();
-
- public function setUp() {
+ function setUp() {
+ $this->dropTables([
+ 'addressbooks',
+ 'cards',
+ 'addressbookchanges',
+ ]);
+ $this->createSchema('addressbooks');
$pdo = $this->getPDO();
+
$this->backend = new PDO($pdo);
- $pdo->exec('INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) VALUES ("principals/user1", "book1", "book1", "addressbook 1", 1)');
- $pdo->exec('INSERT INTO cards (addressbookid, carddata, uri, lastmodified, etag, size) VALUES (1, "card1", "card1", 0, "' . md5('card1') . '", 5)');
+ $pdo->exec("INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) VALUES ('principals/user1', 'book1', 'book1', 'addressbook 1', 1)");
+ $pdo->exec("INSERT INTO cards (addressbookid, carddata, uri, lastmodified, etag, size) VALUES (1, 'card1', 'card1', 0, '" . md5('card1') . "', 5)");
}
- public function testGetAddressBooksForUser() {
+ function testGetAddressBooksForUser() {
$result = $this->backend->getAddressBooksForUser('principals/user1');
- $expected = array(
- array(
- 'id' => 1,
- 'uri' => 'book1',
- 'principaluri' => 'principals/user1',
- '{DAV:}displayname' => 'book1',
+ $expected = [
+ [
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
- '{http://calendarserver.org/ns/}getctag' => 1,
- '{http://sabredav.org/ns}sync-token' => 1
- )
- );
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{http://sabredav.org/ns}sync-token' => 1
+ ]
+ ];
$this->assertEquals($expected, $result);
}
- public function testUpdateAddressBookInvalidProp() {
+ function testUpdateAddressBookInvalidProp() {
$propPatch = new PropPatch([
- '{DAV:}displayname' => 'updated',
+ '{DAV:}displayname' => 'updated',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
- '{DAV:}foo' => 'bar',
+ '{DAV:}foo' => 'bar',
]);
$this->backend->updateAddressBook(1, $propPatch);
@@ -62,23 +65,23 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$result = $this->backend->getAddressBooksForUser('principals/user1');
- $expected = array(
- array(
- 'id' => 1,
- 'uri' => 'book1',
- 'principaluri' => 'principals/user1',
- '{DAV:}displayname' => 'book1',
+ $expected = [
+ [
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
- '{http://calendarserver.org/ns/}getctag' => 1,
- '{http://sabredav.org/ns}sync-token' => 1
- )
- );
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{http://sabredav.org/ns}sync-token' => 1
+ ]
+ ];
$this->assertEquals($expected, $result);
}
- public function testUpdateAddressBookNoProps() {
+ function testUpdateAddressBookNoProps() {
$propPatch = new PropPatch([
]);
@@ -89,27 +92,27 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$result = $this->backend->getAddressBooksForUser('principals/user1');
- $expected = array(
- array(
- 'id' => 1,
- 'uri' => 'book1',
- 'principaluri' => 'principals/user1',
- '{DAV:}displayname' => 'book1',
+ $expected = [
+ [
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
- '{http://calendarserver.org/ns/}getctag' => 1,
- '{http://sabredav.org/ns}sync-token' => 1
- )
- );
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{http://sabredav.org/ns}sync-token' => 1
+ ]
+ ];
$this->assertEquals($expected, $result);
}
- public function testUpdateAddressBookSuccess() {
+ function testUpdateAddressBookSuccess() {
$propPatch = new PropPatch([
- '{DAV:}displayname' => 'updated',
+ '{DAV:}displayname' => 'updated',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
]);
@@ -120,104 +123,108 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$result = $this->backend->getAddressBooksForUser('principals/user1');
- $expected = array(
- array(
- 'id' => 1,
- 'uri' => 'book1',
- 'principaluri' => 'principals/user1',
- '{DAV:}displayname' => 'updated',
+ $expected = [
+ [
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'updated',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'updated',
- '{http://calendarserver.org/ns/}getctag' => 2,
- '{http://sabredav.org/ns}sync-token' => 2
- )
- );
+ '{http://calendarserver.org/ns/}getctag' => 2,
+ '{http://sabredav.org/ns}sync-token' => 2
+ ]
+ ];
$this->assertEquals($expected, $result);
}
- public function testDeleteAddressBook() {
+ function testDeleteAddressBook() {
$this->backend->deleteAddressBook(1);
- $this->assertEquals(array(), $this->backend->getAddressBooksForUser('principals/user1'));
+ $this->assertEquals([], $this->backend->getAddressBooksForUser('principals/user1'));
}
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
- public function testCreateAddressBookUnsupportedProp() {
+ function testCreateAddressBookUnsupportedProp() {
- $this->backend->createAddressBook('principals/user1','book2', array(
+ $this->backend->createAddressBook('principals/user1', 'book2', [
'{DAV:}foo' => 'bar',
- ));
+ ]);
}
- public function testCreateAddressBookSuccess() {
+ function testCreateAddressBookSuccess() {
- $this->backend->createAddressBook('principals/user1','book2', array(
- '{DAV:}displayname' => 'book2',
+ $this->backend->createAddressBook('principals/user1', 'book2', [
+ '{DAV:}displayname' => 'book2',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2',
- ));
-
- $expected = array(
- array(
- 'id' => 1,
- 'uri' => 'book1',
- 'principaluri' => 'principals/user1',
- '{DAV:}displayname' => 'book1',
+ ]);
+
+ $expected = [
+ [
+ 'id' => 1,
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book1',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 1',
- '{http://calendarserver.org/ns/}getctag' => 1,
- '{http://sabredav.org/ns}sync-token' => 1,
- ),
- array(
- 'id' => 2,
- 'uri' => 'book2',
- 'principaluri' => 'principals/user1',
- '{DAV:}displayname' => 'book2',
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{http://sabredav.org/ns}sync-token' => 1,
+ ],
+ [
+ 'id' => 2,
+ 'uri' => 'book2',
+ 'principaluri' => 'principals/user1',
+ '{DAV:}displayname' => 'book2',
'{' . CardDAV\Plugin::NS_CARDDAV . '}addressbook-description' => 'addressbook 2',
- '{http://calendarserver.org/ns/}getctag' => 1,
- '{http://sabredav.org/ns}sync-token' => 1,
- )
- );
+ '{http://calendarserver.org/ns/}getctag' => 1,
+ '{http://sabredav.org/ns}sync-token' => 1,
+ ]
+ ];
$result = $this->backend->getAddressBooksForUser('principals/user1');
$this->assertEquals($expected, $result);
}
- public function testGetCards() {
+ function testGetCards() {
$result = $this->backend->getCards(1);
- $expected = array(
- array(
- 'id' => 1,
- 'uri' => 'card1',
+ $expected = [
+ [
+ 'id' => 1,
+ 'uri' => 'card1',
'lastmodified' => 0,
- 'etag' => '"' . md5('card1') . '"',
- 'size' => 5
- )
- );
+ 'etag' => '"' . md5('card1') . '"',
+ 'size' => 5
+ ]
+ ];
$this->assertEquals($expected, $result);
}
- public function testGetCard() {
+ function testGetCard() {
- $result = $this->backend->getCard(1,'card1');
+ $result = $this->backend->getCard(1, 'card1');
- $expected = array(
- 'id' => 1,
- 'uri' => 'card1',
- 'carddata' => 'card1',
+ $expected = [
+ 'id' => 1,
+ 'uri' => 'card1',
+ 'carddata' => 'card1',
'lastmodified' => 0,
- 'etag' => '"' . md5('card1') . '"',
- 'size' => 5
- );
+ 'etag' => '"' . md5('card1') . '"',
+ 'size' => 5
+ ];
+
+ if (is_resource($result['carddata'])) {
+ $result['carddata'] = stream_get_contents($result['carddata']);
+ }
$this->assertEquals($expected, $result);
@@ -226,13 +233,16 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
/**
* @depends testGetCard
*/
- public function testCreateCard() {
+ function testCreateCard() {
$result = $this->backend->createCard(1, 'card2', 'data2');
$this->assertEquals('"' . md5('data2') . '"', $result);
- $result = $this->backend->getCard(1,'card2');
+ $result = $this->backend->getCard(1, 'card2');
$this->assertEquals(2, $result['id']);
$this->assertEquals('card2', $result['uri']);
+ if (is_resource($result['carddata'])) {
+ $result['carddata'] = stream_get_contents($result['carddata']);
+ }
$this->assertEquals('data2', $result['carddata']);
}
@@ -240,41 +250,52 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
/**
* @depends testCreateCard
*/
- public function testGetMultiple() {
+ function testGetMultiple() {
$result = $this->backend->createCard(1, 'card2', 'data2');
$result = $this->backend->createCard(1, 'card3', 'data3');
$check = [
[
- 'id' => 1,
- 'uri' => 'card1',
- 'carddata' => 'card1',
+ 'id' => 1,
+ 'uri' => 'card1',
+ 'carddata' => 'card1',
'lastmodified' => 0,
],
[
- 'id' => 2,
- 'uri' => 'card2',
- 'carddata' => 'data2',
+ 'id' => 2,
+ 'uri' => 'card2',
+ 'carddata' => 'data2',
'lastmodified' => time(),
],
[
- 'id' => 3,
- 'uri' => 'card3',
- 'carddata' => 'data3',
+ 'id' => 3,
+ 'uri' => 'card3',
+ 'carddata' => 'data3',
'lastmodified' => time(),
],
];
- $result = $this->backend->getMultipleCards(1, ['card1','card2','card3']);
+ $result = $this->backend->getMultipleCards(1, ['card1', 'card2', 'card3']);
+
+ foreach ($check as $index => $node) {
- foreach($check as $index=>$node) {
+ foreach ($node as $k => $v) {
- foreach($node as $k=>$v) {
+ $expected = $v;
+ $actual = $result[$index][$k];
- if ($k!=='lastmodified') {
- $this->assertEquals($v, $result[$index][$k]);
- } else {
- $this->assertTrue(isset($result[$index][$k]));
+ switch ($k) {
+ case 'lastmodified' :
+ $this->assertInternalType('int', $actual);
+ break;
+ case 'carddata' :
+ if (is_resource($actual)) {
+ $actual = stream_get_contents($actual);
+ }
+ // No break intended.
+ default :
+ $this->assertEquals($expected, $actual);
+ break;
}
}
@@ -287,13 +308,16 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
/**
* @depends testGetCard
*/
- public function testUpdateCard() {
+ function testUpdateCard() {
$result = $this->backend->updateCard(1, 'card1', 'newdata');
$this->assertEquals('"' . md5('newdata') . '"', $result);
- $result = $this->backend->getCard(1,'card1');
+ $result = $this->backend->getCard(1, 'card1');
$this->assertEquals(1, $result['id']);
+ if (is_resource($result['carddata'])) {
+ $result['carddata'] = stream_get_contents($result['carddata']);
+ }
$this->assertEquals('newdata', $result['carddata']);
}
@@ -301,10 +325,10 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
/**
* @depends testGetCard
*/
- public function testDeleteCard() {
+ function testDeleteCard() {
$this->backend->deleteCard(1, 'card1');
- $result = $this->backend->getCard(1,'card1');
+ $result = $this->backend->getCard(1, 'card1');
$this->assertFalse($result);
}
@@ -347,4 +371,3 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
}
}
-
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php
index 3f96d3c5d..840b898e8 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/Mock.php
@@ -13,24 +13,24 @@ class Mock extends AbstractBackend {
$this->cards = $cards;
if (is_null($this->addressBooks)) {
- $this->addressBooks = array(
- array(
- 'id' => 'foo',
- 'uri' => 'book1',
- 'principaluri' => 'principals/user1',
+ $this->addressBooks = [
+ [
+ 'id' => 'foo',
+ 'uri' => 'book1',
+ 'principaluri' => 'principals/user1',
'{DAV:}displayname' => 'd-name',
- ),
- );
+ ],
+ ];
- $card2 = fopen('php://memory','r+');
- fwrite($card2,"BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD");
+ $card2 = fopen('php://memory', 'r+');
+ fwrite($card2, "BEGIN:VCARD\nVERSION:3.0\nUID:45678\nEND:VCARD");
rewind($card2);
- $this->cards = array(
- 'foo' => array(
+ $this->cards = [
+ 'foo' => [
'card1' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
'card2' => $card2,
- ),
- );
+ ],
+ ];
}
}
@@ -38,8 +38,8 @@ class Mock extends AbstractBackend {
function getAddressBooksForUser($principalUri) {
- $books = array();
- foreach($this->addressBooks as $book) {
+ $books = [];
+ foreach ($this->addressBooks as $book) {
if ($book['principaluri'] === $principalUri) {
$books[] = $book;
}
@@ -64,14 +64,14 @@ class Mock extends AbstractBackend {
* @param \Sabre\DAV\PropPatch $propPatch
* @return void
*/
- public function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) {
+ function updateAddressBook($addressBookId, \Sabre\DAV\PropPatch $propPatch) {
- foreach($this->addressBooks as &$book) {
+ foreach ($this->addressBooks as &$book) {
if ($book['id'] !== $addressBookId)
continue;
$propPatch->handleRemaining(function($mutations) use (&$book) {
- foreach($mutations as $key=>$value) {
+ foreach ($mutations as $key => $value) {
$book[$key] = $value;
}
return true;
@@ -83,17 +83,17 @@ class Mock extends AbstractBackend {
function createAddressBook($principalUri, $url, array $properties) {
- $this->addressBooks[] = array_merge($properties, array(
- 'id' => $url,
- 'uri' => $url,
+ $this->addressBooks[] = array_merge($properties, [
+ 'id' => $url,
+ 'uri' => $url,
'principaluri' => $principalUri,
- ));
+ ]);
}
function deleteAddressBook($addressBookId) {
- foreach($this->addressBooks as $key=>$value) {
+ foreach ($this->addressBooks as $key => $value) {
if ($value['id'] === $addressBookId)
unset($this->addressBooks[$key]);
}
@@ -101,41 +101,142 @@ class Mock extends AbstractBackend {
}
+ /**
+ * Returns all cards for a specific addressbook id.
+ *
+ * This method should return the following properties for each card:
+ * * carddata - raw vcard data
+ * * uri - Some unique url
+ * * lastmodified - A unix timestamp
+ *
+ * It's recommended to also return the following properties:
+ * * etag - A unique etag. This must change every time the card changes.
+ * * size - The size of the card in bytes.
+ *
+ * If these last two properties are provided, less time will be spent
+ * calculating them. If they are specified, you can also ommit carddata.
+ * This may speed up certain requests, especially with large cards.
+ *
+ * @param mixed $addressbookId
+ * @return array
+ */
function getCards($addressBookId) {
- $cards = array();
- foreach($this->cards[$addressBookId] as $uri=>$data) {
- $cards[] = array(
- 'uri' => $uri,
- 'carddata' => $data,
- );
+ $cards = [];
+ foreach ($this->cards[$addressBookId] as $uri => $data) {
+ if (is_resource($data)) {
+ $cards[] = [
+ 'uri' => $uri,
+ 'carddata' => $data,
+ ];
+ } else {
+ $cards[] = [
+ 'uri' => $uri,
+ 'carddata' => $data,
+ 'etag' => '"' . md5($data) . '"',
+ 'size' => strlen($data)
+ ];
+ }
}
return $cards;
}
+ /**
+ * Returns a specfic card.
+ *
+ * The same set of properties must be returned as with getCards. The only
+ * exception is that 'carddata' is absolutely required.
+ *
+ * If the card does not exist, you must return false.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @return array
+ */
function getCard($addressBookId, $cardUri) {
if (!isset($this->cards[$addressBookId][$cardUri])) {
return false;
}
- return array(
- 'uri' => $cardUri,
- 'carddata' => $this->cards[$addressBookId][$cardUri],
- );
+ $data = $this->cards[$addressBookId][$cardUri];
+ return [
+ 'uri' => $cardUri,
+ 'carddata' => $data,
+ 'etag' => '"' . md5($data) . '"',
+ 'size' => strlen($data)
+ ];
}
+ /**
+ * Creates a new card.
+ *
+ * The addressbook id will be passed as the first argument. This is the
+ * same id as it is returned from the getAddressBooksForUser method.
+ *
+ * The cardUri is a base uri, and doesn't include the full path. The
+ * cardData argument is the vcard body, and is passed as a string.
+ *
+ * It is possible to return an ETag from this method. This ETag is for the
+ * newly created resource, and must be enclosed with double quotes (that
+ * is, the string itself must contain the double quotes).
+ *
+ * You should only return the ETag if you store the carddata as-is. If a
+ * subsequent GET request on the same card does not have the same body,
+ * byte-by-byte and you did return an ETag here, clients tend to get
+ * confused.
+ *
+ * If you don't return an ETag, you can just return null.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ * @return string|null
+ */
function createCard($addressBookId, $cardUri, $cardData) {
+ if (is_resource($cardData)) {
+ $cardData = stream_get_contents($cardData);
+ }
$this->cards[$addressBookId][$cardUri] = $cardData;
+ return '"' . md5($cardData) . '"';
}
+ /**
+ * Updates a card.
+ *
+ * The addressbook id will be passed as the first argument. This is the
+ * same id as it is returned from the getAddressBooksForUser method.
+ *
+ * The cardUri is a base uri, and doesn't include the full path. The
+ * cardData argument is the vcard body, and is passed as a string.
+ *
+ * It is possible to return an ETag from this method. This ETag should
+ * match that of the updated resource, and must be enclosed with double
+ * quotes (that is: the string itself must contain the actual quotes).
+ *
+ * You should only return the ETag if you store the carddata as-is. If a
+ * subsequent GET request on the same card does not have the same body,
+ * byte-by-byte and you did return an ETag here, clients tend to get
+ * confused.
+ *
+ * If you don't return an ETag, you can just return null.
+ *
+ * @param mixed $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ * @return string|null
+ */
function updateCard($addressBookId, $cardUri, $cardData) {
+ if (is_resource($cardData)) {
+ $cardData = stream_get_contents($cardData);
+ }
$this->cards[$addressBookId][$cardUri] = $cardData;
+ return '"' . md5($cardData) . '"';
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php
index 38cb655d0..c1b0e274e 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOMySQLTest.php
@@ -2,35 +2,8 @@
namespace Sabre\CardDAV\Backend;
-require_once 'Sabre/TestUtil.php';
-
class PDOMySQLTest extends AbstractPDOTest {
- /**
- * @return PDO
- */
- public function getPDO() {
-
- if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
-
- $pdo = \Sabre\TestUtil::getMySQLDB();
- if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
-
- $pdo->query("DROP TABLE IF EXISTS addressbooks, cards, addressbookchanges");
-
- $queries = explode(
- ';',
- file_get_contents(__DIR__ . '/../../../../examples/sql/mysql.addressbook.sql')
- );
-
- foreach($queries as $query) {
- $query = trim($query," \r\n\t");
- if ($query)
- $pdo->exec($query);
- }
- return $pdo;
-
- }
+ public $driver = 'mysql';
}
-
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php
index 5a4a7a327..b187c4d78 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/Backend/PDOSqliteTest.php
@@ -2,53 +2,8 @@
namespace Sabre\CardDAV\Backend;
-require_once 'Sabre/TestUtil.php';
-
class PDOSqliteTest extends AbstractPDOTest {
- function tearDown() {
-
- if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend');
- if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2');
-
- }
-
- /**
- * @return PDO
- */
- function getPDO() {
-
- return self::getSQLite();
-
- }
-
- /**
- * @return PDO
- */
- static function getSQLite() {
-
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
- $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
-
- $pdo->query("DROP TABLE IF EXISTS addressbooks");
- $pdo->query("DROP TABLE IF EXISTS addressbookchanges");
- $pdo->query("DROP TABLE IF EXISTS cards");
-
- $queries = explode(
- ';',
- file_get_contents(__DIR__ . '/../../../../examples/sql/sqlite.addressbooks.sql')
- );
-
- foreach($queries as $query) {
- $query = trim($query," \r\n\t");
- if ($query)
- $pdo->exec($query);
- }
-
- return $pdo;
-
- }
+ public $driver = 'sqlite';
}
-
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php
index cf8dbab0c..cb7d152c3 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/CardTest.php
@@ -18,16 +18,16 @@ class CardTest extends \PHPUnit_Framework_TestCase {
$this->backend = new Backend\Mock();
$this->card = new Card(
$this->backend,
- array(
- 'uri' => 'book1',
- 'id' => 'foo',
+ [
+ 'uri' => 'book1',
+ 'id' => 'foo',
'principaluri' => 'principals/user1',
- ),
- array(
- 'uri' => 'card1',
+ ],
+ [
+ 'uri' => 'card1',
'addressbookid' => 'foo',
- 'carddata' => 'card',
- )
+ 'carddata' => 'card',
+ ]
);
}
@@ -42,15 +42,15 @@ class CardTest extends \PHPUnit_Framework_TestCase {
$this->card = new Card(
$this->backend,
- array(
- 'uri' => 'book1',
- 'id' => 'foo',
+ [
+ 'uri' => 'book1',
+ 'id' => 'foo',
'principaluri' => 'principals/user1',
- ),
- array(
- 'uri' => 'card1',
+ ],
+ [
+ 'uri' => 'card1',
'addressbookid' => 'foo',
- )
+ ]
);
$result = $this->card->get();
$this->assertEquals("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD", $result);
@@ -63,7 +63,7 @@ class CardTest extends \PHPUnit_Framework_TestCase {
*/
function testPut() {
- $file = fopen('php://memory','r+');
+ $file = fopen('php://memory', 'r+');
fwrite($file, 'newdata');
rewind($file);
$this->card->put($file);
@@ -88,7 +88,7 @@ class CardTest extends \PHPUnit_Framework_TestCase {
function testGetETag() {
- $this->assertEquals('"' . md5('card') . '"' , $this->card->getETag());
+ $this->assertEquals('"' . md5('card') . '"', $this->card->getETag());
}
@@ -96,19 +96,19 @@ class CardTest extends \PHPUnit_Framework_TestCase {
$card = new Card(
$this->backend,
- array(
- 'uri' => 'book1',
- 'id' => 'foo',
+ [
+ 'uri' => 'book1',
+ 'id' => 'foo',
'principaluri' => 'principals/user1',
- ),
- array(
- 'uri' => 'card1',
+ ],
+ [
+ 'uri' => 'card1',
'addressbookid' => 'foo',
- 'carddata' => 'card',
- 'etag' => '"blabla"',
- )
+ 'carddata' => 'card',
+ 'etag' => '"blabla"',
+ ]
);
- $this->assertEquals('"blabla"' , $card->getETag());
+ $this->assertEquals('"blabla"', $card->getETag());
}
@@ -129,17 +129,17 @@ class CardTest extends \PHPUnit_Framework_TestCase {
$card = new Card(
$this->backend,
- array(
- 'uri' => 'book1',
- 'id' => 'foo',
+ [
+ 'uri' => 'book1',
+ 'id' => 'foo',
'principaluri' => 'principals/user1',
- ),
- array(
- 'uri' => 'card1',
+ ],
+ [
+ 'uri' => 'card1',
'addressbookid' => 'foo',
- 'etag' => '"blabla"',
- 'size' => 4,
- )
+ 'etag' => '"blabla"',
+ 'size' => 4,
+ ]
);
$this->assertEquals(4, $card->getSize());
@@ -149,58 +149,53 @@ class CardTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals('principals/user1', $this->card->getOwner());
$this->assertNull($this->card->getGroup());
- $this->assertEquals(array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => 'principals/user1',
- 'protected' => true,
- ),
- array(
- 'privilege' => '{DAV:}write',
+ $this->assertEquals([
+ [
+ 'privilege' => '{DAV:}all',
'principal' => 'principals/user1',
'protected' => true,
- ),
- ), $this->card->getACL());
+ ],
+ ], $this->card->getACL());
}
function testOverrideACL() {
$card = new Card(
$this->backend,
- array(
- 'uri' => 'book1',
- 'id' => 'foo',
+ [
+ 'uri' => 'book1',
+ 'id' => 'foo',
'principaluri' => 'principals/user1',
- ),
- array(
- 'uri' => 'card1',
+ ],
+ [
+ 'uri' => 'card1',
'addressbookid' => 'foo',
- 'carddata' => 'card',
- 'acl' => array(
- array(
+ 'carddata' => 'card',
+ 'acl' => [
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
- ),
- ),
- )
+ ],
+ ],
+ ]
);
- $this->assertEquals(array(
- array(
+ $this->assertEquals([
+ [
'privilege' => '{DAV:}read',
'principal' => 'principals/user1',
'protected' => true,
- ),
- ), $card->getACL());
+ ],
+ ], $card->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @expectedException Sabre\DAV\Exception\Forbidden
*/
function testSetACL() {
- $this->card->setACL(array());
+ $this->card->setACL([]);
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php
index 431cd2524..4796a131f 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/IDirectoryTest.php
@@ -8,15 +8,15 @@ class IDirectoryTest extends \PHPUnit_Framework_TestCase {
function testResourceType() {
- $tree = array(
+ $tree = [
new DirectoryMock('directory')
- );
+ ];
$server = new DAV\Server($tree);
$plugin = new Plugin();
$server->addPlugin($plugin);
- $props = $server->getProperties('directory', array('{DAV:}resourcetype'));
+ $props = $server->getProperties('directory', ['{DAV:}resourcetype']);
$this->assertTrue($props['{DAV:}resourcetype']->is('{' . Plugin::NS_CARDDAV . '}directory'));
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php
index b0ee45880..d79239d0f 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/MultiGetTest.php
@@ -11,10 +11,10 @@ class MultiGetTest extends AbstractPluginTest {
function testMultiGet() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
- 'REQUEST_URI' => '/addressbooks/user1/book1',
- ));
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ ]);
$request->setBody(
'<?xml version="1.0"?>
@@ -37,27 +37,27 @@ class MultiGetTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
- '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
- '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:3.0\r\nUID:12345\r\nEND:VCARD\r\n",
- )
- )
- ), $result);
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
+ '{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
+ ]
+ ]
+ ], $result);
}
function testMultiGetVCard4() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'REPORT',
- 'REQUEST_URI' => '/addressbooks/user1/book1',
- ));
+ 'REQUEST_URI' => '/addressbooks/user1/book1',
+ ]);
$request->setBody(
'<?xml version="1.0"?>
@@ -80,20 +80,20 @@ class MultiGetTest extends AbstractPluginTest {
$this->assertEquals(207, $response->status, 'Incorrect status code. Full response body:' . $response->body);
// using the client for parsing
- $client = new DAV\Client(array('baseUri'=>'/'));
+ $client = new DAV\Client(['baseUri' => '/']);
$result = $client->parseMultiStatus($response->body);
$prodId = "PRODID:-//Sabre//Sabre VObject " . \Sabre\VObject\Version::VERSION . "//EN";
- $this->assertEquals(array(
- '/addressbooks/user1/book1/card1' => array(
- 200 => array(
- '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
+ $this->assertEquals([
+ '/addressbooks/user1/book1/card1' => [
+ 200 => [
+ '{DAV:}getetag' => '"' . md5("BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD") . '"',
'{urn:ietf:params:xml:ns:carddav}address-data' => "BEGIN:VCARD\r\nVERSION:4.0\r\n$prodId\r\nUID:12345\r\nEND:VCARD\r\n",
- )
- )
- ), $result);
+ ]
+ ]
+ ], $result);
}
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php
index 9c916350e..6962e7830 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/PluginTest.php
@@ -3,7 +3,6 @@
namespace Sabre\CardDAV;
use Sabre\DAV;
-use Sabre\DAV\Xml\Property\Href;
class PluginTest extends AbstractPluginTest {
@@ -18,23 +17,23 @@ class PluginTest extends AbstractPluginTest {
function testSupportedReportSet() {
- $this->assertEquals(array(
+ $this->assertEquals([
'{' . Plugin::NS_CARDDAV . '}addressbook-multiget',
'{' . Plugin::NS_CARDDAV . '}addressbook-query',
- ), $this->plugin->getSupportedReportSet('addressbooks/user1/book1'));
+ ], $this->plugin->getSupportedReportSet('addressbooks/user1/book1'));
}
function testSupportedReportSetEmpty() {
- $this->assertEquals(array(
- ), $this->plugin->getSupportedReportSet(''));
+ $this->assertEquals([
+ ], $this->plugin->getSupportedReportSet(''));
}
function testAddressBookHomeSet() {
- $result = $this->server->getProperties('principals/user1', array('{' . Plugin::NS_CARDDAV . '}addressbook-home-set'));
+ $result = $this->server->getProperties('principals/user1', ['{' . Plugin::NS_CARDDAV . '}addressbook-home-set']);
$this->assertEquals(1, count($result));
$this->assertTrue(isset($result['{' . Plugin::NS_CARDDAV . '}addressbook-home-set']));
@@ -44,11 +43,11 @@ class PluginTest extends AbstractPluginTest {
function testDirectoryGateway() {
- $result = $this->server->getProperties('principals/user1', array('{' . Plugin::NS_CARDDAV . '}directory-gateway'));
+ $result = $this->server->getProperties('principals/user1', ['{' . Plugin::NS_CARDDAV . '}directory-gateway']);
$this->assertEquals(1, count($result));
$this->assertTrue(isset($result['{' . Plugin::NS_CARDDAV . '}directory-gateway']));
- $this->assertEquals(array('directory'), $result['{' . Plugin::NS_CARDDAV . '}directory-gateway']->getHrefs());
+ $this->assertEquals(['directory'], $result['{' . Plugin::NS_CARDDAV . '}directory-gateway']->getHrefs());
}
@@ -64,7 +63,7 @@ class PluginTest extends AbstractPluginTest {
$r = $this->server->emit('onHTMLActionsPanel', [$this->server->tree->getNodeForPath('addressbooks/user1'), &$output]);
$this->assertFalse($r);
- $this->assertTrue(!!strpos($output,'Display name'));
+ $this->assertTrue(!!strpos($output, 'Display name'));
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php
index f828cc25b..0ba4fd669 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/SogoStripContentTypeTest.php
@@ -5,44 +5,44 @@ namespace Sabre\CardDAV;
use Sabre\HTTP;
use Sabre\DAV\PropFind;
-class SogoStripContentType extends \Sabre\DAVServerTest {
+class SogoStripContentTypeTest extends \Sabre\DAVServerTest {
protected $setupCardDAV = true;
- protected $carddavAddressBooks = array(
- array(
- 'id' => 1,
- 'uri' => 'book1',
+ protected $carddavAddressBooks = [
+ [
+ 'id' => 1,
+ 'uri' => 'book1',
'principaluri' => 'principals/user1',
- ),
- );
- protected $carddavCards = array(
- 1 => array(
+ ],
+ ];
+ protected $carddavCards = [
+ 1 => [
'card1.vcf' => "BEGIN:VCARD\nVERSION:3.0\nUID:12345\nEND:VCARD",
- ),
- );
+ ],
+ ];
function testDontStrip() {
- $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf',array('{DAV:}getcontenttype'));
- $this->assertEquals(array(
+ $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf', ['{DAV:}getcontenttype']);
+ $this->assertEquals([
'{DAV:}getcontenttype' => 'text/vcard; charset=utf-8'
- ), $result);
+ ], $result);
}
function testStrip() {
- $this->server->httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $this->server->httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1',
- ));
- $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf',array('{DAV:}getcontenttype'));
- $this->assertEquals(array(
+ ]);
+ $result = $this->server->getProperties('addressbooks/user1/book1/card1.vcf', ['{DAV:}getcontenttype']);
+ $this->assertEquals([
'{DAV:}getcontenttype' => 'text/x-vcard'
- ), $result);
+ ], $result);
}
function testDontTouchOtherMimeTypes() {
- $this->server->httpRequest = new HTTP\Request('GET','/addressbooks/user1/book1/card1.vcf', [
+ $this->server->httpRequest = new HTTP\Request('GET', '/addressbooks/user1/book1/card1.vcf', [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 Lightning/1.2.1',
]);
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php b/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php
index c9cc10d35..ec8a3501e 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/TestUtil.php
@@ -2,8 +2,6 @@
namespace Sabre\CardDAV;
-use PDO;
-
class TestUtil {
static function getBackend() {
@@ -22,18 +20,18 @@ class TestUtil {
$addressbookId = $backend->createAddressBook(
'principals/user1',
'UUID-123467',
- array(
- '{DAV:}displayname' => 'user1 addressbook',
+ [
+ '{DAV:}displayname' => 'user1 addressbook',
'{urn:ietf:params:xml:ns:carddav}addressbook-description' => 'AddressBook description',
- )
+ ]
);
$backend->createAddressBook(
'principals/user1',
'UUID-123468',
- array(
- '{DAV:}displayname' => 'user1 addressbook2',
+ [
+ '{DAV:}displayname' => 'user1 addressbook2',
'{urn:ietf:params:xml:ns:carddav}addressbook-description' => 'AddressBook description',
- )
+ ]
);
$backend->createCard($addressbookId, 'UUID-2345', self::getTestCardData());
return $pdo;
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php
index 71fde719d..82d82fadd 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/VCFExportTest.php
@@ -10,21 +10,21 @@ class VCFExportTest extends \Sabre\DAVServerTest {
protected $autoLogin = 'user1';
protected $setupACL = true;
- protected $carddavAddressBooks = array(
- array(
- 'id' => 'book1',
- 'uri' => 'book1',
+ protected $carddavAddressBooks = [
+ [
+ 'id' => 'book1',
+ 'uri' => 'book1',
'principaluri' => 'principals/user1',
- )
- );
- protected $carddavCards = array(
- 'book1' => array(
+ ]
+ ];
+ protected $carddavCards = [
+ 'book1' => [
"card1" => "BEGIN:VCARD\r\nFN:Person1\r\nEND:VCARD\r\n",
"card2" => "BEGIN:VCARD\r\nFN:Person2\r\nEND:VCARD",
"card3" => "BEGIN:VCARD\r\nFN:Person3\r\nEND:VCARD\r\n",
"card4" => "BEGIN:VCARD\nFN:Person4\nEND:VCARD\n",
- )
- );
+ ]
+ ];
function setUp() {
@@ -50,11 +50,11 @@ class VCFExportTest extends \Sabre\DAVServerTest {
function testExport() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_URI' => '/addressbooks/user1/book1?export',
- 'QUERY_STRING' => 'export',
+ $request = HTTP\Sapi::createFromServerArray([
+ 'REQUEST_URI' => '/addressbooks/user1/book1?export',
+ 'QUERY_STRING' => 'export',
'REQUEST_METHOD' => 'GET',
- ));
+ ]);
$response = $this->request($request);
$this->assertEquals(200, $response->status, $response->body);
@@ -73,7 +73,7 @@ FN:Person4
END:VCARD
";
// We actually expected windows line endings
- $expected = str_replace("\n","\r\n", $expected);
+ $expected = str_replace("\n", "\r\n", $expected);
$this->assertEquals($expected, $response->body);
@@ -89,4 +89,47 @@ END:VCARD
}
+ function testContentDisposition() {
+
+ $request = new HTTP\Request(
+ 'GET',
+ '/addressbooks/user1/book1?export'
+ );
+
+ $response = $this->request($request, 200);
+ $this->assertEquals('text/directory', $response->getHeader('Content-Type'));
+ $this->assertEquals(
+ 'attachment; filename="book1-' . date('Y-m-d') . '.vcf"',
+ $response->getHeader('Content-Disposition')
+ );
+
+ }
+
+ function testContentDispositionBadChars() {
+
+ $this->carddavBackend->createAddressBook(
+ 'principals/user1',
+ 'book-b_ad"(ch)ars',
+ []
+ );
+ $this->carddavBackend->createCard(
+ 'book-b_ad"(ch)ars',
+ 'card1',
+ "BEGIN:VCARD\r\nFN:Person1\r\nEND:VCARD\r\n"
+ );
+
+ $request = new HTTP\Request(
+ 'GET',
+ '/addressbooks/user1/book-b_ad"(ch)ars?export'
+ );
+
+ $response = $this->request($request, 200);
+ $this->assertEquals('text/directory', $response->getHeader('Content-Type'));
+ $this->assertEquals(
+ 'attachment; filename="book-b_adchars-' . date('Y-m-d') . '.vcf"',
+ $response->getHeader('Content-Disposition')
+ );
+
+ }
+
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php
index c87716c10..57ac21b4a 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateFilterTest.php
@@ -48,35 +48,35 @@ HELLO;
// Check if TITLE is defined
$filter1 =
- array('name' => 'title', 'is-not-defined' => false, 'param-filters' => array(), 'text-matches' => array());
+ ['name' => 'title', 'is-not-defined' => false, 'param-filters' => [], 'text-matches' => []];
// Check if FOO is defined
$filter2 =
- array('name' => 'foo', 'is-not-defined' => false, 'param-filters' => array(), 'text-matches' => array());
+ ['name' => 'foo', 'is-not-defined' => false, 'param-filters' => [], 'text-matches' => []];
// Check if TITLE is not defined
$filter3 =
- array('name' => 'title', 'is-not-defined' => true, 'param-filters' => array(), 'text-matches' => array());
+ ['name' => 'title', 'is-not-defined' => true, 'param-filters' => [], 'text-matches' => []];
// Check if FOO is not defined
$filter4 =
- array('name' => 'foo', 'is-not-defined' => true, 'param-filters' => array(), 'text-matches' => array());
+ ['name' => 'foo', 'is-not-defined' => true, 'param-filters' => [], 'text-matches' => []];
// Check if TEL[TYPE] is defined
$filter5 =
- array(
- 'name' => 'tel',
+ [
+ 'name' => 'tel',
'is-not-defined' => false,
- 'test' => 'anyof',
- 'param-filters' => array(
- array(
- 'name' => 'type',
+ 'test' => 'anyof',
+ 'param-filters' => [
+ [
+ 'name' => 'type',
'is-not-defined' => false,
- 'text-match' => null
- ),
- ),
- 'text-matches' => array(),
- );
+ 'text-match' => null
+ ],
+ ],
+ 'text-matches' => [],
+ ];
// Check if TEL[FOO] is defined
$filter6 = $filter5;
@@ -101,20 +101,20 @@ HELLO;
// Check if URL contains 'google'
$filter11 =
- array(
- 'name' => 'url',
+ [
+ 'name' => 'url',
'is-not-defined' => false,
- 'test' => 'anyof',
- 'param-filters' => array(),
- 'text-matches' => array(
- array(
- 'match-type' => 'contains',
- 'value' => 'google',
+ 'test' => 'anyof',
+ 'param-filters' => [],
+ 'text-matches' => [
+ [
+ 'match-type' => 'contains',
+ 'value' => 'google',
'negate-condition' => false,
- 'collation' => 'i;octet',
- ),
- ),
- );
+ 'collation' => 'i;octet',
+ ],
+ ],
+ ];
// Check if URL contains 'bing'
$filter12 = $filter11;
@@ -131,12 +131,12 @@ HELLO;
// Param filter with text
$filter15 = $filter5;
- $filter15['param-filters'][0]['text-match'] = array(
- 'match-type' => 'contains',
- 'value' => 'WORK',
- 'collation' => 'i;octet',
+ $filter15['param-filters'][0]['text-match'] = [
+ 'match-type' => 'contains',
+ 'value' => 'WORK',
+ 'collation' => 'i;octet',
'negate-condition' => false,
- );
+ ];
$filter16 = $filter15;
$filter16['param-filters'][0]['text-match']['negate-condition'] = true;
@@ -144,60 +144,60 @@ HELLO;
// Param filter + text filter
$filter17 = $filter5;
$filter17['test'] = 'anyof';
- $filter17['text-matches'][] = array(
- 'match-type' => 'contains',
- 'value' => '444',
- 'collation' => 'i;octet',
+ $filter17['text-matches'][] = [
+ 'match-type' => 'contains',
+ 'value' => '444',
+ 'collation' => 'i;octet',
'negate-condition' => false,
- );
+ ];
$filter18 = $filter17;
$filter18['text-matches'][0]['negate-condition'] = true;
$filter18['test'] = 'allof';
- return array(
+ return [
// Basic filters
- array($body1, array($filter1), 'anyof',true),
- array($body1, array($filter2), 'anyof',false),
- array($body1, array($filter3), 'anyof',false),
- array($body1, array($filter4), 'anyof',true),
+ [$body1, [$filter1], 'anyof',true],
+ [$body1, [$filter2], 'anyof',false],
+ [$body1, [$filter3], 'anyof',false],
+ [$body1, [$filter4], 'anyof',true],
// Combinations
- array($body1, array($filter1, $filter2), 'anyof',true),
- array($body1, array($filter1, $filter2), 'allof',false),
- array($body1, array($filter1, $filter4), 'anyof',true),
- array($body1, array($filter1, $filter4), 'allof',true),
- array($body1, array($filter2, $filter3), 'anyof',false),
- array($body1, array($filter2, $filter3), 'allof',false),
+ [$body1, [$filter1, $filter2], 'anyof',true],
+ [$body1, [$filter1, $filter2], 'allof',false],
+ [$body1, [$filter1, $filter4], 'anyof',true],
+ [$body1, [$filter1, $filter4], 'allof',true],
+ [$body1, [$filter2, $filter3], 'anyof',false],
+ [$body1, [$filter2, $filter3], 'allof',false],
// Basic parameters
- array($body1, array($filter5), 'anyof', true, 'TEL;TYPE is defined, so this should return true'),
- array($body1, array($filter6), 'anyof', false, 'TEL;FOO is not defined, so this should return false'),
+ [$body1, [$filter5], 'anyof', true, 'TEL;TYPE is defined, so this should return true'],
+ [$body1, [$filter6], 'anyof', false, 'TEL;FOO is not defined, so this should return false'],
- array($body1, array($filter7), 'anyof', false, 'TEL;TYPE is defined, so this should return false'),
- array($body1, array($filter8), 'anyof', true, 'TEL;TYPE is not defined, so this should return true'),
+ [$body1, [$filter7], 'anyof', false, 'TEL;TYPE is defined, so this should return false'],
+ [$body1, [$filter8], 'anyof', true, 'TEL;TYPE is not defined, so this should return true'],
// Combined parameters
- array($body1, array($filter9), 'anyof', true),
- array($body1, array($filter10), 'anyof', false),
+ [$body1, [$filter9], 'anyof', true],
+ [$body1, [$filter10], 'anyof', false],
// Text-filters
- array($body1, array($filter11), 'anyof', true),
- array($body1, array($filter12), 'anyof', false),
- array($body1, array($filter13), 'anyof', false),
- array($body1, array($filter14), 'anyof', true),
+ [$body1, [$filter11], 'anyof', true],
+ [$body1, [$filter12], 'anyof', false],
+ [$body1, [$filter13], 'anyof', false],
+ [$body1, [$filter14], 'anyof', true],
// Param filter with text-match
- array($body1, array($filter15), 'anyof', true),
- array($body1, array($filter16), 'anyof', false),
+ [$body1, [$filter15], 'anyof', true],
+ [$body1, [$filter16], 'anyof', false],
// Param filter + text filter
- array($body1, array($filter17), 'anyof', true),
- array($body1, array($filter18), 'anyof', false),
- array($body1, array($filter18), 'anyof', false),
- );
+ [$body1, [$filter17], 'anyof', true],
+ [$body1, [$filter18], 'anyof', false],
+ [$body1, [$filter18], 'anyof', false],
+ ];
}
diff --git a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php
index ad8495c13..dda8a0c37 100644
--- a/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php
+++ b/vendor/sabre/dav/tests/Sabre/CardDAV/ValidateVCardTest.php
@@ -15,20 +15,20 @@ class ValidateVCardTest extends \PHPUnit_Framework_TestCase {
function setUp() {
- $addressbooks = array(
- array(
- 'id' => 'addressbook1',
+ $addressbooks = [
+ [
+ 'id' => 'addressbook1',
'principaluri' => 'principals/admin',
- 'uri' => 'addressbook1',
- )
- );
+ 'uri' => 'addressbook1',
+ ]
+ ];
- $this->cardBackend = new Backend\Mock($addressbooks,array());
+ $this->cardBackend = new Backend\Mock($addressbooks, []);
$principalBackend = new DAVACL\PrincipalBackend\Mock();
- $tree = array(
+ $tree = [
new AddressBookRoot($principalBackend, $this->cardBackend),
- );
+ ];
$this->server = new DAV\Server($tree);
$this->server->sapi = new HTTP\SapiMock();
@@ -42,21 +42,36 @@ class ValidateVCardTest extends \PHPUnit_Framework_TestCase {
}
- function request(HTTP\Request $request) {
+ function request(HTTP\Request $request, $expectedStatus = null) {
$this->server->httpRequest = $request;
$this->server->exec();
+ if ($expectedStatus) {
+
+ $realStatus = $this->server->httpResponse->getStatus();
+
+ $msg = '';
+ if ($realStatus !== $expectedStatus) {
+ $msg = 'Response body: ' . $this->server->httpResponse->getBodyAsString();
+ }
+ $this->assertEquals(
+ $expectedStatus,
+ $realStatus,
+ $msg
+ );
+ }
+
return $this->server->httpResponse;
}
function testCreateFile() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
- ));
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ]);
$response = $this->request($request);
@@ -66,38 +81,159 @@ class ValidateVCardTest extends \PHPUnit_Framework_TestCase {
function testCreateFileValid() {
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
- ));
- $request->setBody("BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n");
-
- $response = $this->request($request);
+ $request = new HTTP\Request(
+ 'PUT',
+ '/addressbooks/admin/addressbook1/blabla.vcf'
+ );
- $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
- $expected = array(
- 'uri' => 'blabla.vcf',
- 'carddata' => "BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n",
+ $vcard = <<<VCF
+BEGIN:VCARD
+VERSION:4.0
+UID:foo
+FN:Firstname LastName
+N:LastName;FirstName;;;
+END:VCARD
+VCF;
+ $request->setBody($vcard);
+
+ $response = $this->request($request, 201);
+
+ // The custom Ew header should not be set
+ $this->assertNull(
+ $response->getHeader('X-Sabre-Ew-Gross')
+ );
+ // Valid, non-auto-fixed responses should contain an ETag.
+ $this->assertTrue(
+ $response->getHeader('ETag') !== null,
+ 'We did not receive an etag'
);
- $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf'));
+
+ $expected = [
+ 'uri' => 'blabla.vcf',
+ 'carddata' => $vcard,
+ 'size' => strlen($vcard),
+ 'etag' => '"' . md5($vcard) . '"',
+ ];
+
+ $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1', 'blabla.vcf'));
}
- function testCreateFileNoUID() {
+ /**
+ * This test creates an intentionally broken vCard that vobject is able
+ * to automatically repair.
+ *
+ * @depends testCreateFileValid
+ */
+ function testCreateVCardAutoFix() {
$request = new HTTP\Request(
'PUT',
'/addressbooks/admin/addressbook1/blabla.vcf'
);
- $request->setBody("BEGIN:VCARD\r\nEND:VCARD\r\n");
- $response = $this->request($request);
+ // The error in this vcard is that there's not enough semi-colons in N
+ $vcard = <<<VCF
+BEGIN:VCARD
+VERSION:4.0
+UID:foo
+FN:Firstname LastName
+N:LastName;FirstName;;
+END:VCARD
+VCF;
- $this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
+ $request->setBody($vcard);
+
+ $response = $this->request($request, 201);
+
+ // Auto-fixed vcards should NOT return an etag
+ $this->assertNull(
+ $response->getHeader('ETag')
+ );
+
+ // We should have gotten an Ew header
+ $this->assertNotNull(
+ $response->getHeader('X-Sabre-Ew-Gross')
+ );
+
+ $expectedVCard = <<<VCF
+BEGIN:VCARD\r
+VERSION:4.0\r
+UID:foo\r
+FN:Firstname LastName\r
+N:LastName;FirstName;;;\r
+END:VCARD\r
+
+VCF;
+
+ $expected = [
+ 'uri' => 'blabla.vcf',
+ 'carddata' => $expectedVCard,
+ 'size' => strlen($expectedVCard),
+ 'etag' => '"' . md5($expectedVCard) . '"',
+ ];
+
+ $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1', 'blabla.vcf'));
- $foo = $this->cardBackend->getCard('addressbook1','blabla.vcf');
- $this->assertTrue(strpos($foo['carddata'],'UID')!==false);
+ }
+
+ /**
+ * This test creates an intentionally broken vCard that vobject is able
+ * to automatically repair.
+ *
+ * However, we're supplying a heading asking the server to treat the
+ * request as strict, so the server should still let the request fail.
+ *
+ * @depends testCreateFileValid
+ */
+ function testCreateVCardStrictFail() {
+
+ $request = new HTTP\Request(
+ 'PUT',
+ '/addressbooks/admin/addressbook1/blabla.vcf',
+ [
+ 'Prefer' => 'handling=strict',
+ ]
+ );
+
+ // The error in this vcard is that there's not enough semi-colons in N
+ $vcard = <<<VCF
+BEGIN:VCARD
+VERSION:4.0
+UID:foo
+FN:Firstname LastName
+N:LastName;FirstName;;
+END:VCARD
+VCF;
+
+ $request->setBody($vcard);
+ $this->request($request, 415);
+
+ }
+
+ function testCreateFileNoUID() {
+
+ $request = new HTTP\Request(
+ 'PUT',
+ '/addressbooks/admin/addressbook1/blabla.vcf'
+ );
+ $vcard = <<<VCF
+BEGIN:VCARD
+VERSION:4.0
+FN:Firstname LastName
+N:LastName;FirstName;;;
+END:VCARD
+VCF;
+ $request->setBody($vcard);
+
+ $response = $this->request($request, 201);
+
+ $foo = $this->cardBackend->getCard('addressbook1', 'blabla.vcf');
+ $this->assertTrue(
+ strpos($foo['carddata'], 'UID') !== false,
+ print_r($foo, true)
+ );
}
function testCreateFileJson() {
@@ -106,23 +242,23 @@ class ValidateVCardTest extends \PHPUnit_Framework_TestCase {
'PUT',
'/addressbooks/admin/addressbook1/blabla.vcf'
);
- $request->setBody('[ "vcard" , [ [ "UID" , {}, "text", "foo" ] ] ]');
+ $request->setBody('[ "vcard" , [ [ "VERSION", {}, "text", "4.0"], [ "UID" , {}, "text", "foo" ], [ "FN", {}, "text", "FirstName LastName"] ] ]');
$response = $this->request($request);
$this->assertEquals(201, $response->status, 'Incorrect status returned! Full response body: ' . $response->body);
- $foo = $this->cardBackend->getCard('addressbook1','blabla.vcf');
- $this->assertEquals("BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n", $foo['carddata']);
+ $foo = $this->cardBackend->getCard('addressbook1', 'blabla.vcf');
+ $this->assertEquals("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nFN:FirstName LastName\r\nEND:VCARD\r\n", $foo['carddata']);
}
function testCreateFileVCalendar() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
- ));
+ 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
+ ]);
$request->setBody("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n");
$response = $this->request($request);
@@ -133,40 +269,37 @@ class ValidateVCardTest extends \PHPUnit_Framework_TestCase {
function testUpdateFile() {
- $this->cardBackend->createCard('addressbook1','blabla.vcf','foo');
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
- ));
-
- $response = $this->request($request);
+ $this->cardBackend->createCard('addressbook1', 'blabla.vcf', 'foo');
+ $request = new HTTP\Request(
+ 'PUT',
+ '/addressbooks/admin/addressbook1/blabla.vcf'
+ );
- $this->assertEquals(415, $response->status);
+ $response = $this->request($request, 415);
}
function testUpdateFileParsableBody() {
- $this->cardBackend->createCard('addressbook1','blabla.vcf','foo');
- $request = HTTP\Sapi::createFromServerArray(array(
- 'REQUEST_METHOD' => 'PUT',
- 'REQUEST_URI' => '/addressbooks/admin/addressbook1/blabla.vcf',
- ));
- $body = "BEGIN:VCARD\r\nUID:foo\r\nEND:VCARD\r\n";
- $request->setBody($body);
+ $this->cardBackend->createCard('addressbook1', 'blabla.vcf', 'foo');
+ $request = new HTTP\Request(
+ 'PUT',
+ '/addressbooks/admin/addressbook1/blabla.vcf'
+ );
- $response = $this->request($request);
+ $body = "BEGIN:VCARD\r\nVERSION:4.0\r\nUID:foo\r\nFN:FirstName LastName\r\nEND:VCARD\r\n";
+ $request->setBody($body);
- $this->assertEquals(204, $response->status);
+ $response = $this->request($request, 204);
- $expected = array(
+ $expected = [
'uri' => 'blabla.vcf',
- 'carddata' => $body,
- );
+ 'carddata' => $body,
+ 'size' => strlen($body),
+ 'etag' => '"' . md5($body) . '"',
+ ];
- $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1','blabla.vcf'));
+ $this->assertEquals($expected, $this->cardBackend->getCard('addressbook1', 'blabla.vcf'));
}
}
-
-?>
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php
index b5b8d64ee..6a8d389a0 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/AbstractServer.php
@@ -24,7 +24,7 @@ abstract class AbstractServer extends \PHPUnit_Framework_TestCase {
$this->server->sapi = new HTTP\SapiMock();
$this->server->httpResponse = $this->response;
$this->server->debugExceptions = true;
- $this->deleteTree(SABRE_TEMPDIR,false);
+ $this->deleteTree(SABRE_TEMPDIR, false);
file_put_contents(SABRE_TEMPDIR . '/test.txt', 'Test contents');
mkdir(SABRE_TEMPDIR . '/dir');
file_put_contents(SABRE_TEMPDIR . '/dir/child.txt', 'Child contents');
@@ -34,7 +34,7 @@ abstract class AbstractServer extends \PHPUnit_Framework_TestCase {
function tearDown() {
- $this->deleteTree(SABRE_TEMPDIR,false);
+ $this->deleteTree(SABRE_TEMPDIR, false);
}
@@ -44,12 +44,12 @@ abstract class AbstractServer extends \PHPUnit_Framework_TestCase {
}
- private function deleteTree($path,$deleteRoot = true) {
+ private function deleteTree($path, $deleteRoot = true) {
- foreach(scandir($path) as $node) {
+ foreach (scandir($path) as $node) {
- if ($node=='.' || $node=='.svn' || $node=='..') continue;
- $myPath = $path.'/'. $node;
+ if ($node == '.' || $node == '.svn' || $node == '..') continue;
+ $myPath = $path . '/' . $node;
if (is_file($myPath)) {
unlink($myPath);
} else {
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php
index 7d7a59898..455403aff 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractBasicTest.php
@@ -2,7 +2,6 @@
namespace Sabre\DAV\Auth\Backend;
-use Sabre\DAV;
use Sabre\HTTP;
class AbstractBasicTest extends \PHPUnit_Framework_TestCase {
@@ -22,10 +21,10 @@ class AbstractBasicTest extends \PHPUnit_Framework_TestCase {
function testCheckUnknownUser() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'PHP_AUTH_USER' => 'username',
- 'PHP_AUTH_PW' => 'wrongpassword',
- ));
+ 'PHP_AUTH_PW' => 'wrongpassword',
+ ]);
$response = new HTTP\Response();
$backend = new AbstractBasicMock();
@@ -38,10 +37,10 @@ class AbstractBasicTest extends \PHPUnit_Framework_TestCase {
function testCheckSuccess() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'PHP_AUTH_USER' => 'username',
- 'PHP_AUTH_PW' => 'password',
- ));
+ 'PHP_AUTH_PW' => 'password',
+ ]);
$response = new HTTP\Response();
$backend = new AbstractBasicMock();
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php
index 8ef416c37..14c72aaa0 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractDigestTest.php
@@ -2,7 +2,6 @@
namespace Sabre\DAV\Auth\Backend;
-use Sabre\DAV;
use Sabre\HTTP;
class AbstractDigestTest extends \PHPUnit_Framework_TestCase {
@@ -87,12 +86,12 @@ class AbstractDigestTest extends \PHPUnit_Framework_TestCase {
function testCheck() {
$digestHash = md5('HELLO:12345:1:1:auth:' . md5('GET:/'));
- $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response='.$digestHash.', opaque=1, qop=auth, nc=1, cnonce=1';
- $request = HTTP\Sapi::createFromServerArray(array(
+ $header = 'username=user, realm=myRealm, nonce=12345, uri=/, response=' . $digestHash . ', opaque=1, qop=auth, nc=1, cnonce=1';
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'GET',
'PHP_AUTH_DIGEST' => $header,
'REQUEST_URI' => '/',
- ));
+ ]);
$response = new HTTP\Response();
@@ -127,10 +126,10 @@ class AbstractDigestMock extends AbstractDigest {
function getDigestHash($realm, $userName) {
- switch($userName) {
+ switch ($userName) {
case 'null' : return null;
case 'false' : return false;
- case 'array' : return array();
+ case 'array' : return [];
case 'user' : return 'HELLO';
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php
index d22923d51..b14e9fa2e 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/AbstractPDOTest.php
@@ -2,11 +2,21 @@
namespace Sabre\DAV\Auth\Backend;
-use Sabre\DAV;
-
abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
- abstract function getPDO();
+ use \Sabre\DAV\DbTestHelperTrait;
+
+ function setUp() {
+
+ $this->dropTables('users');
+ $this->createSchema('users');
+
+ $this->getPDO()->query(
+ "INSERT INTO users (username,digesta1) VALUES ('user','hash')"
+
+ );
+
+ }
function testConstruct() {
@@ -24,11 +34,11 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$pdo = $this->getPDO();
$backend = new PDO($pdo);
- $this->assertNull($backend->getDigestHash('realm','blabla'));
+ $this->assertNull($backend->getDigestHash('realm', 'blabla'));
$expected = 'hash';
- $this->assertEquals($expected, $backend->getDigestHash('realm','user'));
+ $this->assertEquals($expected, $backend->getDigestHash('realm', 'user'));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php
index 697b593db..29cbc2162 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/ApacheTest.php
@@ -2,7 +2,6 @@
namespace Sabre\DAV\Auth\Backend;
-use Sabre\DAV;
use Sabre\HTTP;
class ApacheTest extends \PHPUnit_Framework_TestCase {
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php
index d2e5fe49b..f694f4806 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/FileTest.php
@@ -6,7 +6,7 @@ class FileTest extends \PHPUnit_Framework_TestCase {
function tearDown() {
- if (file_exists(SABRE_TEMPDIR . '/filebackend')) unlink(SABRE_TEMPDIR .'/filebackend');
+ if (file_exists(SABRE_TEMPDIR . '/filebackend')) unlink(SABRE_TEMPDIR . '/filebackend');
}
@@ -22,20 +22,19 @@ class FileTest extends \PHPUnit_Framework_TestCase {
*/
function testLoadFileBroken() {
- file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:hash');
- $file = new File();
- $file->loadFile(SABRE_TEMPDIR .'/backend');
+ file_put_contents(SABRE_TEMPDIR . '/backend', 'user:realm:hash');
+ $file = new File(SABRE_TEMPDIR . '/backend');
}
function testLoadFile() {
- file_put_contents(SABRE_TEMPDIR . '/backend','user:realm:' . md5('user:realm:password'));
+ file_put_contents(SABRE_TEMPDIR . '/backend', 'user:realm:' . md5('user:realm:password'));
$file = new File();
$file->loadFile(SABRE_TEMPDIR . '/backend');
- $this->assertFalse($file->getDigestHash('realm','blabla'));
- $this->assertEquals(md5('user:realm:password'), $file->getDigestHash('realm','user'));
+ $this->assertFalse($file->getDigestHash('realm', 'blabla'));
+ $this->assertEquals(md5('user:realm:password'), $file->getDigestHash('realm', 'user'));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php
index a782cb74d..b30b3f143 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/Mock.php
@@ -2,10 +2,8 @@
namespace Sabre\DAV\Auth\Backend;
-use
- Sabre\DAV,
- Sabre\HTTP\RequestInterface,
- Sabre\HTTP\ResponseInterface;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
class Mock implements BackendInterface {
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php
index 8de2be667..18f59793a 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOMySQLTest.php
@@ -2,32 +2,8 @@
namespace Sabre\DAV\Auth\Backend;
-require_once 'Sabre/TestUtil.php';
-
class PDOMySQLTest extends AbstractPDOTest {
- function getPDO() {
-
- if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
- $pdo = \Sabre\TestUtil::getMySQLDB();
- if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
- $pdo->query("DROP TABLE IF EXISTS users");
- $pdo->query(<<<SQL
-create table users (
- id integer unsigned not null primary key auto_increment,
- username varchar(50),
- digesta1 varchar(32),
- email varchar(80),
- displayname varchar(80),
- unique(username)
-)
-SQL
- );
-
- $pdo->query("INSERT INTO users (username,digesta1,email,displayname) VALUES ('user','hash','user@example.org','User')");
-
- return $pdo;
-
- }
+ public $driver = 'mysql';
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php
index abfb031bb..b1f382237 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/Backend/PDOSqliteTest.php
@@ -2,27 +2,8 @@
namespace Sabre\DAV\Auth\Backend;
-require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php';
+class PDOSqliteTest extends AbstractPDOTest {
-class PDOSQLiteTest extends AbstractPDOTest {
-
- function tearDown() {
-
- if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend');
- if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2');
-
- }
-
- function getPDO() {
-
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
- $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
- $pdo->query('CREATE TABLE users (username TEXT, digesta1 TEXT, email VARCHAR(80), displayname VARCHAR(80))');
- $pdo->query('INSERT INTO users VALUES ("user","hash","user@example.org","User")');
-
- return $pdo;
-
- }
+ public $driver = 'sqlite';
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php
index 0ac9e0613..b566dd757 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Auth/PluginTest.php
@@ -5,13 +5,11 @@ namespace Sabre\DAV\Auth;
use Sabre\HTTP;
use Sabre\DAV;
-require_once 'Sabre/HTTP/ResponseMock.php';
-
class PluginTest extends \PHPUnit_Framework_TestCase {
function testInit() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$plugin = new Plugin(new Backend\Mock());
$this->assertTrue($plugin instanceof Plugin);
$fakeServer->addPlugin($plugin);
@@ -25,7 +23,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
*/
function testAuthenticate() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$plugin = new Plugin(new Backend\Mock());
$fakeServer->addPlugin($plugin);
$this->assertTrue(
@@ -40,7 +38,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
*/
function testAuthenticateFail() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$backend = new Backend\Mock();
$backend->fail = true;
@@ -51,11 +49,30 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
}
/**
+ * @depends testAuthenticateFail
+ */
+ function testAuthenticateFailDontAutoRequire() {
+
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
+ $backend = new Backend\Mock();
+ $backend->fail = true;
+
+ $plugin = new Plugin($backend);
+ $plugin->autoRequireLogin = false;
+ $fakeServer->addPlugin($plugin);
+ $this->assertTrue(
+ $fakeServer->emit('beforeMethod', [new HTTP\Request(), new HTTP\Response()])
+ );
+ $this->assertEquals(1, count($plugin->getLoginFailedReasons()));
+
+ }
+
+ /**
* @depends testAuthenticate
*/
function testMultipleBackend() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$backend1 = new Backend\Mock();
$backend2 = new Backend\Mock();
$backend2->fail = true;
@@ -77,7 +94,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
*/
function testNoAuthBackend() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$plugin = new Plugin();
$fakeServer->addPlugin($plugin);
@@ -90,7 +107,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
*/
function testInvalidCheckResponse() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$backend = new Backend\Mock();
$backend->invalidCheckResponse = true;
@@ -105,7 +122,7 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
*/
function testGetCurrentPrincipal() {
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
+ $fakeServer = new DAV\Server(new DAV\SimpleCollection('bla'));
$plugin = new Plugin(new Backend\Mock());
$fakeServer->addPlugin($plugin);
$fakeServer->emit('beforeMethod', [new HTTP\Request(), new HTTP\Response()]);
@@ -113,18 +130,4 @@ class PluginTest extends \PHPUnit_Framework_TestCase {
}
- /**
- * @depends testAuthenticate
- */
- function testGetCurrentUser() {
-
- $fakeServer = new DAV\Server( new DAV\SimpleCollection('bla'));
- $plugin = new Plugin(new Backend\Mock());
- $fakeServer->addPlugin($plugin);
- $fakeServer->emit('beforeMethod', [new HTTP\Request(), new HTTP\Response()]);
- $this->assertEquals('admin', $plugin->getCurrentUser());
-
- }
-
}
-
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php
index 155c785f8..ec104ec80 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/BasicNodeTest.php
@@ -7,7 +7,7 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
- public function testPut() {
+ function testPut() {
$file = new FileMock();
$file->put('hi');
@@ -17,29 +17,29 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
- public function testGet() {
+ function testGet() {
$file = new FileMock();
$file->get();
}
- public function testGetSize() {
+ function testGetSize() {
$file = new FileMock();
- $this->assertEquals(0,$file->getSize());
+ $this->assertEquals(0, $file->getSize());
}
- public function testGetETag() {
+ function testGetETag() {
$file = new FileMock();
$this->assertNull($file->getETag());
}
- public function testGetContentType() {
+ function testGetContentType() {
$file = new FileMock();
$this->assertNull($file->getContentType());
@@ -49,7 +49,7 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
- public function testDelete() {
+ function testDelete() {
$file = new FileMock();
$file->delete();
@@ -59,24 +59,24 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
- public function testSetName() {
+ function testSetName() {
$file = new FileMock();
$file->setName('hi');
}
- public function testGetLastModified() {
+ function testGetLastModified() {
$file = new FileMock();
// checking if lastmod is within the range of a few seconds
$lastMod = $file->getLastModified();
- $compareTime = ($lastMod + 1)-time();
+ $compareTime = ($lastMod + 1) - time();
$this->assertTrue($compareTime < 3);
}
- public function testGetChild() {
+ function testGetChild() {
$dir = new DirectoryMock();
$file = $dir->getChild('mockfile');
@@ -84,14 +84,14 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
}
- public function testChildExists() {
+ function testChildExists() {
$dir = new DirectoryMock();
$this->assertTrue($dir->childExists('mockfile'));
}
- public function testChildExistsFalse() {
+ function testChildExistsFalse() {
$dir = new DirectoryMock();
$this->assertFalse($dir->childExists('mockfile2'));
@@ -101,7 +101,7 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\NotFound
*/
- public function testGetChild404() {
+ function testGetChild404() {
$dir = new DirectoryMock();
$file = $dir->getChild('blabla');
@@ -111,26 +111,26 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
- public function testCreateFile() {
+ function testCreateFile() {
$dir = new DirectoryMock();
- $dir->createFile('hello','data');
+ $dir->createFile('hello', 'data');
}
/**
* @expectedException Sabre\DAV\Exception\Forbidden
*/
- public function testCreateDirectory() {
+ function testCreateDirectory() {
$dir = new DirectoryMock();
$dir->createDirectory('hello');
}
- public function testSimpleDirectoryConstruct() {
+ function testSimpleDirectoryConstruct() {
- $dir = new SimpleCollection('simpledir',array());
+ $dir = new SimpleCollection('simpledir', []);
$this->assertInstanceOf('Sabre\DAV\SimpleCollection', $dir);
}
@@ -138,13 +138,13 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
/**
* @depends testSimpleDirectoryConstruct
*/
- public function testSimpleDirectoryConstructChild() {
+ function testSimpleDirectoryConstructChild() {
$file = new FileMock();
- $dir = new SimpleCollection('simpledir',array($file));
+ $dir = new SimpleCollection('simpledir', [$file]);
$file2 = $dir->getChild('mockfile');
- $this->assertEquals($file,$file2);
+ $this->assertEquals($file, $file2);
}
@@ -152,23 +152,23 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
* @expectedException Sabre\DAV\Exception
* @depends testSimpleDirectoryConstruct
*/
- public function testSimpleDirectoryBadParam() {
+ function testSimpleDirectoryBadParam() {
- $dir = new SimpleCollection('simpledir',array('string shouldn\'t be here'));
+ $dir = new SimpleCollection('simpledir', ['string shouldn\'t be here']);
}
/**
* @depends testSimpleDirectoryConstruct
*/
- public function testSimpleDirectoryAddChild() {
+ function testSimpleDirectoryAddChild() {
$file = new FileMock();
$dir = new SimpleCollection('simpledir');
$dir->addChild($file);
$file2 = $dir->getChild('mockfile');
- $this->assertEquals($file,$file2);
+ $this->assertEquals($file, $file2);
}
@@ -176,23 +176,23 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
* @depends testSimpleDirectoryConstruct
* @depends testSimpleDirectoryAddChild
*/
- public function testSimpleDirectoryGetChildren() {
+ function testSimpleDirectoryGetChildren() {
$file = new FileMock();
$dir = new SimpleCollection('simpledir');
$dir->addChild($file);
- $this->assertEquals(array($file),$dir->getChildren());
+ $this->assertEquals([$file], $dir->getChildren());
}
/*
* @depends testSimpleDirectoryConstruct
*/
- public function testSimpleDirectoryGetName() {
+ function testSimpleDirectoryGetName() {
$dir = new SimpleCollection('simpledir');
- $this->assertEquals('simpledir',$dir->getName());
+ $this->assertEquals('simpledir', $dir->getName());
}
@@ -200,7 +200,7 @@ class BasicNodeTest extends \PHPUnit_Framework_TestCase {
* @depends testSimpleDirectoryConstruct
* @expectedException Sabre\DAV\Exception\NotFound
*/
- public function testSimpleDirectoryGetChild404() {
+ function testSimpleDirectoryGetChild404() {
$dir = new SimpleCollection('simpledir');
$dir->getChild('blabla');
@@ -218,7 +218,7 @@ class DirectoryMock extends Collection {
function getChildren() {
- return array(new FileMock());
+ return [new FileMock()];
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php
index 157c2170a..54a3053ec 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/GuessContentTypeTest.php
@@ -11,8 +11,8 @@ class GuessContentTypeTest extends DAV\AbstractServer {
parent::setUp();
\Sabre\TestUtil::clearTempDir();
- file_put_contents(SABRE_TEMPDIR . '/somefile.jpg','blabla');
- file_put_contents(SABRE_TEMPDIR . '/somefile.hoi','blabla');
+ file_put_contents(SABRE_TEMPDIR . '/somefile.jpg', 'blabla');
+ file_put_contents(SABRE_TEMPDIR . '/somefile.hoi', 'blabla');
}
@@ -24,13 +24,13 @@ class GuessContentTypeTest extends DAV\AbstractServer {
function testGetProperties() {
- $properties = array(
+ $properties = [
'{DAV:}getcontenttype',
- );
- $result = $this->server->getPropertiesForPath('/somefile.jpg',$properties);
- $this->assertArrayHasKey(0,$result);
- $this->assertArrayHasKey(404,$result[0]);
- $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][404]);
+ ];
+ $result = $this->server->getPropertiesForPath('/somefile.jpg', $properties);
+ $this->assertArrayHasKey(0, $result);
+ $this->assertArrayHasKey(404, $result[0]);
+ $this->assertArrayHasKey('{DAV:}getcontenttype', $result[0][404]);
}
@@ -40,14 +40,14 @@ class GuessContentTypeTest extends DAV\AbstractServer {
function testGetPropertiesPluginEnabled() {
$this->server->addPlugin(new GuessContentType());
- $properties = array(
+ $properties = [
'{DAV:}getcontenttype',
- );
- $result = $this->server->getPropertiesForPath('/somefile.jpg',$properties);
- $this->assertArrayHasKey(0,$result);
- $this->assertArrayHasKey(200,$result[0], 'We received: ' . print_r($result,true));
- $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][200]);
- $this->assertEquals('image/jpeg',$result[0][200]['{DAV:}getcontenttype']);
+ ];
+ $result = $this->server->getPropertiesForPath('/somefile.jpg', $properties);
+ $this->assertArrayHasKey(0, $result);
+ $this->assertArrayHasKey(200, $result[0], 'We received: ' . print_r($result, true));
+ $this->assertArrayHasKey('{DAV:}getcontenttype', $result[0][200]);
+ $this->assertEquals('image/jpeg', $result[0][200]['{DAV:}getcontenttype']);
}
@@ -57,14 +57,14 @@ class GuessContentTypeTest extends DAV\AbstractServer {
function testGetPropertiesUnknown() {
$this->server->addPlugin(new GuessContentType());
- $properties = array(
+ $properties = [
'{DAV:}getcontenttype',
- );
- $result = $this->server->getPropertiesForPath('/somefile.hoi',$properties);
- $this->assertArrayHasKey(0,$result);
- $this->assertArrayHasKey(200,$result[0]);
- $this->assertArrayHasKey('{DAV:}getcontenttype',$result[0][200]);
- $this->assertEquals('application/octet-stream',$result[0][200]['{DAV:}getcontenttype']);
+ ];
+ $result = $this->server->getPropertiesForPath('/somefile.hoi', $properties);
+ $this->assertArrayHasKey(0, $result);
+ $this->assertArrayHasKey(200, $result[0]);
+ $this->assertArrayHasKey('{DAV:}getcontenttype', $result[0][200]);
+ $this->assertEquals('application/octet-stream', $result[0][200]['{DAV:}getcontenttype']);
}
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php
index 9d9fbb319..33c4ede96 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/MapGetToPropFindTest.php
@@ -18,23 +18,23 @@ class MapGetToPropFindTest extends DAV\AbstractServer {
function testCollectionGet() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'GET',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('');
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(207, $this->response->status,'Incorrect status response received. Full response body: ' . $this->response->body);
- $this->assertEquals(array(
+ $this->assertEquals(207, $this->response->status, 'Incorrect status response received. Full response body: ' . $this->response->body);
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'DAV' => ['1, 3, extended-mkcol'],
- 'Vary' => ['Brief,Prefer'],
- ),
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'DAV' => ['1, 3, extended-mkcol'],
+ 'Vary' => ['Brief,Prefer'],
+ ],
$this->response->getHeaders()
);
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php
index 00beea9f2..f20c50f86 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Browser/PluginTest.php
@@ -28,16 +28,16 @@ class PluginTest extends DAV\AbstractServer{
$this->assertEquals(200, $this->response->getStatus(), "Incorrect status received. Full response body: " . $this->response->getBodyAsString());
$this->assertEquals(
[
- 'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['text/html; charset=utf-8'],
- 'Content-Security-Policy' => ["img-src 'self'; style-src 'self';"]
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ 'Content-Type' => ['text/html; charset=utf-8'],
+ 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"]
],
$this->response->getHeaders()
);
$body = $this->response->getBodyAsString();
$this->assertTrue(strpos($body, '<title>dir') !== false, $body);
- $this->assertTrue(strpos($body, '<a href="/dir/child.txt">')!==false);
+ $this->assertTrue(strpos($body, '<a href="/dir/child.txt">') !== false);
}
@@ -54,16 +54,16 @@ class PluginTest extends DAV\AbstractServer{
$this->assertEquals(200, $this->response->getStatus(), "Incorrect status received. Full response body: " . $this->response->getBodyAsString());
$this->assertEquals(
[
- 'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['text/html; charset=utf-8'],
- 'Content-Security-Policy' => ["img-src 'self'; style-src 'self';"]
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ 'Content-Type' => ['text/html; charset=utf-8'],
+ 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"]
],
$this->response->getHeaders()
);
$body = $this->response->getBodyAsString();
$this->assertTrue(strpos($body, '<title>dir') !== false, $body);
- $this->assertTrue(strpos($body, '<a href="/dir/child.txt">')!==false);
+ $this->assertTrue(strpos($body, '<a href="/dir/child.txt">') !== false);
}
function testCollectionGetRoot() {
@@ -75,17 +75,17 @@ class PluginTest extends DAV\AbstractServer{
$this->assertEquals(200, $this->response->status, "Incorrect status received. Full response body: " . $this->response->getBodyAsString());
$this->assertEquals(
[
- 'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['text/html; charset=utf-8'],
- 'Content-Security-Policy' => ["img-src 'self'; style-src 'self';"]
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ 'Content-Type' => ['text/html; charset=utf-8'],
+ 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"]
],
$this->response->getHeaders()
);
$body = $this->response->getBodyAsString();
$this->assertTrue(strpos($body, '<title>/') !== false, $body);
- $this->assertTrue(strpos($body, '<a href="/dir/">')!==false);
- $this->assertTrue(strpos($body, '<span class="btn disabled">')!==false);
+ $this->assertTrue(strpos($body, '<a href="/dir/">') !== false);
+ $this->assertTrue(strpos($body, '<span class="btn disabled">') !== false);
}
@@ -122,15 +122,15 @@ class PluginTest extends DAV\AbstractServer{
function testPostMkCol() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'POST',
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
- );
- $postVars = array(
+ 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
+ ];
+ $postVars = [
'sabreAction' => 'mkcol',
- 'name' => 'new_collection',
- );
+ 'name' => 'new_collection',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setPostData($postVars);
@@ -138,10 +138,10 @@ class PluginTest extends DAV\AbstractServer{
$this->server->exec();
$this->assertEquals(302, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Location' => ['/'],
- ), $this->response->getHeaders());
+ 'Location' => ['/'],
+ ], $this->response->getHeaders());
$this->assertTrue(is_dir(SABRE_TEMPDIR . '/new_collection'));
@@ -155,11 +155,11 @@ class PluginTest extends DAV\AbstractServer{
$this->assertEquals(200, $this->response->getStatus(), 'Error: ' . $this->response->body);
$this->assertEquals([
- 'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['image/vnd.microsoft.icon'],
- 'Content-Length' => ['4286'],
- 'Cache-Control' => ['public, max-age=1209600'],
- 'Content-Security-Policy' => ["img-src 'self'; style-src 'self';"]
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ 'Content-Type' => ['image/vnd.microsoft.icon'],
+ 'Content-Length' => ['4286'],
+ 'Cache-Control' => ['public, max-age=1209600'],
+ 'Content-Security-Policy' => ["default-src 'none'; img-src 'self'; style-src 'self'; font-src 'self';"]
], $this->response->getHeaders());
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php
index d8b53a5a1..5a48b063c 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ClientMock.php
@@ -18,13 +18,13 @@ class ClientMock extends Client {
* @param string $url
* @return string
*/
- public function getAbsoluteUrl($url) {
+ function getAbsoluteUrl($url) {
return parent::getAbsoluteUrl($url);
}
- public function doRequest(RequestInterface $request) {
+ function doRequest(RequestInterface $request) {
$this->request = $request;
return $this->response;
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php
index c06d6aa1f..8788475cb 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Exception/LockedTest.php
@@ -2,9 +2,8 @@
namespace Sabre\DAV\Exception;
-use
- Sabre\DAV,
- DOMDocument;
+use Sabre\DAV;
+use DOMDocument;
class LockedTest extends \PHPUnit_Framework_TestCase {
@@ -15,7 +14,7 @@ class LockedTest extends \PHPUnit_Framework_TestCase {
$root = $dom->createElement('d:root');
$dom->appendChild($root);
- $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:d', 'DAV:');
$lockInfo = new DAV\Locks\LockInfo();
$lockInfo->uri = '/foo';
@@ -44,7 +43,7 @@ class LockedTest extends \PHPUnit_Framework_TestCase {
$root = $dom->createElement('d:root');
$dom->appendChild($root);
- $root->setAttribute('xmlns:d','DAV:');
+ $root->setAttribute('xmlns:d', 'DAV:');
$lockInfo = new DAV\Locks\LockInfo();
$lockInfo->uri = '/foo&bar';
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php
index 6d6bf5668..0eb4f3dd8 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ExceptionTest.php
@@ -7,18 +7,18 @@ class ExceptionTest extends \PHPUnit_Framework_TestCase {
function testStatus() {
$e = new Exception();
- $this->assertEquals(500,$e->getHTTPCode());
+ $this->assertEquals(500, $e->getHTTPCode());
}
function testExceptionStatuses() {
- $c = array(
+ $c = [
'Sabre\\DAV\\Exception\\NotAuthenticated' => 401,
'Sabre\\DAV\\Exception\\InsufficientStorage' => 507,
- );
+ ];
- foreach($c as $class=>$status) {
+ foreach ($c as $class => $status) {
$obj = new $class();
$this->assertEquals($status, $obj->getHTTPCode());
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php
index 3708594e0..f5d65a44f 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/FileTest.php
@@ -2,8 +2,6 @@
namespace Sabre\DAV\FSExt;
-use Sabre\DAV;
-
require_once 'Sabre/TestUtil.php';
class FileTest extends \PHPUnit_Framework_TestCase {
@@ -26,12 +24,12 @@ class FileTest extends \PHPUnit_Framework_TestCase {
$file = new File($filename);
$result = $file->put('New contents');
- $this->assertEquals('New contents',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
+ $this->assertEquals('New contents', file_get_contents(SABRE_TEMPDIR . '/file.txt'));
$this->assertEquals(
'"' .
sha1(
fileinode($filename) .
- filesize($filename ) .
+ filesize($filename) .
filemtime($filename)
) . '"',
$result
@@ -45,13 +43,13 @@ class FileTest extends \PHPUnit_Framework_TestCase {
$file->put('0000000');
$file->patch('111', 2, 3);
- $this->assertEquals('0001110',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
+ $this->assertEquals('0001110', file_get_contents(SABRE_TEMPDIR . '/file.txt'));
}
function testRangeStream() {
- $stream = fopen('php://memory','r+');
+ $stream = fopen('php://memory', 'r+');
fwrite($stream, "222");
rewind($stream);
@@ -59,7 +57,7 @@ class FileTest extends \PHPUnit_Framework_TestCase {
$file->put('0000000');
$file->patch($stream, 2, 3);
- $this->assertEquals('0002220',file_get_contents(SABRE_TEMPDIR . '/file.txt'));
+ $this->assertEquals('0002220', file_get_contents(SABRE_TEMPDIR . '/file.txt'));
}
@@ -67,7 +65,7 @@ class FileTest extends \PHPUnit_Framework_TestCase {
function testGet() {
$file = new File(SABRE_TEMPDIR . '/file.txt');
- $this->assertEquals('Contents',stream_get_contents($file->get()));
+ $this->assertEquals('Contents', stream_get_contents($file->get()));
}
@@ -88,7 +86,7 @@ class FileTest extends \PHPUnit_Framework_TestCase {
'"' .
sha1(
fileinode($filename) .
- filesize($filename ) .
+ filesize($filename) .
filemtime($filename)
) . '"',
$file->getETag()
@@ -105,7 +103,7 @@ class FileTest extends \PHPUnit_Framework_TestCase {
function testGetSize() {
$file = new File(SABRE_TEMPDIR . '/file.txt');
- $this->assertEquals(8,$file->getSize());
+ $this->assertEquals(8, $file->getSize());
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php
index 63d858de1..20fca490a 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/FSExt/ServerTest.php
@@ -28,7 +28,7 @@ class ServerTest extends DAV\AbstractServer{
'Content-Type' => ['application/octet-stream'],
'Content-Length' => [13],
'Last-Modified' => [HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($filename)))],
- 'ETag' => ['"' . sha1(fileinode($filename ) . filesize($filename) . filemtime($filename)) . '"'],
+ 'ETag' => ['"' . sha1(fileinode($filename) . filesize($filename) . filemtime($filename)) . '"'],
],
$this->response->getHeaders()
);
@@ -50,12 +50,12 @@ class ServerTest extends DAV\AbstractServer{
'Content-Type' => ['application/octet-stream'],
'Content-Length' => [13],
'Last-Modified' => [HTTP\Util::toHTTPDate(new \DateTime('@' . filemtime($this->tempDir . '/test.txt')))],
- 'ETag' => ['"' . sha1(fileinode($filename ) . filesize($filename) . filemtime($filename)) . '"'],
+ 'ETag' => ['"' . sha1(fileinode($filename) . filesize($filename) . filemtime($filename)) . '"'],
],
$this->response->getHeaders()
);
- $this->assertEquals(200,$this->response->status);
+ $this->assertEquals(200, $this->response->status);
$this->assertEquals('', $this->response->body);
}
@@ -71,12 +71,12 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
'Content-Length' => ['0'],
- 'ETag' => ['"' . sha1(fileinode($filename ) . filesize($filename) . filemtime($filename)) . '"'],
+ 'ETag' => ['"' . sha1(fileinode($filename) . filesize($filename) . filemtime($filename)) . '"'],
], $this->response->getHeaders());
$this->assertEquals(201, $this->response->status);
$this->assertEquals('', $this->response->body);
- $this->assertEquals('Testing new file',file_get_contents($filename));
+ $this->assertEquals('Testing new file', file_get_contents($filename));
}
@@ -89,11 +89,11 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ],$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
$this->assertEquals(412, $this->response->status);
- $this->assertNotEquals('Testing new file',file_get_contents($this->tempDir . '/test.txt'));
+ $this->assertNotEquals('Testing new file', file_get_contents($this->tempDir . '/test.txt'));
}
@@ -105,8 +105,8 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Length' => ['0'],
- ],$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ ], $this->response->getHeaders());
$this->assertEquals(201, $this->response->status);
$this->assertEquals('', $this->response->body);
@@ -125,7 +125,7 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals(204, $this->response->status);
$this->assertEquals('', $this->response->body);
- $this->assertEquals('Testing updated file',file_get_contents($this->tempDir . '/test.txt'));
+ $this->assertEquals('Testing updated file', file_get_contents($this->tempDir . '/test.txt'));
}
@@ -137,8 +137,8 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Length' => ['0'],
- ],$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ ], $this->response->getHeaders());
$this->assertEquals(204, $this->response->status);
$this->assertEquals('', $this->response->body);
@@ -148,8 +148,8 @@ class ServerTest extends DAV\AbstractServer{
function testDeleteDirectory() {
- mkdir($this->tempDir.'/testcol');
- file_put_contents($this->tempDir.'/testcol/test.txt','Hi! I\'m a file with a short lifespan');
+ mkdir($this->tempDir . '/testcol');
+ file_put_contents($this->tempDir . '/testcol/test.txt', 'Hi! I\'m a file with a short lifespan');
$request = new HTTP\Request('DELETE', '/testcol');
$this->server->httpRequest = ($request);
@@ -157,8 +157,8 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Length' => ['0'],
- ],$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ ], $this->response->getHeaders());
$this->assertEquals(204, $this->response->status);
$this->assertEquals('', $this->response->body);
$this->assertFalse(file_exists($this->tempDir . '/testcol'));
@@ -172,12 +172,12 @@ class ServerTest extends DAV\AbstractServer{
$this->server->exec();
$this->assertEquals([
- 'DAV' => ['1, 3, extended-mkcol'],
- 'MS-Author-Via' => ['DAV'],
- 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'],
- 'Accept-Ranges' => ['bytes'],
- 'Content-Length' => ['0'],
- 'X-Sabre-Version'=> [DAV\Version::VERSION],
+ 'DAV' => ['1, 3, extended-mkcol'],
+ 'MS-Author-Via' => ['DAV'],
+ 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'],
+ 'Accept-Ranges' => ['bytes'],
+ 'Content-Length' => ['0'],
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
], $this->response->getHeaders());
$this->assertEquals(200, $this->response->status);
@@ -187,7 +187,7 @@ class ServerTest extends DAV\AbstractServer{
function testMove() {
- mkdir($this->tempDir.'/testcol');
+ mkdir($this->tempDir . '/testcol');
$request = new HTTP\Request('MOVE', '/test.txt', ['Destination' => '/testcol/test2.txt']);
$this->server->httpRequest = ($request);
@@ -197,9 +197,9 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals('', $this->response->body);
$this->assertEquals([
- 'Content-Length' => ['0'],
- 'X-Sabre-Version'=> [DAV\Version::VERSION],
- ],$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ ], $this->response->getHeaders());
$this->assertTrue(
is_file($this->tempDir . '/testcol/test2.txt')
@@ -217,8 +217,8 @@ class ServerTest extends DAV\AbstractServer{
*/
function testMoveOtherObject() {
- mkdir($this->tempDir.'/tree1');
- mkdir($this->tempDir.'/tree2');
+ mkdir($this->tempDir . '/tree1');
+ mkdir($this->tempDir . '/tree2');
$tree = new DAV\Tree(new DAV\SimpleCollection('root', [
new DAV\FS\Directory($this->tempDir . '/tree1'),
@@ -234,9 +234,9 @@ class ServerTest extends DAV\AbstractServer{
$this->assertEquals('', $this->response->body);
$this->assertEquals([
- 'Content-Length' => ['0'],
- 'X-Sabre-Version'=> [DAV\Version::VERSION],
- ],$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ 'X-Sabre-Version' => [DAV\Version::VERSION],
+ ], $this->response->getHeaders());
$this->assertTrue(
is_dir($this->tempDir . '/tree2/tree1')
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php
index 6c10afa9f..bd1b33150 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/HttpDeleteTest.php
@@ -19,12 +19,12 @@ class HttpDeleteTest extends DAVServerTest {
*
* @return void
*/
- public function setUpTree() {
+ function setUpTree() {
$this->tree = new Mock\Collection('root', [
'file1' => 'foo',
- 'dir' => [
- 'subfile' => 'bar',
+ 'dir' => [
+ 'subfile' => 'bar',
'subfile2' => 'baz',
],
]);
@@ -34,7 +34,7 @@ class HttpDeleteTest extends DAVServerTest {
/**
* A successful DELETE
*/
- public function testDelete() {
+ function testDelete() {
$request = new HTTP\Request('DELETE', '/file1');
@@ -49,7 +49,7 @@ class HttpDeleteTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
+ 'Content-Length' => ['0'],
],
$response->getHeaders()
);
@@ -59,7 +59,7 @@ class HttpDeleteTest extends DAVServerTest {
/**
* Deleting a Directory
*/
- public function testDeleteDirectory() {
+ function testDeleteDirectory() {
$request = new HTTP\Request('DELETE', '/dir');
@@ -74,7 +74,7 @@ class HttpDeleteTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
+ 'Content-Length' => ['0'],
],
$response->getHeaders()
);
@@ -84,7 +84,7 @@ class HttpDeleteTest extends DAVServerTest {
/**
* DELETE on a node that does not exist
*/
- public function testDeleteNotFound() {
+ function testDeleteNotFound() {
$request = new HTTP\Request('DELETE', '/file2');
$response = $this->request($request);
@@ -100,7 +100,7 @@ class HttpDeleteTest extends DAVServerTest {
/**
* DELETE with preconditions
*/
- public function testDeletePreconditions() {
+ function testDeletePreconditions() {
$request = new HTTP\Request('DELETE', '/file1', [
'If-Match' => '"' . md5('foo') . '"',
@@ -119,7 +119,7 @@ class HttpDeleteTest extends DAVServerTest {
/**
* DELETE with incorrect preconditions
*/
- public function testDeletePreconditionsFailed() {
+ function testDeletePreconditionsFailed() {
$request = new HTTP\Request('DELETE', '/file1', [
'If-Match' => '"' . md5('bar') . '"',
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php b/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php
index eddaf3f22..86480b1c2 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/HttpPutTest.php
@@ -46,8 +46,8 @@ class HttpPutTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5('hello') . '"']
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5('hello') . '"']
],
$response->getHeaders()
);
@@ -75,8 +75,8 @@ class HttpPutTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5('bar') . '"']
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5('bar') . '"']
],
$response->getHeaders()
);
@@ -109,8 +109,8 @@ class HttpPutTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5('hello') . '"']
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5('hello') . '"']
],
$response->getHeaders()
);
@@ -143,8 +143,8 @@ class HttpPutTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5('hello') . '"'],
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5('hello') . '"'],
],
$response->getHeaders()
);
@@ -196,8 +196,8 @@ class HttpPutTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5('hello') . '"']
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5('hello') . '"']
],
$response->getHeaders()
);
@@ -291,8 +291,8 @@ class HttpPutTest extends DAVServerTest {
$this->assertEquals(
[
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- 'ETag' => ['"' . md5('hello') . '"'],
+ 'Content-Length' => ['0'],
+ 'ETag' => ['"' . md5('hello') . '"'],
],
$response->getHeaders()
);
@@ -334,7 +334,7 @@ class HttpPutTest extends DAVServerTest {
$request = new HTTP\Request('PUT', '/file2', [], 'hello');
$response = $this->request($request);
- $this->assertEquals(418, $response->getStatus(), 'Incorrect status code received. Full response body: ' .$response->getBodyAsString());
+ $this->assertEquals(418, $response->getStatus(), 'Incorrect status code received. Full response body: ' . $response->getBodyAsString());
$this->assertFalse(
$this->server->tree->nodeExists('file2')
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php
index 4ccb42fbb..edd09e634 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Issue33Test.php
@@ -17,16 +17,16 @@ class Issue33Test extends \PHPUnit_Framework_TestCase {
function testCopyMoveInfo() {
$bar = new SimpleCollection('bar');
- $root = new SimpleCollection('webdav',array($bar));
+ $root = new SimpleCollection('webdav', [$bar]);
$server = new Server($root);
$server->setBaseUri('/webdav/');
- $serverVars = array(
- 'REQUEST_URI' => '/webdav/bar',
+ $serverVars = [
+ 'REQUEST_URI' => '/webdav/bar',
'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3',
- 'HTTP_OVERWRITE' => 'F',
- );
+ 'HTTP_OVERWRITE' => 'F',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
@@ -48,19 +48,19 @@ class Issue33Test extends \PHPUnit_Framework_TestCase {
$dir->createDirectory('bar');
$tree = new Tree($dir);
- $tree->move('bar',urldecode('%C3%A0fo%C3%B3'));
+ $tree->move('bar', urldecode('%C3%A0fo%C3%B3'));
$node = $tree->getNodeForPath(urldecode('%C3%A0fo%C3%B3'));
- $this->assertEquals(urldecode('%C3%A0fo%C3%B3'),$node->getName());
+ $this->assertEquals(urldecode('%C3%A0fo%C3%B3'), $node->getName());
}
function testDirName() {
$dirname1 = 'bar';
- $dirname2 = urlencode('%C3%A0fo%C3%B3');;
+ $dirname2 = urlencode('%C3%A0fo%C3%B3');
- $this->assertTrue(dirname($dirname1)==dirname($dirname2));
+ $this->assertTrue(dirname($dirname1) == dirname($dirname2));
}
@@ -71,12 +71,12 @@ class Issue33Test extends \PHPUnit_Framework_TestCase {
function testEverything() {
// Request object
- $serverVars = array(
- 'REQUEST_METHOD' => 'MOVE',
- 'REQUEST_URI' => '/webdav/bar',
+ $serverVars = [
+ 'REQUEST_METHOD' => 'MOVE',
+ 'REQUEST_URI' => '/webdav/bar',
'HTTP_DESTINATION' => 'http://dev2.tribalos.com/webdav/%C3%A0fo%C3%B3',
- 'HTTP_OVERWRITE' => 'F',
- );
+ 'HTTP_OVERWRITE' => 'F',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('');
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php
index f39e9a036..bbde69097 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/AbstractTest.php
@@ -31,15 +31,15 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$lock->timeout = 60;
$lock->created = time();
$lock->token = 'MY-UNIQUE-TOKEN';
- $lock->uri ='someuri';
+ $lock->uri = 'someuri';
$this->assertTrue($backend->lock('someuri', $lock));
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(1,count($locks));
- $this->assertEquals('Sinterklaas',$locks[0]->owner);
- $this->assertEquals('someuri',$locks[0]->uri);
+ $this->assertEquals(1, count($locks));
+ $this->assertEquals('Sinterklaas', $locks[0]->owner);
+ $this->assertEquals('someuri', $locks[0]->uri);
}
@@ -61,9 +61,9 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$locks = $backend->getLocks('someuri/child', false);
- $this->assertEquals(1,count($locks));
- $this->assertEquals('Sinterklaas',$locks[0]->owner);
- $this->assertEquals('someuri',$locks[0]->uri);
+ $this->assertEquals(1, count($locks));
+ $this->assertEquals('Sinterklaas', $locks[0]->owner);
+ $this->assertEquals('someuri', $locks[0]->uri);
}
@@ -86,7 +86,7 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$locks = $backend->getLocks('someuri/child', false);
- $this->assertEquals(0,count($locks));
+ $this->assertEquals(0, count($locks));
}
@@ -104,13 +104,13 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$this->assertTrue($backend->lock('someuri/child', $lock));
$locks = $backend->getLocks('someuri/child', false);
- $this->assertEquals(1,count($locks));
+ $this->assertEquals(1, count($locks));
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(0,count($locks));
+ $this->assertEquals(0, count($locks));
$locks = $backend->getLocks('someuri', true);
- $this->assertEquals(1,count($locks));
+ $this->assertEquals(1, count($locks));
}
@@ -135,10 +135,10 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(1,count($locks));
+ $this->assertEquals(1, count($locks));
- $this->assertEquals('Santa Clause',$locks[0]->owner);
- $this->assertEquals('someuri',$locks[0]->uri);
+ $this->assertEquals('Santa Clause', $locks[0]->owner);
+ $this->assertEquals('someuri', $locks[0]->uri);
}
@@ -158,12 +158,12 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$this->assertTrue($backend->lock('someuri', $lock));
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(1,count($locks));
+ $this->assertEquals(1, count($locks));
- $this->assertTrue($backend->unlock('someuri',$lock));
+ $this->assertTrue($backend->unlock('someuri', $lock));
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(0,count($locks));
+ $this->assertEquals(0, count($locks));
}
@@ -183,13 +183,13 @@ abstract class AbstractTest extends \PHPUnit_Framework_TestCase {
$this->assertTrue($backend->lock('someuri', $lock));
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(1,count($locks));
+ $this->assertEquals(1, count($locks));
$lock->token = 'SOME-OTHER-TOKEN';
- $this->assertFalse($backend->unlock('someuri',$lock));
+ $this->assertFalse($backend->unlock('someuri', $lock));
$locks = $backend->getLocks('someuri', false);
- $this->assertEquals(1,count($locks));
+ $this->assertEquals(1, count($locks));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php
index b6f06224c..0ba02fc8b 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOMySQLTest.php
@@ -2,31 +2,8 @@
namespace Sabre\DAV\Locks\Backend;
-require_once 'Sabre/TestUtil.php';
+class PDOMySQLTest extends PDOTest {
-class PDOMySQLTest extends AbstractTest {
-
- function getBackend() {
-
- if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or it was not properly configured');
- $pdo = \Sabre\TestUtil::getMySQLDB();
- if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
- $pdo->query('DROP TABLE IF EXISTS locks;');
- $pdo->query("
-CREATE TABLE locks (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- owner VARCHAR(100),
- timeout INTEGER UNSIGNED,
- created INTEGER,
- token VARCHAR(100),
- scope TINYINT,
- depth TINYINT,
- uri text
-);");
-
- $backend = new PDO($pdo);
- return $backend;
-
- }
+ public $driver = 'mysql';
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php
index d6336c7b2..a27eae93c 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/Backend/PDOTest.php
@@ -2,27 +2,18 @@
namespace Sabre\DAV\Locks\Backend;
-require_once 'Sabre/TestUtil.php';
-require_once 'Sabre/DAV/Locks/Backend/AbstractTest.php';
+abstract class PDOTest extends AbstractTest {
-class PDOTest extends AbstractTest {
+ use \Sabre\DAV\DbTestHelperTrait;
function getBackend() {
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
- \Sabre\TestUtil::clearTempDir();
- mkdir(SABRE_TEMPDIR . '/pdolocks');
- $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/pdolocks/db.sqlite');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
- $pdo->query('CREATE TABLE locks ( id integer primary key asc, owner text, timeout text, created integer, token text, scope integer, depth integer, uri text)');
- $backend = new PDO($pdo);
- return $backend;
+ $this->dropTables('locks');
+ $this->createSchema('locks');
- }
-
- function tearDown() {
+ $pdo = $this->getPDO();
- \Sabre\TestUtil::clearTempDir();
+ return new PDO($pdo);
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php
index 23f283796..f08f19da5 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/MSWordTest.php
@@ -62,12 +62,12 @@ class MSWordTest extends \PHPUnit_Framework_TestCase {
function getLockRequest() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'LOCK',
'HTTP_CONTENT_TYPE' => 'application/xml',
'HTTP_TIMEOUT' => 'Second-3600',
'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
- ));
+ ]);
$request->setBody('<D:lockinfo xmlns:D="DAV:">
<D:lockscope>
@@ -86,12 +86,12 @@ class MSWordTest extends \PHPUnit_Framework_TestCase {
}
function getLockRequest2() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'LOCK',
'HTTP_CONTENT_TYPE' => 'application/xml',
'HTTP_TIMEOUT' => 'Second-3600',
'REQUEST_URI' => '/~$Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
- ));
+ ]);
$request->setBody('<D:lockinfo xmlns:D="DAV:">
<D:lockscope>
@@ -111,11 +111,11 @@ class MSWordTest extends \PHPUnit_Framework_TestCase {
function getPutRequest($lockToken) {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'PUT',
'REQUEST_URI' => '/Nouveau%20Microsoft%20Office%20Excel%20Worksheet.xlsx',
- 'HTTP_IF' => 'If: ('.$lockToken.')',
- ));
+ 'HTTP_IF' => 'If: (' . $lockToken . ')',
+ ]);
$request->setBody('FAKE BODY');
return $request;
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php
index ef0e473ae..6511d4e7d 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Locks/PluginTest.php
@@ -35,13 +35,13 @@ class PluginTest extends DAV\AbstractServer {
function testGetFeatures() {
- $this->assertEquals(array(2),$this->locksPlugin->getFeatures());
+ $this->assertEquals([2], $this->locksPlugin->getFeatures());
}
function testGetHTTPMethods() {
- $this->assertEquals(array('LOCK','UNLOCK'),$this->locksPlugin->getHTTPMethods(''));
+ $this->assertEquals(['LOCK', 'UNLOCK'], $this->locksPlugin->getHTTPMethods(''));
}
@@ -51,10 +51,10 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ],
$this->response->getHeaders()
);
@@ -77,16 +77,16 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
- $this->assertEquals(200, $this->response->status,'Got an incorrect status back. Response body: ' . $this->response->body);
+ $this->assertEquals(200, $this->response->status, 'Got an incorrect status back. Response body: ' . $this->response->body);
- $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", "xmlns\\1=\"urn:DAV\"", $this->response->body);
$xml = simplexml_load_string($body);
- $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('d', 'urn:DAV');
- $elements = array(
+ $elements = [
'/d:prop',
'/d:prop/d:lockdiscovery',
'/d:prop/d:lockdiscovery/d:activelock',
@@ -101,18 +101,18 @@ class PluginTest extends DAV\AbstractServer {
'/d:prop/d:lockdiscovery/d:activelock/d:timeout',
'/d:prop/d:lockdiscovery/d:activelock/d:locktoken',
'/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href',
- );
+ ];
- foreach($elements as $elem) {
+ foreach ($elements as $elem) {
$data = $xml->xpath($elem);
- $this->assertEquals(1,count($data),'We expected 1 match for the xpath expression "' . $elem . '". ' . count($data) . ' were found. Full response body: ' . $this->response->body);
+ $this->assertEquals(1, count($data), 'We expected 1 match for the xpath expression "' . $elem . '". ' . count($data) . ' were found. Full response body: ' . $this->response->body);
}
$depth = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:depth');
- $this->assertEquals('infinity',(string)$depth[0]);
+ $this->assertEquals('infinity', (string)$depth[0]);
$token = $xml->xpath('/d:prop/d:lockdiscovery/d:activelock/d:locktoken/d:href');
- $this->assertEquals($this->response->getHeader('Lock-Token'),'<' . (string)$token[0] . '>','Token in response body didn\'t match token in response header.');
+ $this->assertEquals($this->response->getHeader('Lock-Token'), '<' . (string)$token[0] . '>', 'Token in response body didn\'t match token in response header.');
}
@@ -139,7 +139,7 @@ class PluginTest extends DAV\AbstractServer {
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
$this->assertEquals(423, $this->response->status, 'Full response: ' . $this->response->body);
@@ -174,9 +174,9 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
- $this->assertEquals(200, $this->response->status,'We received an incorrect status code. Full response body: ' . $this->response->getBody());
+ $this->assertEquals(200, $this->response->status, 'We received an incorrect status code. Full response body: ' . $this->response->getBody());
}
@@ -209,9 +209,9 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
- $this->assertEquals(423, $this->response->getStatus(),'We received an incorrect status code. Full response body: ' . $this->response->getBody());
+ $this->assertEquals(423, $this->response->getStatus(), 'We received an incorrect status code. Full response body: ' . $this->response->getBody());
}
@@ -233,8 +233,8 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(201, $this->response->status);
@@ -251,7 +251,7 @@ class PluginTest extends DAV\AbstractServer {
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Content-Type' => ['application/xml; charset=utf-8'],
],
$this->response->getHeaders()
);
@@ -271,7 +271,7 @@ class PluginTest extends DAV\AbstractServer {
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Content-Type' => ['application/xml; charset=utf-8'],
],
$this->response->getHeaders()
);
@@ -298,8 +298,8 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
@@ -308,8 +308,8 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(423, $this->response->status);
@@ -340,10 +340,10 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpResponse = new HTTP\ResponseMock();
$this->server->invokeMethod($request, $this->server->httpResponse);
- $this->assertEquals(204,$this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
+ $this->assertEquals(204, $this->server->httpResponse->status, 'Got an incorrect status code. Full response body: ' . $this->response->body);
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Length' => ['0'],
+ 'Content-Length' => ['0'],
],
$this->server->httpResponse->getHeaders()
);
@@ -372,17 +372,17 @@ class PluginTest extends DAV\AbstractServer {
$lockToken = $this->server->httpResponse->getHeader('Lock-Token');
// See Issue 123
- $lockToken = trim($lockToken,'<>');
+ $lockToken = trim($lockToken, '<>');
$request = new HTTP\Request('UNLOCK', '/test.txt', ['Lock-Token' => $lockToken]);
$this->server->httpRequest = $request;
$this->server->httpResponse = new HTTP\ResponseMock();
$this->server->invokeMethod($request, $this->server->httpResponse);
- $this->assertEquals(204, $this->server->httpResponse->status,'Got an incorrect status code. Full response body: ' . $this->response->body);
+ $this->assertEquals(204, $this->server->httpResponse->status, 'Got an incorrect status code. Full response body: ' . $this->response->body);
$this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Length' => ['0'],
+ 'Content-Length' => ['0'],
],
$this->server->httpResponse->getHeaders()
);
@@ -396,7 +396,7 @@ class PluginTest extends DAV\AbstractServer {
function testLockRetainOwner() {
$request = HTTP\Sapi::createFromServerArray([
- 'REQUEST_URI' => '/test.txt',
+ 'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'LOCK',
]);
$this->server->httpRequest = $request;
@@ -412,8 +412,8 @@ class PluginTest extends DAV\AbstractServer {
$lockToken = $this->server->httpResponse->getHeader('Lock-Token');
$locks = $this->locksPlugin->getLocks('test.txt');
- $this->assertEquals(1,count($locks));
- $this->assertEquals('Evert',$locks[0]->owner);
+ $this->assertEquals(1, count($locks));
+ $this->assertEquals('Evert', $locks[0]->owner);
}
@@ -423,10 +423,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockPutBadToken() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -441,24 +441,24 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'PUT',
- 'HTTP_IF' => '(<opaquelocktoken:token1>)',
- );
+ 'HTTP_IF' => '(<opaquelocktoken:token1>)',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('newbody');
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
// $this->assertEquals('412 Precondition failed',$this->response->status);
$this->assertEquals(423, $this->response->status);
@@ -470,10 +470,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockDeleteParent() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -488,22 +488,22 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir',
'REQUEST_METHOD' => 'DELETE',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
$this->assertEquals(423, $this->response->status);
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
/**
@@ -511,10 +511,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockDeleteSucceed() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -529,23 +529,23 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child.txt',
'REQUEST_METHOD' => 'DELETE',
- 'HTTP_IF' => '(' . $this->response->getHeader('Lock-Token') . ')',
- );
+ 'HTTP_IF' => '(' . $this->response->getHeader('Lock-Token') . ')',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
$this->assertEquals(204, $this->response->status);
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
@@ -554,10 +554,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockCopyLockSource() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -572,23 +572,23 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
- 'REQUEST_URI' => '/dir/child.txt',
- 'REQUEST_METHOD' => 'COPY',
+ $serverVars = [
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'COPY',
'HTTP_DESTINATION' => '/dir/child2.txt',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(201, $this->response->status,'Copy must succeed if only the source is locked, but not the destination');
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals(201, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
/**
@@ -596,10 +596,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockCopyLockDestination() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child2.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -614,23 +614,23 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(201, $this->response->status);
- $serverVars = array(
- 'REQUEST_URI' => '/dir/child.txt',
- 'REQUEST_METHOD' => 'COPY',
+ $serverVars = [
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'COPY',
'HTTP_DESTINATION' => '/dir/child2.txt',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(423, $this->response->status,'Copy must succeed if only the source is locked, but not the destination');
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals(423, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
@@ -639,10 +639,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockMoveLockSourceLocked() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -657,23 +657,23 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
- 'REQUEST_URI' => '/dir/child.txt',
- 'REQUEST_METHOD' => 'MOVE',
+ $serverVars = [
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
'HTTP_DESTINATION' => '/dir/child2.txt',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(423, $this->response->status,'Copy must succeed if only the source is locked, but not the destination');
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals(423, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
@@ -682,10 +682,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockMoveLockSourceSucceed() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -700,23 +700,23 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
- 'REQUEST_URI' => '/dir/child.txt',
- 'REQUEST_METHOD' => 'MOVE',
+ $serverVars = [
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
'HTTP_DESTINATION' => '/dir/child2.txt',
- 'HTTP_IF' => '(' . $this->response->getHeader('Lock-Token') . ')',
- );
+ 'HTTP_IF' => '(' . $this->response->getHeader('Lock-Token') . ')',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(201, $this->response->status,'A valid lock-token was provided for the source, so this MOVE operation must succeed. Full response body: ' . $this->response->body);
+ $this->assertEquals(201, $this->response->status, 'A valid lock-token was provided for the source, so this MOVE operation must succeed. Full response body: ' . $this->response->body);
}
@@ -725,10 +725,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockMoveLockDestination() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir/child2.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -743,23 +743,23 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(201, $this->response->status);
- $serverVars = array(
- 'REQUEST_URI' => '/dir/child.txt',
- 'REQUEST_METHOD' => 'MOVE',
+ $serverVars = [
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
'HTTP_DESTINATION' => '/dir/child2.txt',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(423, $this->response->status,'Copy must succeed if only the source is locked, but not the destination');
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals(423, $this->response->status, 'Copy must succeed if only the source is locked, but not the destination');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
/**
@@ -767,11 +767,11 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockMoveLockParent() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir',
'REQUEST_METHOD' => 'LOCK',
- 'HTTP_DEPTH' => 'infinite',
- );
+ 'HTTP_DEPTH' => 'infinite',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -786,24 +786,24 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
- $this->assertEquals(200,$this->response->status);
+ $this->assertEquals(200, $this->response->status);
- $serverVars = array(
- 'REQUEST_URI' => '/dir/child.txt',
- 'REQUEST_METHOD' => 'MOVE',
+ $serverVars = [
+ 'REQUEST_URI' => '/dir/child.txt',
+ 'REQUEST_METHOD' => 'MOVE',
'HTTP_DESTINATION' => '/dir/child2.txt',
- 'HTTP_IF' => '</dir> (' . $this->response->getHeader('Lock-Token') . ')',
- );
+ 'HTTP_IF' => '</dir> (' . $this->response->getHeader('Lock-Token') . ')',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(201, $this->response->status,'We locked the parent of both the source and destination, but the move didn\'t succeed.');
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
+ $this->assertEquals(201, $this->response->status, 'We locked the parent of both the source and destination, but the move didn\'t succeed.');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
}
@@ -812,10 +812,10 @@ class PluginTest extends DAV\AbstractServer {
*/
function testLockPutGoodToken() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'LOCK',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -830,24 +830,24 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(200, $this->response->status);
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'PUT',
- 'HTTP_IF' => '('.$this->response->getHeader('Lock-Token').')',
- );
+ 'HTTP_IF' => '(' . $this->response->getHeader('Lock-Token') . ')',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('newbody');
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(204, $this->response->status);
@@ -871,22 +871,22 @@ class PluginTest extends DAV\AbstractServer {
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(201, $this->response->getStatus());
$request = new HTTP\Request(
'PUT',
'/test.txt',
- ['If' => '</unrelated.txt> ('.$this->response->getHeader('Lock-Token').')']
+ ['If' => '</unrelated.txt> (' . $this->response->getHeader('Lock-Token') . ')']
);
$request->setBody('newbody');
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
$this->assertEquals(204, $this->response->status);
@@ -894,11 +894,11 @@ class PluginTest extends DAV\AbstractServer {
function testPutWithIncorrectETag() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'PUT',
- 'HTTP_IF' => '(["etag1"])',
- );
+ 'HTTP_IF' => '(["etag1"])',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('newbody');
@@ -920,14 +920,14 @@ class PluginTest extends DAV\AbstractServer {
$filename = SABRE_TEMPDIR . '/test.txt';
$etag = sha1(
fileinode($filename) .
- filesize($filename ) .
+ filesize($filename) .
filemtime($filename)
);
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'PUT',
- 'HTTP_IF' => '(["'.$etag.'"])',
- );
+ 'HTTP_IF' => '(["' . $etag . '"])',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('newbody');
@@ -939,11 +939,11 @@ class PluginTest extends DAV\AbstractServer {
function testDeleteWithETagOnCollection() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/dir',
'REQUEST_METHOD' => 'DELETE',
- 'HTTP_IF' => '(["etag1"])',
- );
+ 'HTTP_IF' => '(["etag1"])',
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = $request;
@@ -954,9 +954,9 @@ class PluginTest extends DAV\AbstractServer {
function testGetTimeoutHeader() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'HTTP_TIMEOUT' => 'second-100',
- ));
+ ]);
$this->server->httpRequest = $request;
$this->assertEquals(100, $this->locksPlugin->getTimeoutHeader());
@@ -965,9 +965,9 @@ class PluginTest extends DAV\AbstractServer {
function testGetTimeoutHeaderTwoItems() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'HTTP_TIMEOUT' => 'second-5, infinite',
- ));
+ ]);
$this->server->httpRequest = $request;
$this->assertEquals(5, $this->locksPlugin->getTimeoutHeader());
@@ -976,9 +976,9 @@ class PluginTest extends DAV\AbstractServer {
function testGetTimeoutHeaderInfinite() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'HTTP_TIMEOUT' => 'infinite, second-5',
- ));
+ ]);
$this->server->httpRequest = $request;
$this->assertEquals(LockInfo::TIMEOUT_INFINITE, $this->locksPlugin->getTimeoutHeader());
@@ -990,9 +990,9 @@ class PluginTest extends DAV\AbstractServer {
*/
function testGetTimeoutHeaderInvalid() {
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'HTTP_TIMEOUT' => 'yourmom',
- ));
+ ]);
$this->server->httpRequest = $request;
$this->locksPlugin->getTimeoutHeader();
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php
index e6415792c..3213fcb1b 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/Mount/PluginTest.php
@@ -18,27 +18,27 @@ class PluginTest extends DAV\AbstractServer {
function testPassThrough() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'GET',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(501, $this->response->status,'We expected GET to not be implemented for Directories. Response body: ' . $this->response->body);
+ $this->assertEquals(501, $this->response->status, 'We expected GET to not be implemented for Directories. Response body: ' . $this->response->body);
}
function testMountResponse() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/?mount',
'REQUEST_METHOD' => 'GET',
'QUERY_STRING' => 'mount',
'HTTP_HOST' => 'example.org',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = ($request);
@@ -47,11 +47,11 @@ class PluginTest extends DAV\AbstractServer {
$this->assertEquals(200, $this->response->status);
$xml = simplexml_load_string($this->response->body);
- $this->assertInstanceOf('SimpleXMLElement',$xml, 'Response was not a valid xml document. The list of errors:' . print_r(libxml_get_errors(),true) . '. xml body: ' . $this->response->body . '. What type we got: ' . gettype($xml) . ' class, if object: ' . get_class($xml));
+ $this->assertInstanceOf('SimpleXMLElement', $xml, 'Response was not a valid xml document. The list of errors:' . print_r(libxml_get_errors(), true) . '. xml body: ' . $this->response->body . '. What type we got: ' . gettype($xml) . ' class, if object: ' . get_class($xml));
- $xml->registerXPathNamespace('dm','http://purl.org/NET/webdav/mount');
+ $xml->registerXPathNamespace('dm', 'http://purl.org/NET/webdav/mount');
$url = $xml->xpath('//dm:url');
- $this->assertEquals('http://example.org/',(string)$url[0]);
+ $this->assertEquals('http://example.org/', (string)$url[0]);
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php
index 9b7eeb90c..15289ce52 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ObjectTreeTest.php
@@ -13,8 +13,8 @@ class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
\Sabre\TestUtil::clearTempDir();
mkdir(SABRE_TEMPDIR . '/root');
mkdir(SABRE_TEMPDIR . '/root/subdir');
- file_put_contents(SABRE_TEMPDIR . '/root/file.txt','contents');
- file_put_contents(SABRE_TEMPDIR . '/root/subdir/subfile.txt','subcontents');
+ file_put_contents(SABRE_TEMPDIR . '/root/file.txt', 'contents');
+ file_put_contents(SABRE_TEMPDIR . '/root/subdir/subfile.txt', 'subcontents');
$rootNode = new FSExt\Directory(SABRE_TEMPDIR . '/root');
$this->tree = new Tree($rootNode);
@@ -29,22 +29,22 @@ class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
function testGetRootNode() {
$root = $this->tree->getNodeForPath('');
- $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory',$root);
+ $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory', $root);
}
function testGetSubDir() {
$root = $this->tree->getNodeForPath('subdir');
- $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory',$root);
+ $this->assertInstanceOf('Sabre\\DAV\\FSExt\\Directory', $root);
}
function testCopyFile() {
- $this->tree->copy('file.txt','file2.txt');
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt'));
- $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/file2.txt'));
+ $this->tree->copy('file.txt', 'file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/file2.txt'));
+ $this->assertEquals('contents', file_get_contents(SABRE_TEMPDIR . '/root/file2.txt'));
}
@@ -53,10 +53,10 @@ class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
*/
function testCopyDirectory() {
- $this->tree->copy('subdir','subdir2');
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2'));
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
- $this->assertEquals('subcontents',file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
+ $this->tree->copy('subdir', 'subdir2');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/subdir2'));
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/subdir2/subfile.txt'));
+ $this->assertEquals('subcontents', file_get_contents(SABRE_TEMPDIR . '/root/subdir2/subfile.txt'));
}
@@ -65,10 +65,10 @@ class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
*/
function testMoveFile() {
- $this->tree->move('file.txt','file2.txt');
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/file2.txt'));
- $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt'));
- $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/file2.txt'));
+ $this->tree->move('file.txt', 'file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/file2.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/root/file.txt'));
+ $this->assertEquals('contents', file_get_contents(SABRE_TEMPDIR . '/root/file2.txt'));
}
@@ -77,10 +77,10 @@ class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
*/
function testMoveFileNewParent() {
- $this->tree->move('file.txt','subdir/file2.txt');
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir/file2.txt'));
- $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/file.txt'));
- $this->assertEquals('contents',file_get_contents(SABRE_TEMPDIR.'/root/subdir/file2.txt'));
+ $this->tree->move('file.txt', 'subdir/file2.txt');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/subdir/file2.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/root/file.txt'));
+ $this->assertEquals('contents', file_get_contents(SABRE_TEMPDIR . '/root/subdir/file2.txt'));
}
@@ -89,11 +89,11 @@ class ObjectTreeTest extends \PHPUnit_Framework_TestCase {
*/
function testMoveDirectory() {
- $this->tree->move('subdir','subdir2');
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2'));
- $this->assertTrue(file_exists(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
- $this->assertFalse(file_exists(SABRE_TEMPDIR.'/root/subdir'));
- $this->assertEquals('subcontents',file_get_contents(SABRE_TEMPDIR.'/root/subdir2/subfile.txt'));
+ $this->tree->move('subdir', 'subdir2');
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/subdir2'));
+ $this->assertTrue(file_exists(SABRE_TEMPDIR . '/root/subdir2/subfile.txt'));
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/root/subdir'));
+ $this->assertEquals('subcontents', file_get_contents(SABRE_TEMPDIR . '/root/subdir2/subfile.txt'));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php
index d6cc406be..eff1e7d67 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/FileMock.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\DAV\PartialUpdate;
+
use Sabre\DAV;
class FileMock implements IPatchSupport {
@@ -49,10 +50,10 @@ class FileMock implements IPatchSupport {
$data = stream_get_contents($data);
}
- switch($rangeType) {
+ switch ($rangeType) {
case 1 :
- $this->data.=$data;
+ $this->data .= $data;
break;
case 3 :
// Turn the offset into an offset-offset.
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php
index 31be2a1b1..ca8ca3f6e 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/PartialUpdate/SpecificationTest.php
@@ -16,11 +16,11 @@ class SpecificationTest extends \PHPUnit_Framework_TestCase {
protected $server;
- public function setUp() {
+ function setUp() {
- $tree = array(
+ $tree = [
new File(SABRE_TEMPDIR . '/foobar.txt')
- );
+ ];
$server = new Server($tree);
$server->debugExceptions = true;
$server->addPlugin(new Plugin());
@@ -31,7 +31,7 @@ class SpecificationTest extends \PHPUnit_Framework_TestCase {
}
- public function tearDown() {
+ function tearDown() {
\Sabre\TestUtil::clearTempDir();
@@ -40,10 +40,10 @@ class SpecificationTest extends \PHPUnit_Framework_TestCase {
/**
* @dataProvider data
*/
- public function testUpdateRange($headerValue, $httpStatus, $endResult, $contentLength = 4) {
+ function testUpdateRange($headerValue, $httpStatus, $endResult, $contentLength = 4) {
$headers = [
- 'Content-Type' => 'application/x-sabredav-partialupdate',
+ 'Content-Type' => 'application/x-sabredav-partialupdate',
'X-Update-Range' => $headerValue,
];
@@ -64,25 +64,25 @@ class SpecificationTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals($endResult, file_get_contents(SABRE_TEMPDIR . '/foobar.txt'));
}
- }
+ }
- public function data() {
+ function data() {
- return array(
+ return [
// Problems
- array('foo', 400, null),
- array('bytes=0-3', 411, null, 0),
- array('bytes=4-1', 416, null),
-
- array('bytes=0-3', 204, '----567890'),
- array('bytes=1-4', 204, '1----67890'),
- array('bytes=0-', 204, '----567890'),
- array('bytes=-4', 204, '123456----'),
- array('bytes=-2', 204, '12345678----'),
- array('bytes=2-', 204, '12----7890'),
- array('append', 204, '1234567890----'),
-
- );
+ ['foo', 400, null],
+ ['bytes=0-3', 411, null, 0],
+ ['bytes=4-1', 416, null],
+
+ ['bytes=0-3', 204, '----567890'],
+ ['bytes=1-4', 204, '1----67890'],
+ ['bytes=0-', 204, '----567890'],
+ ['bytes=-4', 204, '123456----'],
+ ['bytes=-2', 204, '12345678----'],
+ ['bytes=2-', 204, '12----7890'],
+ ['append', 204, '1234567890----'],
+
+ ];
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php
index 6ac20d2da..4c576f108 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerEventsTest.php
@@ -31,7 +31,9 @@ class ServerEventsTest extends AbstractServer {
function testAfterResponse() {
- $mock = $this->getMock('stdClass', ['afterResponseCallback']);
+ $mock = $this->getMockBuilder('stdClass')
+ ->setMethods(['afterResponseCallback'])
+ ->getMock();
$mock->expects($this->once())->method('afterResponseCallback');
$this->server->on('afterResponse', [$mock, 'afterResponseCallback']);
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php
index e35189ec3..557eddbbc 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerMKCOLTest.php
@@ -8,20 +8,20 @@ class ServerMKCOLTest extends AbstractServer {
function testMkcol() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/testcol',
'REQUEST_METHOD' => 'MKCOL',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody("");
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- ),$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ ], $this->response->getHeaders());
$this->assertEquals(201, $this->response->status);
$this->assertEquals('', $this->response->body);
@@ -34,20 +34,20 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLUnknownBody() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/testcol',
'REQUEST_METHOD' => 'MKCOL',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody("Hello");
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
$this->assertEquals(415, $this->response->status);
@@ -58,23 +58,23 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLBrokenXML() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
+ $serverVars = [
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody("Hello");
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
- $this->assertEquals(400, $this->response->getStatus(), $this->response->getBodyAsString() );
+ $this->assertEquals(400, $this->response->getStatus(), $this->response->getBodyAsString());
}
@@ -83,21 +83,21 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLUnknownXML() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
+ $serverVars = [
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?><html></html>');
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
$this->assertEquals(400, $this->response->getStatus());
@@ -108,11 +108,11 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLNoResourceType() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
+ $serverVars = [
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -126,12 +126,12 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
- $this->assertEquals(400, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(400, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -140,11 +140,11 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLIncorrectResourceType() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
+ $serverVars = [
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -158,12 +158,12 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
- $this->assertEquals(403, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(403, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -172,11 +172,11 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLSuccess() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
+ $serverVars = [
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -190,12 +190,12 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- ),$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ ], $this->response->getHeaders());
- $this->assertEquals(201, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(201, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -204,11 +204,11 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLWhiteSpaceResourceType() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
+ $serverVars = [
+ 'REQUEST_URI' => '/testcol',
+ 'REQUEST_METHOD' => 'MKCOL',
'HTTP_CONTENT_TYPE' => 'application/xml',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
@@ -224,12 +224,12 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Length' => ['0'],
- ),$this->response->getHeaders());
+ 'Content-Length' => ['0'],
+ ], $this->response->getHeaders());
- $this->assertEquals(201, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(201, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -238,10 +238,10 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLNoParent() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/testnoparent/409me',
'REQUEST_METHOD' => 'MKCOL',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('');
@@ -249,12 +249,12 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
- $this->assertEquals(409, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(409, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -263,10 +263,10 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLParentIsNoCollection() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt/409me',
'REQUEST_METHOD' => 'MKCOL',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('');
@@ -274,12 +274,12 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
- $this->assertEquals(409, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(409, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -288,10 +288,10 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLAlreadyExists() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/test.txt',
'REQUEST_METHOD' => 'MKCOL',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('');
@@ -299,13 +299,13 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT'],
+ ], $this->response->getHeaders());
- $this->assertEquals(405, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(405, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
}
@@ -315,13 +315,11 @@ class ServerMKCOLTest extends AbstractServer {
*/
function testMKCOLAndProps() {
- $serverVars = array(
- 'REQUEST_URI' => '/testcol',
- 'REQUEST_METHOD' => 'MKCOL',
- 'HTTP_CONTENT_TYPE' => 'application/xml',
+ $request = new HTTP\Request(
+ 'MKCOL',
+ '/testcol',
+ ['Content-Type' => 'application/xml']
);
-
- $request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody('<?xml version="1.0"?>
<mkcol xmlns="DAV:">
<set>
@@ -334,12 +332,34 @@ class ServerMKCOLTest extends AbstractServer {
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(207, $this->response->status, 'Wrong statuscode received. Full response body: ' .$this->response->body);
+ $this->assertEquals(207, $this->response->status, 'Wrong statuscode received. Full response body: ' . $this->response->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $this->response->getHeaders());
+
+ $responseBody = $this->response->getBodyAsString();
+
+ $expected = <<<XML
+<?xml version="1.0"?>
+<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
+ <d:response>
+ <d:href>/testcol</d:href>
+ <d:propstat>
+ <d:prop>
+ <d:displayname />
+ </d:prop>
+ <d:status>HTTP/1.1 403 Forbidden</d:status>
+ </d:propstat>
+ </d:response>
+</d:multistatus>
+XML;
+
+ $this->assertXmlStringEqualsXmlString(
+ $expected,
+ $responseBody
+ );
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php
index ab0ad295e..fa67102cc 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPluginTest.php
@@ -1,6 +1,7 @@
<?php
namespace Sabre\DAV;
+
use Sabre\HTTP;
require_once 'Sabre/DAV/AbstractServer.php';
@@ -28,13 +29,13 @@ class ServerPluginTest extends AbstractServer {
function testBaseClass() {
$p = new ServerPluginMock();
- $this->assertEquals([],$p->getFeatures());
- $this->assertEquals([],$p->getHTTPMethods(''));
+ $this->assertEquals([], $p->getFeatures());
+ $this->assertEquals([], $p->getHTTPMethods(''));
$this->assertEquals(
[
- 'name' => 'Sabre\DAV\ServerPluginMock',
+ 'name' => 'Sabre\DAV\ServerPluginMock',
'description' => null,
- 'link' => null
+ 'link' => null
], $p->getPluginInfo()
);
@@ -42,34 +43,34 @@ class ServerPluginTest extends AbstractServer {
function testOptions() {
- $serverVars = array(
+ $serverVars = [
'REQUEST_URI' => '/',
'REQUEST_METHOD' => 'OPTIONS',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(array(
+ $this->assertEquals([
'DAV' => ['1, 3, extended-mkcol, drinking'],
'MS-Author-Via' => ['DAV'],
'Allow' => ['OPTIONS, GET, HEAD, DELETE, PROPFIND, PUT, PROPPATCH, COPY, MOVE, REPORT, BEER, WINE'],
'Accept-Ranges' => ['bytes'],
'Content-Length' => ['0'],
'X-Sabre-Version' => [Version::VERSION],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
$this->assertEquals(200, $this->response->status);
$this->assertEquals('', $this->response->body);
- $this->assertEquals('OPTIONS',$this->testPlugin->beforeMethod);
+ $this->assertEquals('OPTIONS', $this->testPlugin->beforeMethod);
}
function testGetPlugin() {
- $this->assertEquals($this->testPlugin,$this->server->getPlugin(get_class($this->testPlugin)));
+ $this->assertEquals($this->testPlugin, $this->server->getPlugin(get_class($this->testPlugin)));
}
@@ -81,17 +82,17 @@ class ServerPluginTest extends AbstractServer {
function testGetSupportedReportSet() {
- $this->assertEquals(array(), $this->testPlugin->getSupportedReportSet('/'));
+ $this->assertEquals([], $this->testPlugin->getSupportedReportSet('/'));
}
function testGetPlugins() {
$this->assertEquals(
- array(
+ [
get_class($this->testPlugin) => $this->testPlugin,
- 'core' => $this->server->getPlugin('core'),
- ),
+ 'core' => $this->server->getPlugin('core'),
+ ],
$this->server->getPlugins()
);
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php
index 1dc8d8a37..203cf26d9 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerPreconditionTest.php
@@ -13,7 +13,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfMatchNoNode() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/bar', ['If-Match' => '*']);
$httpResponse = new HTTP\Response();
@@ -25,7 +25,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfMatchHasNode() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '*']);
$httpResponse = new HTTP\Response();
@@ -38,7 +38,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfMatchWrongEtag() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '1234']);
$httpResponse = new HTTP\Response();
@@ -50,7 +50,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfMatchCorrectEtag() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '"abc123"']);
$httpResponse = new HTTP\Response();
@@ -65,7 +65,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfMatchEvolutionEtag() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '\\"abc123\\"']);
$httpResponse = new HTTP\Response();
@@ -77,7 +77,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfMatchMultiple() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/foo', ['If-Match' => '"hellothere", "abc123"']);
$httpResponse = new HTTP\Response();
@@ -89,7 +89,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfNoneMatchNoNode() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/bar', ['If-None-Match' => '*']);
$httpResponse = new HTTP\Response();
@@ -102,7 +102,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfNoneMatchHasNode() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '*']);
$httpResponse = new HTTP\Response();
@@ -114,7 +114,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfNoneMatchWrongEtag() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"1234"']);
$httpResponse = new HTTP\Response();
@@ -126,7 +126,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
*/
function testIfNoneMatchWrongEtagMultiple() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"1234", "5678"']);
$httpResponse = new HTTP\Response();
@@ -137,9 +137,9 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\PreconditionFailed
*/
- public function testIfNoneMatchCorrectEtag() {
+ function testIfNoneMatchCorrectEtag() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"abc123"']);
$httpResponse = new HTTP\Response();
@@ -150,9 +150,9 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\PreconditionFailed
*/
- public function testIfNoneMatchCorrectEtagMultiple() {
+ function testIfNoneMatchCorrectEtagMultiple() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('POST', '/foo', ['If-None-Match' => '"1234, "abc123"']);
$httpResponse = new HTTP\Response();
@@ -162,9 +162,9 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
*/
- public function testIfNoneMatchCorrectEtagAsGet() {
+ function testIfNoneMatchCorrectEtagAsGet() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$httpRequest = new HTTP\Request('GET', '/foo', ['If-None-Match' => '"abc123"']);
$server->httpResponse = new HTTP\ResponseMock();
@@ -178,9 +178,9 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
* This was a test written for issue #515.
*/
- public function testNoneMatchCorrectEtagEnsureSapiSent() {
+ function testNoneMatchCorrectEtagEnsureSapiSent() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
$server->sapi = new HTTP\SapiMock();
HTTP\SapiMock::$sent = 0;
@@ -193,7 +193,7 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
$this->assertFalse($server->checkPreconditions($httpRequest, $server->httpResponse));
$this->assertEquals(304, $server->httpResponse->getStatus());
$this->assertEquals([
- 'ETag' => ['"abc123"'],
+ 'ETag' => ['"abc123"'],
'X-Sabre-Version' => [Version::VERSION],
], $server->httpResponse->getHeaders());
$this->assertEquals(1, HTTP\SapiMock::$sent);
@@ -202,35 +202,35 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
*/
- public function testIfModifiedSinceUnModified() {
+ function testIfModifiedSinceUnModified() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$server->httpResponse = new HTTP\ResponseMock();
$this->assertFalse($server->checkPreconditions($httpRequest, $server->httpResponse));
$this->assertEquals(304, $server->httpResponse->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'Last-Modified' => ['Sat, 06 Apr 1985 23:30:00 GMT'],
- ), $server->httpResponse->getHeaders());
+ ], $server->httpResponse->getHeaders());
}
/**
*/
- public function testIfModifiedSinceModified() {
+ function testIfModifiedSinceModified() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_MODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$httpResponse = new HTTP\ResponseMock();
$this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
@@ -239,14 +239,14 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
*/
- public function testIfModifiedSinceInvalidDate() {
+ function testIfModifiedSinceInvalidDate() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_MODIFIED_SINCE' => 'Your mother',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$httpResponse = new HTTP\ResponseMock();
// Invalid dates must be ignored, so this should return true
@@ -256,14 +256,14 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
*/
- public function testIfModifiedSinceInvalidDate2() {
+ function testIfModifiedSinceInvalidDate2() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_MODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 EST',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$httpResponse = new HTTP\ResponseMock();
$this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
@@ -272,14 +272,14 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
*/
- public function testIfUnmodifiedSinceUnModified() {
+ function testIfUnmodifiedSinceUnModified() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1994 08:49:37 GMT',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$httpResponse = new HTTP\Response();
$this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
@@ -289,14 +289,14 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\PreconditionFailed
*/
- public function testIfUnmodifiedSinceModified() {
+ function testIfUnmodifiedSinceModified() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_UNMODIFIED_SINCE' => 'Tue, 06 Nov 1984 08:49:37 GMT',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$httpResponse = new HTTP\ResponseMock();
$server->checkPreconditions($httpRequest, $httpResponse);
@@ -304,14 +304,14 @@ class ServerPreconditionsTest extends \PHPUnit_Framework_TestCase {
/**
*/
- public function testIfUnmodifiedSinceInvalidDate() {
+ function testIfUnmodifiedSinceInvalidDate() {
- $root = new SimpleCollection('root',array(new ServerPreconditionsNode()));
+ $root = new SimpleCollection('root', [new ServerPreconditionsNode()]);
$server = new Server($root);
- $httpRequest = HTTP\Sapi::createFromServerArray(array(
+ $httpRequest = HTTP\Sapi::createFromServerArray([
'HTTP_IF_UNMODIFIED_SINCE' => 'Sun, 06 Nov 1984 08:49:37 CET',
- 'REQUEST_URI' => '/foo'
- ));
+ 'REQUEST_URI' => '/foo'
+ ]);
$httpResponse = new HTTP\ResponseMock();
$this->assertTrue($server->checkPreconditions($httpRequest, $httpResponse));
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php
index 66dde9db8..043179a00 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerSimpleTest.php
@@ -463,7 +463,7 @@ class ServerSimpleTest extends AbstractServer{
* There are certain cases where no HTTP status may be set. We need to
* intercept these and set it to a default error message.
*/
- function testNoHTTPSTatusSet() {
+ function testNoHTTPStatusSet() {
$this->server->on('method:GET', function() { return false; }, 1);
$this->server->httpRequest = new HTTP\Request('GET', '/');
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php
index 7fde11b22..383f8e657 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/ServerUpdatePropertiesTest.php
@@ -1,101 +1,100 @@
<?php
namespace Sabre\DAV;
-use Sabre\HTTP;
class ServerUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
function testUpdatePropertiesFail() {
- $tree = array(
+ $tree = [
new SimpleCollection('foo'),
- );
+ ];
$server = new Server($tree);
- $result = $server->updateProperties('foo', array(
+ $result = $server->updateProperties('foo', [
'{DAV:}foo' => 'bar'
- ));
+ ]);
- $expected = array(
+ $expected = [
'{DAV:}foo' => 403,
- );
+ ];
$this->assertEquals($expected, $result);
}
function testUpdatePropertiesProtected() {
- $tree = array(
+ $tree = [
new SimpleCollection('foo'),
- );
+ ];
$server = new Server($tree);
$server->on('propPatch', function($path, PropPatch $propPatch) {
$propPatch->handleRemaining(function() { return true; });
});
- $result = $server->updateProperties('foo', array(
+ $result = $server->updateProperties('foo', [
'{DAV:}getetag' => 'bla',
- '{DAV:}foo' => 'bar'
- ));
+ '{DAV:}foo' => 'bar'
+ ]);
- $expected = array(
+ $expected = [
'{DAV:}getetag' => 403,
- '{DAV:}foo' => 424,
- );
+ '{DAV:}foo' => 424,
+ ];
$this->assertEquals($expected, $result);
}
function testUpdatePropertiesEventFail() {
- $tree = array(
+ $tree = [
new SimpleCollection('foo'),
- );
+ ];
$server = new Server($tree);
$server->on('propPatch', function($path, PropPatch $propPatch) {
$propPatch->setResultCode('{DAV:}foo', 404);
$propPatch->handleRemaining(function() { return true; });
});
- $result = $server->updateProperties('foo', array(
- '{DAV:}foo' => 'bar',
+ $result = $server->updateProperties('foo', [
+ '{DAV:}foo' => 'bar',
'{DAV:}foo2' => 'bla',
- ));
+ ]);
- $expected = array(
- '{DAV:}foo' => 404,
+ $expected = [
+ '{DAV:}foo' => 404,
'{DAV:}foo2' => 424,
- );
+ ];
$this->assertEquals($expected, $result);
}
function testUpdatePropertiesEventSuccess() {
- $tree = array(
+ $tree = [
new SimpleCollection('foo'),
- );
+ ];
$server = new Server($tree);
$server->on('propPatch', function($path, PropPatch $propPatch) {
$propPatch->handle(['{DAV:}foo', '{DAV:}foo2'], function() {
return [
- '{DAV:}foo' => 200,
+ '{DAV:}foo' => 200,
'{DAV:}foo2' => 201,
];
});
});
- $result = $server->updateProperties('foo', array(
- '{DAV:}foo' => 'bar',
+ $result = $server->updateProperties('foo', [
+ '{DAV:}foo' => 'bar',
'{DAV:}foo2' => 'bla',
- ));
+ ]);
- $expected = array(
- '{DAV:}foo' => 200,
+ $expected = [
+ '{DAV:}foo' => 200,
'{DAV:}foo2' => 201,
- );
+ ];
$this->assertEquals($expected, $result);
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php
index 9b083b998..15ccfaf9e 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/SimpleFileTest.php
@@ -6,7 +6,7 @@ class SimpleFileTest extends \PHPUnit_Framework_TestCase {
function testAll() {
- $file = new SimpleFile('filename.txt','contents','text/plain');
+ $file = new SimpleFile('filename.txt', 'contents', 'text/plain');
$this->assertEquals('filename.txt', $file->getName());
$this->assertEquals('contents', $file->get());
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php
index 941d1f913..8888f0276 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/StringUtilTest.php
@@ -15,61 +15,61 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase {
function dataset() {
- return array(
- array('FOOBAR', 'FOO', 'i;octet', 'contains', true),
- array('FOOBAR', 'foo', 'i;octet', 'contains', false),
- array('FÖÖBAR', 'FÖÖ', 'i;octet', 'contains', true),
- array('FÖÖBAR', 'föö', 'i;octet', 'contains', false),
- array('FOOBAR', 'FOOBAR', 'i;octet', 'equals', true),
- array('FOOBAR', 'fooBAR', 'i;octet', 'equals', false),
- array('FOOBAR', 'FOO', 'i;octet', 'starts-with', true),
- array('FOOBAR', 'foo', 'i;octet', 'starts-with', false),
- array('FOOBAR', 'BAR', 'i;octet', 'starts-with', false),
- array('FOOBAR', 'bar', 'i;octet', 'starts-with', false),
- array('FOOBAR', 'FOO', 'i;octet', 'ends-with', false),
- array('FOOBAR', 'foo', 'i;octet', 'ends-with', false),
- array('FOOBAR', 'BAR', 'i;octet', 'ends-with', true),
- array('FOOBAR', 'bar', 'i;octet', 'ends-with', false),
-
- array('FOOBAR', 'FOO', 'i;ascii-casemap', 'contains', true),
- array('FOOBAR', 'foo', 'i;ascii-casemap', 'contains', true),
- array('FÖÖBAR', 'FÖÖ', 'i;ascii-casemap', 'contains', true),
- array('FÖÖBAR', 'föö', 'i;ascii-casemap', 'contains', false),
- array('FOOBAR', 'FOOBAR', 'i;ascii-casemap', 'equals', true),
- array('FOOBAR', 'fooBAR', 'i;ascii-casemap', 'equals', true),
- array('FOOBAR', 'FOO', 'i;ascii-casemap', 'starts-with', true),
- array('FOOBAR', 'foo', 'i;ascii-casemap', 'starts-with', true),
- array('FOOBAR', 'BAR', 'i;ascii-casemap', 'starts-with', false),
- array('FOOBAR', 'bar', 'i;ascii-casemap', 'starts-with', false),
- array('FOOBAR', 'FOO', 'i;ascii-casemap', 'ends-with', false),
- array('FOOBAR', 'foo', 'i;ascii-casemap', 'ends-with', false),
- array('FOOBAR', 'BAR', 'i;ascii-casemap', 'ends-with', true),
- array('FOOBAR', 'bar', 'i;ascii-casemap', 'ends-with', true),
-
- array('FOOBAR', 'FOO', 'i;unicode-casemap', 'contains', true),
- array('FOOBAR', 'foo', 'i;unicode-casemap', 'contains', true),
- array('FÖÖBAR', 'FÖÖ', 'i;unicode-casemap', 'contains', true),
- array('FÖÖBAR', 'föö', 'i;unicode-casemap', 'contains', true),
- array('FOOBAR', 'FOOBAR', 'i;unicode-casemap', 'equals', true),
- array('FOOBAR', 'fooBAR', 'i;unicode-casemap', 'equals', true),
- array('FOOBAR', 'FOO', 'i;unicode-casemap', 'starts-with', true),
- array('FOOBAR', 'foo', 'i;unicode-casemap', 'starts-with', true),
- array('FOOBAR', 'BAR', 'i;unicode-casemap', 'starts-with', false),
- array('FOOBAR', 'bar', 'i;unicode-casemap', 'starts-with', false),
- array('FOOBAR', 'FOO', 'i;unicode-casemap', 'ends-with', false),
- array('FOOBAR', 'foo', 'i;unicode-casemap', 'ends-with', false),
- array('FOOBAR', 'BAR', 'i;unicode-casemap', 'ends-with', true),
- array('FOOBAR', 'bar', 'i;unicode-casemap', 'ends-with', true),
- );
+ return [
+ ['FOOBAR', 'FOO', 'i;octet', 'contains', true],
+ ['FOOBAR', 'foo', 'i;octet', 'contains', false],
+ ['FÖÖBAR', 'FÖÖ', 'i;octet', 'contains', true],
+ ['FÖÖBAR', 'föö', 'i;octet', 'contains', false],
+ ['FOOBAR', 'FOOBAR', 'i;octet', 'equals', true],
+ ['FOOBAR', 'fooBAR', 'i;octet', 'equals', false],
+ ['FOOBAR', 'FOO', 'i;octet', 'starts-with', true],
+ ['FOOBAR', 'foo', 'i;octet', 'starts-with', false],
+ ['FOOBAR', 'BAR', 'i;octet', 'starts-with', false],
+ ['FOOBAR', 'bar', 'i;octet', 'starts-with', false],
+ ['FOOBAR', 'FOO', 'i;octet', 'ends-with', false],
+ ['FOOBAR', 'foo', 'i;octet', 'ends-with', false],
+ ['FOOBAR', 'BAR', 'i;octet', 'ends-with', true],
+ ['FOOBAR', 'bar', 'i;octet', 'ends-with', false],
+
+ ['FOOBAR', 'FOO', 'i;ascii-casemap', 'contains', true],
+ ['FOOBAR', 'foo', 'i;ascii-casemap', 'contains', true],
+ ['FÖÖBAR', 'FÖÖ', 'i;ascii-casemap', 'contains', true],
+ ['FÖÖBAR', 'föö', 'i;ascii-casemap', 'contains', false],
+ ['FOOBAR', 'FOOBAR', 'i;ascii-casemap', 'equals', true],
+ ['FOOBAR', 'fooBAR', 'i;ascii-casemap', 'equals', true],
+ ['FOOBAR', 'FOO', 'i;ascii-casemap', 'starts-with', true],
+ ['FOOBAR', 'foo', 'i;ascii-casemap', 'starts-with', true],
+ ['FOOBAR', 'BAR', 'i;ascii-casemap', 'starts-with', false],
+ ['FOOBAR', 'bar', 'i;ascii-casemap', 'starts-with', false],
+ ['FOOBAR', 'FOO', 'i;ascii-casemap', 'ends-with', false],
+ ['FOOBAR', 'foo', 'i;ascii-casemap', 'ends-with', false],
+ ['FOOBAR', 'BAR', 'i;ascii-casemap', 'ends-with', true],
+ ['FOOBAR', 'bar', 'i;ascii-casemap', 'ends-with', true],
+
+ ['FOOBAR', 'FOO', 'i;unicode-casemap', 'contains', true],
+ ['FOOBAR', 'foo', 'i;unicode-casemap', 'contains', true],
+ ['FÖÖBAR', 'FÖÖ', 'i;unicode-casemap', 'contains', true],
+ ['FÖÖBAR', 'föö', 'i;unicode-casemap', 'contains', true],
+ ['FOOBAR', 'FOOBAR', 'i;unicode-casemap', 'equals', true],
+ ['FOOBAR', 'fooBAR', 'i;unicode-casemap', 'equals', true],
+ ['FOOBAR', 'FOO', 'i;unicode-casemap', 'starts-with', true],
+ ['FOOBAR', 'foo', 'i;unicode-casemap', 'starts-with', true],
+ ['FOOBAR', 'BAR', 'i;unicode-casemap', 'starts-with', false],
+ ['FOOBAR', 'bar', 'i;unicode-casemap', 'starts-with', false],
+ ['FOOBAR', 'FOO', 'i;unicode-casemap', 'ends-with', false],
+ ['FOOBAR', 'foo', 'i;unicode-casemap', 'ends-with', false],
+ ['FOOBAR', 'BAR', 'i;unicode-casemap', 'ends-with', true],
+ ['FOOBAR', 'bar', 'i;unicode-casemap', 'ends-with', true],
+ ];
}
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
- public function testBadCollation() {
+ function testBadCollation() {
- StringUtil::textMatch('foobar','foo','blabla','contains');
+ StringUtil::textMatch('foobar', 'foo', 'blabla', 'contains');
}
@@ -77,13 +77,13 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception\BadRequest
*/
- public function testBadMatchType() {
+ function testBadMatchType() {
- StringUtil::textMatch('foobar','foo','i;octet','booh');
+ StringUtil::textMatch('foobar', 'foo', 'i;octet', 'booh');
}
- public function testEnsureUTF8_ascii() {
+ function testEnsureUTF8_ascii() {
$inputString = "harkema";
$outputString = "harkema";
@@ -95,7 +95,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase {
}
- public function testEnsureUTF8_latin1() {
+ function testEnsureUTF8_latin1() {
$inputString = "m\xfcnster";
$outputString = "münster";
@@ -107,7 +107,7 @@ class StringUtilTest extends \PHPUnit_Framework_TestCase {
}
- public function testEnsureUTF8_utf8() {
+ function testEnsureUTF8_utf8() {
$inputString = "m\xc3\xbcnster";
$outputString = "münster";
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php
index 7122f4a01..6acd6b077 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/TemporaryFileFilterTest.php
@@ -25,7 +25,7 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->assertEquals(201, $this->response->status);
$this->assertEquals('0', $this->response->getHeader('Content-Length'));
- $this->assertEquals('Testing new file',file_get_contents(SABRE_TEMPDIR . '/testput.txt'));
+ $this->assertEquals('Testing new file', file_get_contents(SABRE_TEMPDIR . '/testput.txt'));
}
@@ -39,11 +39,11 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->assertEquals('', $this->response->body);
$this->assertEquals(201, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
- $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'),'._testput.txt should not exist in the regular file structure.');
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'), '._testput.txt should not exist in the regular file structure.');
}
@@ -57,20 +57,20 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->assertEquals('', $this->response->body);
$this->assertEquals(201, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
- $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'),'._testput.txt should not exist in the regular file structure.');
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testput.txt'), '._testput.txt should not exist in the regular file structure.');
$this->server->exec();
$this->assertEquals(412, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
}
@@ -83,9 +83,9 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->assertEquals('', $this->response->body);
$this->assertEquals(201, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
$request = new HTTP\Request('GET', '/._testput.txt');
@@ -93,13 +93,13 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->server->exec();
$this->assertEquals(200, $this->response->status);
- $this->assertEquals(array(
- 'X-Sabre-Temp' => ['true'],
+ $this->assertEquals([
+ 'X-Sabre-Temp' => ['true'],
'Content-Length' => [16],
- 'Content-Type' => ['application/octet-stream'],
- ),$this->response->getHeaders());
+ 'Content-Type' => ['application/octet-stream'],
+ ], $this->response->getHeaders());
- $this->assertEquals('Testing new file',stream_get_contents($this->response->body));
+ $this->assertEquals('Testing new file', stream_get_contents($this->response->body));
}
@@ -125,11 +125,11 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->server->exec();
$this->assertEquals(201, $this->response->status);
- $this->assertEquals('application/xml; charset=utf-8',$this->response->getHeader('Content-Type'));
- $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/',$this->response->getHeader('Lock-Token'))===1,'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
- $this->assertEquals('true',$this->response->getHeader('X-Sabre-Temp'));
+ $this->assertEquals('application/xml; charset=utf-8', $this->response->getHeader('Content-Type'));
+ $this->assertTrue(preg_match('/^<opaquelocktoken:(.*)>$/', $this->response->getHeader('Lock-Token')) === 1, 'We did not get a valid Locktoken back (' . $this->response->getHeader('Lock-Token') . ')');
+ $this->assertEquals('true', $this->response->getHeader('X-Sabre-Temp'));
- $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testlock.txt'),'._testlock.txt should not exist in the regular file structure.');
+ $this->assertFalse(file_exists(SABRE_TEMPDIR . '/._testlock.txt'), '._testlock.txt should not exist in the regular file structure.');
}
@@ -143,20 +143,20 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->assertEquals('', $this->response->body);
$this->assertEquals(201, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
$request = new HTTP\Request('DELETE', '/._testput.txt');
$this->server->httpRequest = $request;
$this->server->exec();
- $this->assertEquals(204, $this->response->status, "Incorrect status code received. Full body:\n". $this->response->body);
- $this->assertEquals(array(
+ $this->assertEquals(204, $this->response->status, "Incorrect status code received. Full body:\n" . $this->response->body);
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
- $this->assertEquals('',$this->response->body);
+ $this->assertEquals('', $this->response->body);
}
@@ -169,30 +169,30 @@ class TemporaryFileFilterTest extends AbstractServer {
$this->assertEquals('', $this->response->body);
$this->assertEquals(201, $this->response->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
$request = new HTTP\Request('PROPFIND', '/._testput.txt');
$this->server->httpRequest = ($request);
$this->server->exec();
- $this->assertEquals(207, $this->response->status,'Incorrect status code returned. Body: ' . $this->response->body);
- $this->assertEquals(array(
+ $this->assertEquals(207, $this->response->status, 'Incorrect status code returned. Body: ' . $this->response->body);
+ $this->assertEquals([
'X-Sabre-Temp' => ['true'],
'Content-Type' => ['application/xml; charset=utf-8'],
- ),$this->response->getHeaders());
+ ], $this->response->getHeaders());
- $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/","xmlns\\1=\"urn:DAV\"",$this->response->body);
+ $body = preg_replace("/xmlns(:[A-Za-z0-9_])?=(\"|\')DAV:(\"|\')/", "xmlns\\1=\"urn:DAV\"", $this->response->body);
$xml = simplexml_load_string($body);
- $xml->registerXPathNamespace('d','urn:DAV');
+ $xml->registerXPathNamespace('d', 'urn:DAV');
list($data) = $xml->xpath('/d:multistatus/d:response/d:href');
- $this->assertEquals('/._testput.txt',(string)$data,'href element should have been /._testput.txt');
+ $this->assertEquals('/._testput.txt', (string)$data, 'href element should have been /._testput.txt');
$data = $xml->xpath('/d:multistatus/d:response/d:propstat/d:prop/d:resourcetype');
- $this->assertEquals(1,count($data));
+ $this->assertEquals(1, count($data));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php
index bb5ea6acc..619ac03fd 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/TestPlugin.php
@@ -2,9 +2,8 @@
namespace Sabre\DAV;
-use
- Sabre\HTTP\RequestInterface,
- Sabre\HTTP\ResponseInterface;
+use Sabre\HTTP\RequestInterface;
+use Sabre\HTTP\ResponseInterface;
class TestPlugin extends ServerPlugin {
@@ -24,7 +23,7 @@ class TestPlugin extends ServerPlugin {
function initialize(Server $server) {
- $server->on('beforeMethod', [$this,'beforeMethod']);
+ $server->on('beforeMethod', [$this, 'beforeMethod']);
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php
index 9516c2390..ad33200c8 100644
--- a/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAV/TreeTest.php
@@ -16,18 +16,18 @@ class TreeTest extends \PHPUnit_Framework_TestCase {
function testCopy() {
$tree = new TreeMock();
- $tree->copy('hi','hi2');
+ $tree->copy('hi', 'hi2');
$this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories);
$this->assertEquals('foobar', $tree->getNodeForPath('hi/file')->get());
- $this->assertEquals(array('test1'=>'value'), $tree->getNodeForPath('hi/file')->getProperties(array()));
+ $this->assertEquals(['test1' => 'value'], $tree->getNodeForPath('hi/file')->getProperties([]));
}
function testMove() {
$tree = new TreeMock();
- $tree->move('hi','hi2');
+ $tree->move('hi', 'hi2');
$this->assertEquals('hi2', $tree->getNodeForPath('hi')->getName());
$this->assertTrue($tree->getNodeForPath('hi')->isRenamed);
@@ -37,7 +37,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase {
function testDeepMove() {
$tree = new TreeMock();
- $tree->move('hi/sub','hi2');
+ $tree->move('hi/sub', 'hi2');
$this->assertArrayHasKey('hi2', $tree->getNodeForPath('')->newDirectories);
$this->assertTrue($tree->getNodeForPath('hi/sub')->isDeleted);
@@ -56,7 +56,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase {
$tree = new TreeMock();
$children = $tree->getChildren('');
- $this->assertEquals(2,count($children));
+ $this->assertEquals(2, count($children));
$this->assertEquals('hi', $children[0]->getName());
}
@@ -85,12 +85,12 @@ class TreeTest extends \PHPUnit_Framework_TestCase {
class TreeMock extends Tree {
- private $nodes = array();
+ private $nodes = [];
function __construct() {
$file = new TreeFileTester('file');
- $file->properties = ['test1'=>'value'];
+ $file->properties = ['test1' => 'value'];
$file->data = 'foobar';
parent::__construct(
@@ -113,8 +113,8 @@ class TreeMock extends Tree {
class TreeDirectoryTester extends SimpleCollection {
- public $newDirectories = array();
- public $newFiles = array();
+ public $newDirectories = [];
+ public $newFiles = [];
public $isDeleted = false;
public $isRenamed = false;
@@ -124,7 +124,7 @@ class TreeDirectoryTester extends SimpleCollection {
}
- function createFile($name,$data = null) {
+ function createFile($name, $data = null) {
$this->newFiles[$name] = $data;
@@ -132,7 +132,7 @@ class TreeDirectoryTester extends SimpleCollection {
function getChild($name) {
- if (isset($this->newDirectories[$name])) return new TreeDirectoryTester($name);
+ if (isset($this->newDirectories[$name])) return new self($name);
if (isset($this->newFiles[$name])) return new TreeFileTester($name, $this->newFiles[$name]);
return parent::getChild($name);
@@ -225,7 +225,7 @@ class TreeMultiGetTester extends TreeDirectoryTester implements IMultiGet {
function getMultipleChildren(array $paths) {
$result = [];
- foreach($paths as $path) {
+ foreach ($paths as $path) {
try {
$child = $this->getChild($path);
$result[] = $child;
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php
index 4ecd42717..7d7a54d06 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/ACLMethodTest.php
@@ -14,6 +14,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
$acl = new Plugin();
$server = new DAV\Server();
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpAcl($server->httpRequest, $server->httpResponse);
@@ -21,15 +22,14 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
}
/**
-
- /**
+ /**
* @expectedException Sabre\DAV\Exception\MethodNotAllowed
*/
function testNotSupportedByNode() {
- $tree = array(
+ $tree = [
new DAV\SimpleCollection('test'),
- );
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
$server->httpRequest = new HTTP\Request();
@@ -37,6 +37,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
<d:acl xmlns:d="DAV:">
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -45,9 +46,9 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
function testSuccessSimple() {
- $tree = array(
- new MockACLNode('test',array()),
- );
+ $tree = [
+ new MockACLNode('test', []),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
$server->httpRequest = new HTTP\Request();
@@ -57,6 +58,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
<d:acl xmlns:d="DAV:">
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$this->assertFalse($acl->httpACL($server->httpRequest, $server->httpResponse));
@@ -68,12 +70,12 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testUnrecognizedPrincipal() {
- $tree = array(
- new MockACLNode('test',array()),
- );
+ $tree = [
+ new MockACLNode('test', []),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -82,6 +84,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -93,15 +96,15 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testUnrecognizedPrincipal2() {
- $tree = array(
- new MockACLNode('test',array()),
- new DAV\SimpleCollection('principals',array(
+ $tree = [
+ new MockACLNode('test', []),
+ new DAV\SimpleCollection('principals', [
new DAV\SimpleCollection('notaprincipal'),
- )),
- );
+ ]),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -110,6 +113,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -121,12 +125,12 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testUnknownPrivilege() {
- $tree = array(
- new MockACLNode('test',array()),
- );
+ $tree = [
+ new MockACLNode('test', []),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -135,6 +139,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -146,20 +151,24 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testAbstractPrivilege() {
- $tree = array(
- new MockACLNode('test',array()),
- );
+ $tree = [
+ new MockACLNode('test', []),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->on('getSupportedPrivilegeSet', function($node, &$supportedPrivilegeSet) {
+ $supportedPrivilegeSet['{DAV:}foo'] = ['abstract' => true];
+ });
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
- <d:grant><d:privilege><d:all /></d:privilege></d:grant>
- <d:principal><d:href>/principals/notfound</d:href></d:principal>
+ <d:grant><d:privilege><d:foo /></d:privilege></d:grant>
+ <d:principal><d:href>/principals/foo/</d:href></d:principal>
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -171,20 +180,20 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testUpdateProtectedPrivilege() {
- $oldACL = array(
- array(
+ $oldACL = [
+ [
'principal' => 'principals/notfound',
'privilege' => '{DAV:}write',
'protected' => true,
- ),
- );
+ ],
+ ];
- $tree = array(
- new MockACLNode('test',$oldACL),
- );
+ $tree = [
+ new MockACLNode('test', $oldACL),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -193,6 +202,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -204,20 +214,20 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testUpdateProtectedPrivilege2() {
- $oldACL = array(
- array(
+ $oldACL = [
+ [
'principal' => 'principals/notfound',
'privilege' => '{DAV:}write',
'protected' => true,
- ),
- );
+ ],
+ ];
- $tree = array(
- new MockACLNode('test',$oldACL),
- );
+ $tree = [
+ new MockACLNode('test', $oldACL),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -226,6 +236,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -237,20 +248,20 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
*/
function testUpdateProtectedPrivilege3() {
- $oldACL = array(
- array(
+ $oldACL = [
+ [
'principal' => 'principals/notfound',
'privilege' => '{DAV:}write',
'protected' => true,
- ),
- );
+ ],
+ ];
- $tree = array(
- new MockACLNode('test',$oldACL),
- );
+ $tree = [
+ new MockACLNode('test', $oldACL),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -259,6 +270,7 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$acl->httpACL($server->httpRequest, $server->httpResponse);
@@ -267,28 +279,28 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
function testSuccessComplex() {
- $oldACL = array(
- array(
+ $oldACL = [
+ [
'principal' => 'principals/foo',
'privilege' => '{DAV:}write',
'protected' => true,
- ),
- array(
+ ],
+ [
'principal' => 'principals/bar',
'privilege' => '{DAV:}read',
- ),
- );
-
- $tree = array(
- $node = new MockACLNode('test',$oldACL),
- new DAV\SimpleCollection('principals', array(
- new MockPrincipal('foo','principals/foo'),
- new MockPrincipal('baz','principals/baz'),
- )),
- );
+ ],
+ ];
+
+ $tree = [
+ $node = new MockACLNode('test', $oldACL),
+ new DAV\SimpleCollection('principals', [
+ new MockPrincipal('foo', 'principals/foo'),
+ new MockPrincipal('baz', 'principals/baz'),
+ ]),
+ ];
$acl = new Plugin();
$server = new DAV\Server($tree);
- $server->httpRequest = new HTTP\Request('ACL','/test');
+ $server->httpRequest = new HTTP\Request('ACL', '/test');
$body = '<?xml version="1.0"?>
<d:acl xmlns:d="DAV:">
<d:ace>
@@ -302,23 +314,24 @@ class ACLMethodTest extends \PHPUnit_Framework_TestCase {
</d:ace>
</d:acl>';
$server->httpRequest->setBody($body);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin($acl);
$this->assertFalse($acl->httpAcl($server->httpRequest, $server->httpResponse));
- $this->assertEquals(array(
- array(
+ $this->assertEquals([
+ [
'principal' => 'principals/foo',
'privilege' => '{DAV:}write',
'protected' => true,
- ),
- array(
+ ],
+ [
'principal' => 'principals/baz',
'privilege' => '{DAV:}write',
'protected' => false,
- ),
- ), $node->getACL());
+ ],
+ ], $node->getACL());
}
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php
index 14a80003a..f16693625 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/AllowAccessTest.php
@@ -3,7 +3,6 @@
namespace Sabre\DAVACL;
use Sabre\DAV;
-use Sabre\HTTP;
class AllowAccessTest extends \PHPUnit_Framework_TestCase {
@@ -14,13 +13,24 @@ class AllowAccessTest extends \PHPUnit_Framework_TestCase {
function setUp() {
- $nodes = array(
- new DAV\SimpleCollection('testdir'),
- );
+ $nodes = [
+ new DAV\Mock\Collection('testdir', [
+ 'file1.txt' => 'contents',
+ ]),
+ ];
$this->server = new DAV\Server($nodes);
+ $this->server->addPlugin(
+ new DAV\Auth\Plugin(
+ new DAV\Auth\Backend\Mock()
+ )
+ );
+ // Login
+ $this->server->getPlugin('auth')->beforeMethod(
+ new \Sabre\HTTP\Request(),
+ new \Sabre\HTTP\Response()
+ );
$aclPlugin = new Plugin();
- $aclPlugin->allowAccessToNodesWithoutACL = true;
$this->server->addPlugin($aclPlugin);
}
@@ -64,16 +74,7 @@ class AllowAccessTest extends \PHPUnit_Framework_TestCase {
function testPUT() {
$this->server->httpRequest->setMethod('PUT');
- $this->server->httpRequest->setUrl('/testdir');
-
- $this->assertTrue($this->server->emit('beforeMethod', [$this->server->httpRequest, $this->server->httpResponse]));
-
- }
-
- function testACL() {
-
- $this->server->httpRequest->setMethod('ACL');
- $this->server->httpRequest->setUrl('/testdir');
+ $this->server->httpRequest->setUrl('/testdir/file1.txt');
$this->assertTrue($this->server->emit('beforeMethod', [$this->server->httpRequest, $this->server->httpResponse]));
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php
index be3e9dae9..ceae9aed0 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/BlockAccessTest.php
@@ -3,7 +3,6 @@
namespace Sabre\DAVACL;
use Sabre\DAV;
-use Sabre\HTTP;
class BlockAccessTest extends \PHPUnit_Framework_TestCase {
@@ -21,7 +20,17 @@ class BlockAccessTest extends \PHPUnit_Framework_TestCase {
$this->server = new DAV\Server($nodes);
$this->plugin = new Plugin();
- $this->plugin->allowAccessToNodesWithoutACL = false;
+ $this->plugin->setDefaultAcl([]);
+ $this->server->addPlugin(
+ new DAV\Auth\Plugin(
+ new DAV\Auth\Backend\Mock()
+ )
+ );
+ // Login
+ $this->server->getPlugin('auth')->beforeMethod(
+ new \Sabre\HTTP\Request(),
+ new \Sabre\HTTP\Response()
+ );
$this->server->addPlugin($this->plugin);
}
@@ -178,10 +187,10 @@ class BlockAccessTest extends \PHPUnit_Framework_TestCase {
200 => [],
404 => [],
403 => [
- '{DAV:}displayname' => null,
+ '{DAV:}displayname' => null,
'{DAV:}getcontentlength' => null,
- '{DAV:}bar' => null,
- '{DAV:}owner' => null,
+ '{DAV:}bar' => null,
+ '{DAV:}owner' => null,
],
];
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php
index fc48af67f..1cdf2949f 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/AceConflictTest.php
@@ -11,24 +11,24 @@ class AceConflictTest extends \PHPUnit_Framework_TestCase {
$ex = new AceConflict('message');
$server = new DAV\Server();
- $dom = new \DOMDocument('1.0','utf-8');
- $root = $dom->createElementNS('DAV:','d:root');
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $root = $dom->createElementNS('DAV:', 'd:root');
$dom->appendChild($root);
$ex->serialize($server, $root);
- $xpaths = array(
- '/d:root' => 1,
+ $xpaths = [
+ '/d:root' => 1,
'/d:root/d:no-ace-conflict' => 1,
- );
+ ];
// Reloading because PHP DOM sucks
$dom2 = new \DOMDocument('1.0', 'utf-8');
$dom2->loadXML($dom->saveXML());
$dxpath = new \DOMXPath($dom2);
- $dxpath->registerNamespace('d','DAV:');
- foreach($xpaths as $xpath=>$count) {
+ $dxpath->registerNamespace('d', 'DAV:');
+ foreach ($xpaths as $xpath => $count) {
$this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php
index 7e66adab6..b13e7722d 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NeedPrivilegesExceptionTest.php
@@ -4,41 +4,41 @@ namespace Sabre\DAVACL\Exception;
use Sabre\DAV;
-class NeedPrivilegesTest extends \PHPUnit_Framework_TestCase {
+class NeedPrivilegesExceptionTest extends \PHPUnit_Framework_TestCase {
function testSerialize() {
$uri = 'foo';
- $privileges = array(
+ $privileges = [
'{DAV:}read',
'{DAV:}write',
- );
+ ];
$ex = new NeedPrivileges($uri, $privileges);
$server = new DAV\Server();
- $dom = new \DOMDocument('1.0','utf-8');
- $root = $dom->createElementNS('DAV:','d:root');
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $root = $dom->createElementNS('DAV:', 'd:root');
$dom->appendChild($root);
$ex->serialize($server, $root);
- $xpaths = array(
- '/d:root' => 1,
- '/d:root/d:need-privileges' => 1,
- '/d:root/d:need-privileges/d:resource' => 2,
- '/d:root/d:need-privileges/d:resource/d:href' => 2,
- '/d:root/d:need-privileges/d:resource/d:privilege' => 2,
- '/d:root/d:need-privileges/d:resource/d:privilege/d:read' => 1,
+ $xpaths = [
+ '/d:root' => 1,
+ '/d:root/d:need-privileges' => 1,
+ '/d:root/d:need-privileges/d:resource' => 2,
+ '/d:root/d:need-privileges/d:resource/d:href' => 2,
+ '/d:root/d:need-privileges/d:resource/d:privilege' => 2,
+ '/d:root/d:need-privileges/d:resource/d:privilege/d:read' => 1,
'/d:root/d:need-privileges/d:resource/d:privilege/d:write' => 1,
- );
+ ];
// Reloading because PHP DOM sucks
$dom2 = new \DOMDocument('1.0', 'utf-8');
$dom2->loadXML($dom->saveXML());
$dxpath = new \DOMXPath($dom2);
- $dxpath->registerNamespace('d','DAV:');
- foreach($xpaths as $xpath=>$count) {
+ $dxpath->registerNamespace('d', 'DAV:');
+ foreach ($xpaths as $xpath => $count) {
$this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php
index 2406c1c38..f52b17371 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NoAbstractTest.php
@@ -11,24 +11,24 @@ class NoAbstractTest extends \PHPUnit_Framework_TestCase {
$ex = new NoAbstract('message');
$server = new DAV\Server();
- $dom = new \DOMDocument('1.0','utf-8');
- $root = $dom->createElementNS('DAV:','d:root');
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $root = $dom->createElementNS('DAV:', 'd:root');
$dom->appendChild($root);
$ex->serialize($server, $root);
- $xpaths = array(
- '/d:root' => 1,
+ $xpaths = [
+ '/d:root' => 1,
'/d:root/d:no-abstract' => 1,
- );
+ ];
// Reloading because PHP DOM sucks
$dom2 = new \DOMDocument('1.0', 'utf-8');
$dom2->loadXML($dom->saveXML());
$dxpath = new \DOMXPath($dom2);
- $dxpath->registerNamespace('d','DAV:');
- foreach($xpaths as $xpath=>$count) {
+ $dxpath->registerNamespace('d', 'DAV:');
+ foreach ($xpaths as $xpath => $count) {
$this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php
index 6077b0ba5..df89aaf84 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotRecognizedPrincipalTest.php
@@ -11,24 +11,24 @@ class NotRecognizedPrincipalTest extends \PHPUnit_Framework_TestCase {
$ex = new NotRecognizedPrincipal('message');
$server = new DAV\Server();
- $dom = new \DOMDocument('1.0','utf-8');
- $root = $dom->createElementNS('DAV:','d:root');
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $root = $dom->createElementNS('DAV:', 'd:root');
$dom->appendChild($root);
$ex->serialize($server, $root);
- $xpaths = array(
- '/d:root' => 1,
+ $xpaths = [
+ '/d:root' => 1,
'/d:root/d:recognized-principal' => 1,
- );
+ ];
// Reloading because PHP DOM sucks
$dom2 = new \DOMDocument('1.0', 'utf-8');
$dom2->loadXML($dom->saveXML());
$dxpath = new \DOMXPath($dom2);
- $dxpath->registerNamespace('d','DAV:');
- foreach($xpaths as $xpath=>$count) {
+ $dxpath->registerNamespace('d', 'DAV:');
+ foreach ($xpaths as $xpath => $count) {
$this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php
index 8e7b3685d..50623952b 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/Exception/NotSupportedPrivilegeTest.php
@@ -11,24 +11,24 @@ class NotSupportedPrivilegeTest extends \PHPUnit_Framework_TestCase {
$ex = new NotSupportedPrivilege('message');
$server = new DAV\Server();
- $dom = new \DOMDocument('1.0','utf-8');
- $root = $dom->createElementNS('DAV:','d:root');
+ $dom = new \DOMDocument('1.0', 'utf-8');
+ $root = $dom->createElementNS('DAV:', 'd:root');
$dom->appendChild($root);
$ex->serialize($server, $root);
- $xpaths = array(
- '/d:root' => 1,
+ $xpaths = [
+ '/d:root' => 1,
'/d:root/d:not-supported-privilege' => 1,
- );
+ ];
// Reloading because PHP DOM sucks
$dom2 = new \DOMDocument('1.0', 'utf-8');
$dom2->loadXML($dom->saveXML());
$dxpath = new \DOMXPath($dom2);
- $dxpath->registerNamespace('d','DAV:');
- foreach($xpaths as $xpath=>$count) {
+ $dxpath->registerNamespace('d', 'DAV:');
+ foreach ($xpaths as $xpath => $count) {
$this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count);
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php
index 5e99f2e73..91de64372 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/ExpandPropertiesTest.php
@@ -11,31 +11,38 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
function getServer() {
- $tree = array(
- new DAV\Mock\PropertiesCollection('node1', [], array(
+ $tree = [
+ new DAV\Mock\PropertiesCollection('node1', [], [
'{http://sabredav.org/ns}simple' => 'foo',
'{http://sabredav.org/ns}href' => new DAV\Xml\Property\Href('node2'),
- '{DAV:}displayname' => 'Node 1',
- )),
- new DAV\Mock\PropertiesCollection('node2', [], array(
+ '{DAV:}displayname' => 'Node 1',
+ ]),
+ new DAV\Mock\PropertiesCollection('node2', [], [
+ '{http://sabredav.org/ns}simple' => 'simple',
+ '{http://sabredav.org/ns}hreflist' => new DAV\Xml\Property\Href(['node1', 'node3']),
+ '{DAV:}displayname' => 'Node 2',
+ ]),
+ new DAV\Mock\PropertiesCollection('node3', [], [
'{http://sabredav.org/ns}simple' => 'simple',
- '{http://sabredav.org/ns}hreflist' => new DAV\Xml\Property\Href(['node1','node3']),
- '{DAV:}displayname' => 'Node 2',
- )),
- new DAV\Mock\PropertiesCollection('node3', [], array(
- '{http://sabredav.org/ns}simple' => 'simple',
- '{DAV:}displayname' => 'Node 3',
- )),
- );
+ '{DAV:}displayname' => 'Node 3',
+ ]),
+ ];
$fakeServer = new DAV\Server($tree);
$fakeServer->sapi = new HTTP\SapiMock();
$fakeServer->debugExceptions = true;
$fakeServer->httpResponse = new HTTP\ResponseMock();
$plugin = new Plugin();
- $plugin->allowAccessToNodesWithoutACL = true;
-
+ $plugin->allowUnauthenticatedAccess = false;
+ // Anyone can do anything
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ]
+ ]);
$this->assertTrue($plugin instanceof Plugin);
+
$fakeServer->addPlugin($plugin);
$this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
@@ -53,11 +60,11 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
<d:property name="href" namespace="http://sabredav.org/ns" />
</d:expand-property>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/node1',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -67,38 +74,38 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
$server->exec();
- $this->assertEquals(207, $server->httpResponse->status,'Incorrect status code received. Full body: ' . $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals(207, $server->httpResponse->status, 'Incorrect status code received. Full body: ' . $server->httpResponse->body);
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 1,
- '/d:multistatus/d:response/d:href' => 1,
- '/d:multistatus/d:response/d:propstat' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop' => 2,
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 2,
'/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:simple' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:simple' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1,
'/d:multistatus/d:response/d:propstat/d:prop/s:href/d:href' => 1,
- );
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- $xml->registerXPathNamespace('s','http://sabredav.org/ns');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ $xml->registerXPathNamespace('s', 'http://sabredav.org/ns');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response: ' . $server->httpResponse->body);
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response: ' . $server->httpResponse->body);
}
@@ -116,11 +123,11 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
</d:property>
</d:expand-property>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/node1',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -131,39 +138,39 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status, 'Incorrect response status received. Full response body: ' . $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 1,
- '/d:multistatus/d:response/d:href' => 1,
- '/d:multistatus/d:response/d:propstat' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1,
'/d:multistatus/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1,
- );
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- $xml->registerXPathNamespace('s','http://sabredav.org/ns');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ $xml->registerXPathNamespace('s', 'http://sabredav.org/ns');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . ' Full response body: ' . $server->httpResponse->getBodyAsString());
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . ' Full response body: ' . $server->httpResponse->getBodyAsString());
}
@@ -181,11 +188,11 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
</d:property>
</d:expand-property>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/node2',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -196,39 +203,39 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 1,
- '/d:multistatus/d:response/d:href' => 1,
- '/d:multistatus/d:response/d:propstat' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 2,
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 2,
'/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2,
- );
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- $xml->registerXPathNamespace('s','http://sabredav.org/ns');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ $xml->registerXPathNamespace('s', 'http://sabredav.org/ns');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
}
@@ -249,11 +256,11 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
</d:property>
</d:expand-property>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/node2',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -264,45 +271,45 @@ class ExpandPropertiesTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 1,
- '/d:multistatus/d:response/d:href' => 1,
- '/d:multistatus/d:response/d:propstat' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 3,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 3,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href' => 2,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1,
- '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response' => 1,
+ '/d:multistatus/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat' => 3,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop' => 3,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/d:displayname' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href' => 2,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:href' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat' => 1,
+ '/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop' => 1,
'/d:multistatus/d:response/d:propstat/d:prop/s:hreflist/d:response/d:propstat/d:prop/s:href/d:response/d:propstat/d:prop/d:displayname' => 1,
- );
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- $xml->registerXPathNamespace('s','http://sabredav.org/ns');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ $xml->registerXPathNamespace('s', 'http://sabredav.org/ns');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php
index 7b3e8fc12..2d9744e29 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/MockACLNode.php
@@ -3,14 +3,13 @@
namespace Sabre\DAVACL;
use Sabre\DAV;
-use Sabre\HTTP;
class MockACLNode extends DAV\Node implements IACL {
public $name;
public $acl;
- function __construct($name, array $acl = array()) {
+ function __construct($name, array $acl = []) {
$this->name = $name;
$this->acl = $acl;
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php
index dd8542b8d..934906802 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/MockPrincipal.php
@@ -3,16 +3,15 @@
namespace Sabre\DAVACL;
use Sabre\DAV;
-use Sabre\HTTP;
class MockPrincipal extends DAV\Node implements IPrincipal {
public $name;
public $principalUrl;
- public $groupMembership = array();
- public $groupMemberSet = array();
+ public $groupMembership = [];
+ public $groupMemberSet = [];
- function __construct($name,$principalUrl,array $groupMembership = array(), array $groupMemberSet = array()) {
+ function __construct($name, $principalUrl, array $groupMembership = [], array $groupMemberSet = []) {
$this->name = $name;
$this->principalUrl = $principalUrl;
@@ -35,7 +34,7 @@ class MockPrincipal extends DAV\Node implements IPrincipal {
function getAlternateUriSet() {
- return array();
+ return [];
}
@@ -63,4 +62,3 @@ class MockPrincipal extends DAV\Node implements IPrincipal {
}
}
-
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php
index fb7516a78..8552448f5 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginAdminTest.php
@@ -5,7 +5,6 @@ namespace Sabre\DAVACL;
use Sabre\DAV;
use Sabre\HTTP;
-
require_once 'Sabre/DAVACL/MockACLNode.php';
require_once 'Sabre/HTTP/ResponseMock.php';
@@ -17,10 +16,10 @@ class PluginAdminTest extends \PHPUnit_Framework_TestCase {
$principalBackend = new PrincipalBackend\Mock();
- $tree = array(
- new MockACLNode('adminonly', array()),
+ $tree = [
+ new MockACLNode('adminonly', []),
new PrincipalCollection($principalBackend),
- );
+ ];
$this->server = new DAV\Server($tree);
$this->server->sapi = new HTTP\SapiMock();
@@ -33,11 +32,11 @@ class PluginAdminTest extends \PHPUnit_Framework_TestCase {
$plugin = new Plugin();
$this->server->addPlugin($plugin);
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'OPTIONS',
- 'HTTP_DEPTH' => 1,
- 'REQUEST_URI' => '/adminonly',
- ));
+ 'HTTP_DEPTH' => 1,
+ 'REQUEST_URI' => '/adminonly',
+ ]);
$response = new HTTP\ResponseMock();
@@ -56,16 +55,16 @@ class PluginAdminTest extends \PHPUnit_Framework_TestCase {
function testAdminAccess() {
$plugin = new Plugin();
- $plugin->adminPrincipals = array(
+ $plugin->adminPrincipals = [
'principals/admin',
- );
+ ];
$this->server->addPlugin($plugin);
- $request = HTTP\Sapi::createFromServerArray(array(
+ $request = HTTP\Sapi::createFromServerArray([
'REQUEST_METHOD' => 'OPTIONS',
- 'HTTP_DEPTH' => 1,
- 'REQUEST_URI' => '/adminonly',
- ));
+ 'HTTP_DEPTH' => 1,
+ 'REQUEST_URI' => '/adminonly',
+ ]);
$response = new HTTP\ResponseMock();
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php
index e5b7e1a3f..fb42efba7 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginPropertiesTest.php
@@ -10,6 +10,14 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
function testPrincipalCollectionSet() {
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
+ //Anyone can do anything
$plugin->principalCollectionSet = [
'principals1',
'principals2',
@@ -25,8 +33,8 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $server->getPropertiesForPath('', $requestedProperties);
$result = $result[0];
- $this->assertEquals(1,count($result[200]));
- $this->assertArrayHasKey('{DAV:}principal-collection-set',$result[200]);
+ $this->assertEquals(1, count($result[200]));
+ $this->assertArrayHasKey('{DAV:}principal-collection-set', $result[200]);
$this->assertInstanceOf('Sabre\\DAV\\Xml\\Property\\Href', $result[200]['{DAV:}principal-collection-set']);
$expected = [
@@ -46,6 +54,12 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$plugin = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock());
$fakeServer->addPlugin($plugin);
$plugin = new Plugin();
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$fakeServer->addPlugin($plugin);
@@ -56,8 +70,8 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $fakeServer->getPropertiesForPath('', $requestedProperties);
$result = $result[0];
- $this->assertEquals(1,count($result[200]));
- $this->assertArrayHasKey('{DAV:}current-user-principal',$result[200]);
+ $this->assertEquals(1, count($result[200]));
+ $this->assertArrayHasKey('{DAV:}current-user-principal', $result[200]);
$this->assertInstanceOf('Sabre\DAVACL\Xml\Property\Principal', $result[200]['{DAV:}current-user-principal']);
$this->assertEquals(Xml\Property\Principal::UNAUTHENTICATED, $result[200]['{DAV:}current-user-principal']->getType());
@@ -67,8 +81,8 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $fakeServer->getPropertiesForPath('', $requestedProperties);
$result = $result[0];
- $this->assertEquals(1,count($result[200]));
- $this->assertArrayHasKey('{DAV:}current-user-principal',$result[200]);
+ $this->assertEquals(1, count($result[200]));
+ $this->assertArrayHasKey('{DAV:}current-user-principal', $result[200]);
$this->assertInstanceOf('Sabre\DAVACL\Xml\Property\Principal', $result[200]['{DAV:}current-user-principal']);
$this->assertEquals(Xml\Property\Principal::HREF, $result[200]['{DAV:}current-user-principal']->getType());
$this->assertEquals('principals/admin/', $result[200]['{DAV:}current-user-principal']->getHref());
@@ -78,6 +92,13 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
function testSupportedPrivilegeSet() {
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$server = new DAV\Server();
$server->addPlugin($plugin);
@@ -88,8 +109,8 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $server->getPropertiesForPath('', $requestedProperties);
$result = $result[0];
- $this->assertEquals(1,count($result[200]));
- $this->assertArrayHasKey('{DAV:}supported-privilege-set',$result[200]);
+ $this->assertEquals(1, count($result[200]));
+ $this->assertArrayHasKey('{DAV:}supported-privilege-set', $result[200]);
$this->assertInstanceOf('Sabre\\DAVACL\\Xml\\Property\\SupportedPrivilegeSet', $result[200]['{DAV:}supported-privilege-set']);
$server = new DAV\Server();
@@ -98,26 +119,25 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $server->xml->write('{DAV:}root', $prop);
$xpaths = [
- '/d:root' => 1,
- '/d:root/d:supported-privilege' => 1,
- '/d:root/d:supported-privilege/d:privilege' => 1,
- '/d:root/d:supported-privilege/d:privilege/d:all' => 1,
- '/d:root/d:supported-privilege/d:abstract' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege' => 2,
- '/d:root/d:supported-privilege/d:supported-privilege/d:privilege' => 2,
- '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:read' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:write' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege' => 8,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege' => 8,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-acl' => 1,
+ '/d:root' => 1,
+ '/d:root/d:supported-privilege' => 1,
+ '/d:root/d:supported-privilege/d:privilege' => 1,
+ '/d:root/d:supported-privilege/d:privilege/d:all' => 1,
+ '/d:root/d:supported-privilege/d:abstract' => 0,
+ '/d:root/d:supported-privilege/d:supported-privilege' => 2,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:privilege' => 2,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:read' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:privilege/d:write' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege' => 7,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege' => 7,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-acl' => 1,
'/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:read-current-user-privilege-set' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-content' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-properties' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-acl' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:bind' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unbind' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unlock' => 1,
- '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:abstract' => 0,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-content' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:write-properties' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:bind' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unbind' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:privilege/d:unlock' => 1,
+ '/d:root/d:supported-privilege/d:supported-privilege/d:supported-privilege/d:abstract' => 0,
];
@@ -126,10 +146,10 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$dom2->loadXML($result);
$dxpath = new \DOMXPath($dom2);
- $dxpath->registerNamespace('d','DAV:');
- foreach($xpaths as $xpath=>$count) {
+ $dxpath->registerNamespace('d', 'DAV:');
+ foreach ($xpaths as $xpath => $count) {
- $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count. ' Full XML: ' . $result);
+ $this->assertEquals($count, $dxpath->query($xpath)->length, 'Looking for : ' . $xpath . ', we could only find ' . $dxpath->query($xpath)->length . ' elements, while we expected ' . $count . ' Full XML: ' . $result);
}
@@ -138,6 +158,13 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
function testACL() {
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$nodes = [
new MockACLNode('foo', [
@@ -147,7 +174,7 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
]
]),
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('admin','principals/admin'),
+ $principal = new MockPrincipal('admin', 'principals/admin'),
]),
];
@@ -167,8 +194,8 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $server->getPropertiesForPath('foo', $requestedProperties);
$result = $result[0];
- $this->assertEquals(1,count($result[200]),'The {DAV:}acl property did not return from the list. Full list: ' . print_r($result, true));
- $this->assertArrayHasKey('{DAV:}acl',$result[200]);
+ $this->assertEquals(1, count($result[200]), 'The {DAV:}acl property did not return from the list. Full list: ' . print_r($result, true));
+ $this->assertArrayHasKey('{DAV:}acl', $result[200]);
$this->assertInstanceOf('Sabre\\DAVACL\\Xml\Property\\Acl', $result[200]['{DAV:}acl']);
}
@@ -176,6 +203,7 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
function testACLRestrictions() {
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
$nodes = [
new MockACLNode('foo', [
@@ -185,7 +213,7 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
]
]),
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('admin','principals/admin'),
+ $principal = new MockPrincipal('admin', 'principals/admin'),
]),
];
@@ -205,8 +233,8 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$result = $server->getPropertiesForPath('foo', $requestedProperties);
$result = $result[0];
- $this->assertEquals(1,count($result[200]),'The {DAV:}acl-restrictions property did not return from the list. Full list: ' . print_r($result, true));
- $this->assertArrayHasKey('{DAV:}acl-restrictions',$result[200]);
+ $this->assertEquals(1, count($result[200]), 'The {DAV:}acl-restrictions property did not return from the list. Full list: ' . print_r($result, true));
+ $this->assertArrayHasKey('{DAV:}acl-restrictions', $result[200]);
$this->assertInstanceOf('Sabre\\DAVACL\\Xml\\Property\\AclRestrictions', $result[200]['{DAV:}acl-restrictions']);
}
@@ -215,7 +243,7 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$tree = [
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('user','principals/user'),
+ $principal = new MockPrincipal('user', 'principals/user'),
])
];
@@ -223,6 +251,13 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
//$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend())
//$fakeServer->addPlugin($plugin);
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$fakeServer->addPlugin($plugin);
$requestedProperties = [
@@ -243,7 +278,7 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$tree = [
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('user','principals/user'),
+ $principal = new MockPrincipal('user', 'principals/user'),
]),
];
@@ -251,6 +286,13 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
//$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend());
//$fakeServer->addPlugin($plugin);
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$fakeServer->addPlugin($plugin);
$requestedProperties = [
@@ -272,7 +314,7 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$tree = [
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('user','principals/user'),
+ $principal = new MockPrincipal('user', 'principals/user'),
]),
];
@@ -280,6 +322,13 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
//$plugin = new DAV\Auth\Plugin(new DAV\Auth\MockBackend());
//$fakeServer->addPlugin($plugin);
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$fakeServer->addPlugin($plugin);
$requestedProperties = [
@@ -301,13 +350,20 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$tree = [
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('user','principals/user'),
+ $principal = new MockPrincipal('user', 'principals/user'),
]),
];
$fakeServer = new DAV\Server($tree);
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
$fakeServer->addPlugin($plugin);
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$requestedProperties = [
'{DAV:}group-membership',
@@ -328,13 +384,20 @@ class PluginPropertiesTest extends \PHPUnit_Framework_TestCase {
$tree = [
new DAV\SimpleCollection('principals', [
- $principal = new MockPrincipal('user','principals/user'),
+ $principal = new MockPrincipal('user', 'principals/user'),
]),
];
$fakeServer = new DAV\Server($tree);
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
$fakeServer->addPlugin($plugin);
+ $plugin->setDefaultACL([
+ [
+ 'principal' => '{DAV:}all',
+ 'privilege' => '{DAV:}all',
+ ],
+ ]);
$requestedProperties = [
'{DAV:}displayname',
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php
index 64cedd142..0147e6a61 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PluginUpdatePropertiesTest.php
@@ -3,28 +3,25 @@
namespace Sabre\DAVACL;
use Sabre\DAV;
-use Sabre\HTTP;
-
-
-require_once 'Sabre/DAVACL/MockPrincipal.php';
class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
function testUpdatePropertiesPassthrough() {
- $tree = array(
+ $tree = [
new DAV\SimpleCollection('foo'),
- );
+ ];
$server = new DAV\Server($tree);
+ $server->addPlugin(new DAV\Auth\Plugin());
$server->addPlugin(new Plugin());
- $result = $server->updateProperties('foo', array(
+ $result = $server->updateProperties('foo', [
'{DAV:}foo' => 'bar',
- ));
+ ]);
- $expected = array(
+ $expected = [
'{DAV:}foo' => 403,
- );
+ ];
$this->assertEquals($expected, $result);
@@ -32,35 +29,39 @@ class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
function testRemoveGroupMembers() {
- $tree = array(
- new MockPrincipal('foo','foo'),
- );
+ $tree = [
+ new MockPrincipal('foo', 'foo'),
+ ];
$server = new DAV\Server($tree);
- $server->addPlugin(new Plugin());
+ $plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $server->addPlugin($plugin);
- $result = $server->updateProperties('foo', array(
+ $result = $server->updateProperties('foo', [
'{DAV:}group-member-set' => null,
- ));
+ ]);
- $expected = array(
+ $expected = [
'{DAV:}group-member-set' => 204
- );
+ ];
$this->assertEquals($expected, $result);
- $this->assertEquals(array(),$tree[0]->getGroupMemberSet());
+ $this->assertEquals([], $tree[0]->getGroupMemberSet());
}
function testSetGroupMembers() {
$tree = [
- new MockPrincipal('foo','foo'),
+ new MockPrincipal('foo', 'foo'),
];
$server = new DAV\Server($tree);
- $server->addPlugin(new Plugin());
+ $plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $server->addPlugin($plugin);
$result = $server->updateProperties('foo', [
- '{DAV:}group-member-set' => new DAV\Xml\Property\Href(['/bar','/baz'], true),
+ '{DAV:}group-member-set' => new DAV\Xml\Property\Href(['/bar', '/baz'], true),
]);
$expected = [
@@ -68,7 +69,7 @@ class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
];
$this->assertEquals($expected, $result);
- $this->assertEquals(['bar', 'baz'],$tree[0]->getGroupMemberSet());
+ $this->assertEquals(['bar', 'baz'], $tree[0]->getGroupMemberSet());
}
@@ -77,15 +78,17 @@ class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
*/
function testSetBadValue() {
- $tree = array(
- new MockPrincipal('foo','foo'),
- );
+ $tree = [
+ new MockPrincipal('foo', 'foo'),
+ ];
$server = new DAV\Server($tree);
- $server->addPlugin(new Plugin());
+ $plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $server->addPlugin($plugin);
- $result = $server->updateProperties('foo', array(
+ $result = $server->updateProperties('foo', [
'{DAV:}group-member-set' => new \StdClass(),
- ));
+ ]);
}
@@ -95,10 +98,12 @@ class PluginUpdatePropertiesTest extends \PHPUnit_Framework_TestCase {
new DAV\SimpleCollection('foo'),
];
$server = new DAV\Server($tree);
- $server->addPlugin(new Plugin());
+ $plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
+ $server->addPlugin($plugin);
$result = $server->updateProperties('foo', [
- '{DAV:}group-member-set' => new DAV\Xml\Property\Href(['/bar','/baz'],false),
+ '{DAV:}group-member-set' => new DAV\Xml\Property\Href(['/bar', '/baz'], false),
]);
$expected = [
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php
index 3814ebc0d..9fef3018d 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/AbstractPDOTest.php
@@ -5,10 +5,24 @@ namespace Sabre\DAVACL\PrincipalBackend;
use Sabre\DAV;
use Sabre\HTTP;
-
abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
- abstract function getPDO();
+ use DAV\DbTestHelperTrait;
+
+ function setUp() {
+
+ $this->dropTables(['principals', 'groupmembers']);
+ $this->createSchema('principals');
+
+ $pdo = $this->getPDO();
+
+ $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/user','user@example.org','User')");
+ $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/group','group@example.org','Group')");
+
+ $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (5,4)");
+
+ }
+
function testConstruct() {
@@ -26,21 +40,26 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$pdo = $this->getPDO();
$backend = new PDO($pdo);
- $expected = array(
- array(
- 'uri' => 'principals/user',
+ $expected = [
+ [
+ 'uri' => 'principals/admin',
+ '{http://sabredav.org/ns}email-address' => 'admin@example.org',
+ '{DAV:}displayname' => 'Administrator',
+ ],
+ [
+ 'uri' => 'principals/user',
'{http://sabredav.org/ns}email-address' => 'user@example.org',
- '{DAV:}displayname' => 'User',
- ),
- array(
- 'uri' => 'principals/group',
+ '{DAV:}displayname' => 'User',
+ ],
+ [
+ 'uri' => 'principals/group',
'{http://sabredav.org/ns}email-address' => 'group@example.org',
- '{DAV:}displayname' => 'Group',
- ),
- );
+ '{DAV:}displayname' => 'Group',
+ ],
+ ];
$this->assertEquals($expected, $backend->getPrincipalsByPrefix('principals'));
- $this->assertEquals(array(), $backend->getPrincipalsByPrefix('foo'));
+ $this->assertEquals([], $backend->getPrincipalsByPrefix('foo'));
}
@@ -52,12 +71,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$pdo = $this->getPDO();
$backend = new PDO($pdo);
- $expected = array(
- 'id' => 1,
- 'uri' => 'principals/user',
+ $expected = [
+ 'id' => 4,
+ 'uri' => 'principals/user',
'{http://sabredav.org/ns}email-address' => 'user@example.org',
- '{DAV:}displayname' => 'User',
- );
+ '{DAV:}displayname' => 'User',
+ ];
$this->assertEquals($expected, $backend->getPrincipalByPath('principals/user'));
$this->assertEquals(null, $backend->getPrincipalByPath('foo'));
@@ -68,9 +87,9 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$pdo = $this->getPDO();
$backend = new PDO($pdo);
- $expected = array('principals/user');
+ $expected = ['principals/user'];
- $this->assertEquals($expected,$backend->getGroupMemberSet('principals/group'));
+ $this->assertEquals($expected, $backend->getGroupMemberSet('principals/group'));
}
@@ -78,9 +97,9 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$pdo = $this->getPDO();
$backend = new PDO($pdo);
- $expected = array('principals/group');
+ $expected = ['principals/group'];
- $this->assertEquals($expected,$backend->getGroupMembership('principals/user'));
+ $this->assertEquals($expected, $backend->getGroupMembership('principals/user'));
}
@@ -90,15 +109,15 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
// Start situation
$backend = new PDO($pdo);
- $this->assertEquals(array('principals/user'), $backend->getGroupMemberSet('principals/group'));
+ $this->assertEquals(['principals/user'], $backend->getGroupMemberSet('principals/group'));
// Removing all principals
- $backend->setGroupMemberSet('principals/group', array());
- $this->assertEquals(array(), $backend->getGroupMemberSet('principals/group'));
+ $backend->setGroupMemberSet('principals/group', []);
+ $this->assertEquals([], $backend->getGroupMemberSet('principals/group'));
// Adding principals again
- $backend->setGroupMemberSet('principals/group', array('principals/user'));
- $this->assertEquals(array('principals/user'), $backend->getGroupMemberSet('principals/group'));
+ $backend->setGroupMemberSet('principals/group', ['principals/user']);
+ $this->assertEquals(['principals/user'], $backend->getGroupMemberSet('principals/group'));
}
@@ -109,17 +128,17 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$backend = new PDO($pdo);
- $result = $backend->searchPrincipals('principals', array('{DAV:}blabla' => 'foo'));
- $this->assertEquals(array(), $result);
+ $result = $backend->searchPrincipals('principals', ['{DAV:}blabla' => 'foo']);
+ $this->assertEquals([], $result);
- $result = $backend->searchPrincipals('principals', array('{DAV:}displayname' => 'ou'));
- $this->assertEquals(array('principals/group'), $result);
+ $result = $backend->searchPrincipals('principals', ['{DAV:}displayname' => 'ou']);
+ $this->assertEquals(['principals/group'], $result);
- $result = $backend->searchPrincipals('principals', array('{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE'));
- $this->assertEquals(array('principals/user'), $result);
+ $result = $backend->searchPrincipals('principals', ['{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE']);
+ $this->assertEquals(['principals/user'], $result);
- $result = $backend->searchPrincipals('mom', array('{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE'));
- $this->assertEquals(array(), $result);
+ $result = $backend->searchPrincipals('mom', ['{DAV:}displayname' => 'UsEr', '{http://sabredav.org/ns}email-address' => 'USER@EXAMPLE']);
+ $this->assertEquals([], $result);
}
@@ -137,12 +156,12 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$this->assertTrue($result);
- $this->assertEquals(array(
- 'id' => 1,
- 'uri' => 'principals/user',
- '{DAV:}displayname' => 'pietje',
+ $this->assertEquals([
+ 'id' => 4,
+ 'uri' => 'principals/user',
+ '{DAV:}displayname' => 'pietje',
'{http://sabredav.org/ns}email-address' => 'user@example.org',
- ), $backend->getPrincipalByPath('principals/user'));
+ ], $backend->getPrincipalByPath('principals/user'));
}
@@ -153,7 +172,7 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$propPatch = new DAV\PropPatch([
'{DAV:}displayname' => 'pietje',
- '{DAV:}unknown' => 'foo',
+ '{DAV:}unknown' => 'foo',
]);
$backend->updatePrincipal('principals/user', $propPatch);
@@ -161,17 +180,17 @@ abstract class AbstractPDOTest extends \PHPUnit_Framework_TestCase {
$this->assertFalse($result);
- $this->assertEquals(array(
+ $this->assertEquals([
'{DAV:}displayname' => 424,
- '{DAV:}unknown' => 403
- ), $propPatch->getResult());
+ '{DAV:}unknown' => 403
+ ], $propPatch->getResult());
- $this->assertEquals(array(
- 'id' => '1',
- 'uri' => 'principals/user',
- '{DAV:}displayname' => 'User',
+ $this->assertEquals([
+ 'id' => '4',
+ 'uri' => 'principals/user',
+ '{DAV:}displayname' => 'User',
'{http://sabredav.org/ns}email-address' => 'user@example.org',
- ), $backend->getPrincipalByPath('principals/user'));
+ ], $backend->getPrincipalByPath('principals/user'));
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php
index 83353c86c..8779eb69f 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOMySQLTest.php
@@ -2,49 +2,8 @@
namespace Sabre\DAVACL\PrincipalBackend;
-use Sabre\DAV;
-use Sabre\HTTP;
-
-
-require_once 'Sabre/TestUtil.php';
-
class PDOMySQLTest extends AbstractPDOTest {
- function getPDO() {
-
- if (!SABRE_HASMYSQL) $this->markTestSkipped('MySQL driver is not available, or not properly configured');
- $pdo = \Sabre\TestUtil::getMySQLDB();
- if (!$pdo) $this->markTestSkipped('Could not connect to MySQL database');
- $pdo->query("DROP TABLE IF EXISTS principals");
- $pdo->query(<<<SQL
-create table principals (
- id integer unsigned not null primary key auto_increment,
- uri varchar(50),
- email varchar(80),
- displayname VARCHAR(80),
- vcardurl VARCHAR(80),
- unique(uri)
-)
-SQL
- );
-
- $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/user','user@example.org','User')");
- $pdo->query("INSERT INTO principals (uri,email,displayname) VALUES ('principals/group','group@example.org','Group')");
- $pdo->query("DROP TABLE IF EXISTS groupmembers");
- $pdo->query(<<<SQL
-CREATE TABLE groupmembers (
- id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
- principal_id INTEGER UNSIGNED NOT NULL,
- member_id INTEGER UNSIGNED NOT NULL,
- UNIQUE(principal_id, member_id)
-)
-SQL
- );
-
- $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (2,1)");
-
- return $pdo;
-
- }
+ public $driver = 'mysql';
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php
index f335ed51f..48454981d 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalBackend/PDOSqliteTest.php
@@ -2,44 +2,8 @@
namespace Sabre\DAVACL\PrincipalBackend;
-use Sabre\DAV;
-use Sabre\HTTP;
+class PDOSqliteTest extends AbstractPDOTest {
-
-require_once 'Sabre/DAV/Auth/Backend/AbstractPDOTest.php';
-
-class PDOSQLiteTest extends AbstractPDOTest {
-
- function tearDown() {
-
- if (file_exists(SABRE_TEMPDIR . '/pdobackend')) unlink(SABRE_TEMPDIR . '/pdobackend');
- if (file_exists(SABRE_TEMPDIR . '/pdobackend2')) unlink(SABRE_TEMPDIR . '/pdobackend2');
-
- }
-
- function getPDO() {
-
- if (!SABRE_HASSQLITE) $this->markTestSkipped('SQLite driver is not available');
- $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
- $pdo->query('CREATE TABLE principals (id INTEGER PRIMARY KEY ASC, uri TEXT, email VARCHAR(80), displayname VARCHAR(80))');
- $pdo->query('INSERT INTO principals VALUES (1, "principals/user","user@example.org","User")');
- $pdo->query('INSERT INTO principals VALUES (2, "principals/group","group@example.org","Group")');
-
- $pdo->query(<<<SQL
-CREATE TABLE groupmembers (
- id INTEGER PRIMARY KEY ASC,
- principal_id INT,
- member_id INT,
- UNIQUE(principal_id, member_id)
-)
-SQL
- );
-
- $pdo->query("INSERT INTO groupmembers (principal_id,member_id) VALUES (2,1)");
-
- return $pdo;
-
- }
+ public $driver = 'sqlite';
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php
index f51d2dcce..bcf78821b 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalCollectionTest.php
@@ -2,26 +2,22 @@
namespace Sabre\DAVACL;
-use Sabre\DAV;
-use Sabre\HTTP;
-
-
class PrincipalCollectionTest extends \PHPUnit_Framework_TestCase {
- public function testBasic() {
+ function testBasic() {
$backend = new PrincipalBackend\Mock();
$pc = new PrincipalCollection($backend);
$this->assertTrue($pc instanceof PrincipalCollection);
- $this->assertEquals('principals',$pc->getName());
+ $this->assertEquals('principals', $pc->getName());
}
/**
* @depends testBasic
*/
- public function testGetChildren() {
+ function testGetChildren() {
$backend = new PrincipalBackend\Mock();
$pc = new PrincipalCollection($backend);
@@ -29,7 +25,7 @@ class PrincipalCollectionTest extends \PHPUnit_Framework_TestCase {
$children = $pc->getChildren();
$this->assertTrue(is_array($children));
- foreach($children as $child) {
+ foreach ($children as $child) {
$this->assertTrue($child instanceof IPrincipal);
}
@@ -39,7 +35,7 @@ class PrincipalCollectionTest extends \PHPUnit_Framework_TestCase {
* @depends testBasic
* @expectedException Sabre\DAV\Exception\MethodNotAllowed
*/
- public function testGetChildrenDisable() {
+ function testGetChildrenDisable() {
$backend = new PrincipalBackend\Mock();
$pc = new PrincipalCollection($backend);
@@ -49,7 +45,7 @@ class PrincipalCollectionTest extends \PHPUnit_Framework_TestCase {
}
- public function testFindByUri() {
+ function testFindByUri() {
$backend = new PrincipalBackend\Mock();
$pc = new PrincipalCollection($backend);
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
index 8e4c86782..60e156d9a 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalPropertySearchTest.php
@@ -23,6 +23,7 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$fakeServer->debugExceptions = true;
$plugin = new MockPlugin();
$plugin->allowAccessToNodesWithoutACL = true;
+ $plugin->allowUnauthenticatedAccess = false;
$this->assertTrue($plugin instanceof Plugin);
$fakeServer->addPlugin($plugin);
@@ -48,11 +49,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
</d:prop>
</d:principal-property-search>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '1',
'REQUEST_URI' => '/principals',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -63,10 +64,10 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(400, $server->httpResponse->getStatus(), $server->httpResponse->getBodyAsString());
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
}
@@ -87,11 +88,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
</d:prop>
</d:principal-property-search>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/principals',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -102,11 +103,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->getStatus(), "Full body: " . $server->httpResponse->getBodyAsString());
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'Vary' => ['Brief,Prefer'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Vary' => ['Brief,Prefer'],
+ ], $server->httpResponse->getHeaders());
}
@@ -127,11 +128,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
</d:prop>
</d:principal-property-search>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -142,36 +143,36 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status, $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'Vary' => ['Brief,Prefer'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Vary' => ['Brief,Prefer'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 2,
- '/d:multistatus/d:response/d:href' => 2,
- '/d:multistatus/d:response/d:propstat' => 4,
- '/d:multistatus/d:response/d:propstat/d:prop' => 4,
- '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2,
+ '/d:multistatus/d:response' => 2,
+ '/d:multistatus/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2,
'/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2,
- '/d:multistatus/d:response/d:propstat/d:status' => 4,
- );
+ '/d:multistatus/d:response/d:propstat/d:status' => 4,
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
}
@@ -200,11 +201,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
</d:prop>
</d:principal-property-search>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -215,36 +216,36 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status, $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'Vary' => ['Brief,Prefer'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Vary' => ['Brief,Prefer'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 0,
- '/d:multistatus/d:response/d:href' => 0,
- '/d:multistatus/d:response/d:propstat' => 0,
- '/d:multistatus/d:response/d:propstat/d:prop' => 0,
- '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 0,
+ '/d:multistatus/d:response' => 0,
+ '/d:multistatus/d:response/d:href' => 0,
+ '/d:multistatus/d:response/d:propstat' => 0,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 0,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 0,
'/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 0,
- '/d:multistatus/d:response/d:propstat/d:status' => 0,
- );
+ '/d:multistatus/d:response/d:propstat/d:status' => 0,
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
}
@@ -272,11 +273,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
</d:prop>
</d:principal-property-search>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -287,36 +288,36 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status, $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'Vary' => ['Brief,Prefer'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Vary' => ['Brief,Prefer'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
- '/d:multistatus/d:response' => 2,
- '/d:multistatus/d:response/d:href' => 2,
- '/d:multistatus/d:response/d:propstat' => 4,
- '/d:multistatus/d:response/d:propstat/d:prop' => 4,
- '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2,
+ '/d:multistatus/d:response' => 2,
+ '/d:multistatus/d:response/d:href' => 2,
+ '/d:multistatus/d:response/d:propstat' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop' => 4,
+ '/d:multistatus/d:response/d:propstat/d:prop/d:displayname' => 2,
'/d:multistatus/d:response/d:propstat/d:prop/d:getcontentlength' => 2,
- '/d:multistatus/d:response/d:propstat/d:status' => 4,
- );
+ '/d:multistatus/d:response/d:propstat/d:status' => 4,
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
}
@@ -337,11 +338,11 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
</d:prop>
</d:principal-property-search>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -352,30 +353,30 @@ class PrincipalPropertySearchTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(207, $server->httpResponse->status, $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- 'Vary' => ['Brief,Prefer'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ 'Vary' => ['Brief,Prefer'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:multistatus',
'/d:multistatus/d:response' => 0,
- );
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
}
@@ -386,10 +387,10 @@ class MockPlugin extends Plugin {
function getCurrentUserPrivilegeSet($node) {
- return array(
+ return [
'{DAV:}read',
'{DAV:}write',
- );
+ ];
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php
index 952dc174a..fa1314d10 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalSearchPropertySetTest.php
@@ -21,6 +21,7 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$fakeServer->sapi = new HTTP\SapiMock();
$fakeServer->httpResponse = new HTTP\ResponseMock();
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
$this->assertTrue($plugin instanceof Plugin);
$fakeServer->addPlugin($plugin);
$this->assertEquals($plugin, $fakeServer->getPlugin('acl'));
@@ -34,11 +35,11 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$xml = '<?xml version="1.0"?>
<d:principal-search-property-set xmlns:d="DAV:" />';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '1',
'REQUEST_URI' => '/principals',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -49,10 +50,10 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(400, $server->httpResponse->status);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
}
@@ -61,11 +62,11 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$xml = '<?xml version="1.0"?>
<d:principal-search-property-set xmlns:d="DAV:"><d:ohell /></d:principal-search-property-set>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/principals',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -76,10 +77,10 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(400, $server->httpResponse->status, $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
}
@@ -88,11 +89,11 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$xml = '<?xml version="1.0"?>
<d:principal-search-property-set xmlns:d="DAV:"/>';
- $serverVars = array(
+ $serverVars = [
'REQUEST_METHOD' => 'REPORT',
'HTTP_DEPTH' => '0',
'REQUEST_URI' => '/principals',
- );
+ ];
$request = HTTP\Sapi::createFromServerArray($serverVars);
$request->setBody($xml);
@@ -103,34 +104,34 @@ class PrincipalSearchPropertySetTest extends \PHPUnit_Framework_TestCase {
$server->exec();
$this->assertEquals(200, $server->httpResponse->status, $server->httpResponse->body);
- $this->assertEquals(array(
+ $this->assertEquals([
'X-Sabre-Version' => [DAV\Version::VERSION],
- 'Content-Type' => ['application/xml; charset=utf-8'],
- ), $server->httpResponse->getHeaders());
+ 'Content-Type' => ['application/xml; charset=utf-8'],
+ ], $server->httpResponse->getHeaders());
- $check = array(
+ $check = [
'/d:principal-search-property-set',
- '/d:principal-search-property-set/d:principal-search-property' => 2,
- '/d:principal-search-property-set/d:principal-search-property/d:prop' => 2,
- '/d:principal-search-property-set/d:principal-search-property/d:prop/d:displayname' => 1,
+ '/d:principal-search-property-set/d:principal-search-property' => 2,
+ '/d:principal-search-property-set/d:principal-search-property/d:prop' => 2,
+ '/d:principal-search-property-set/d:principal-search-property/d:prop/d:displayname' => 1,
'/d:principal-search-property-set/d:principal-search-property/d:prop/s:email-address' => 1,
- '/d:principal-search-property-set/d:principal-search-property/d:description' => 2,
- );
+ '/d:principal-search-property-set/d:principal-search-property/d:description' => 2,
+ ];
$xml = simplexml_load_string($server->httpResponse->body);
- $xml->registerXPathNamespace('d','DAV:');
- $xml->registerXPathNamespace('s','http://sabredav.org/ns');
- foreach($check as $v1=>$v2) {
+ $xml->registerXPathNamespace('d', 'DAV:');
+ $xml->registerXPathNamespace('s', 'http://sabredav.org/ns');
+ foreach ($check as $v1 => $v2) {
- $xpath = is_int($v1)?$v2:$v1;
+ $xpath = is_int($v1) ? $v2 : $v1;
$result = $xml->xpath($xpath);
$count = 1;
if (!is_int($v1)) $count = $v2;
- $this->assertEquals($count,count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
+ $this->assertEquals($count, count($result), 'we expected ' . $count . ' appearances of ' . $xpath . ' . We found ' . count($result) . '. Full response body: ' . $server->httpResponse->body);
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php
index 03fd9d64d..20622ad17 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/PrincipalTest.php
@@ -7,10 +7,10 @@ use Sabre\HTTP;
class PrincipalTest extends \PHPUnit_Framework_TestCase {
- public function testConstruct() {
+ function testConstruct() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
$this->assertTrue($principal instanceof Principal);
}
@@ -18,65 +18,65 @@ class PrincipalTest extends \PHPUnit_Framework_TestCase {
/**
* @expectedException Sabre\DAV\Exception
*/
- public function testConstructNoUri() {
+ function testConstructNoUri() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array());
+ $principal = new Principal($principalBackend, []);
}
- public function testGetName() {
+ function testGetName() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals('admin',$principal->getName());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals('admin', $principal->getName());
}
- public function testGetDisplayName() {
+ function testGetDisplayName() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals('admin',$principal->getDisplayname());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals('admin', $principal->getDisplayname());
- $principal = new Principal($principalBackend, array(
- 'uri' => 'principals/admin',
+ $principal = new Principal($principalBackend, [
+ 'uri' => 'principals/admin',
'{DAV:}displayname' => 'Mr. Admin'
- ));
- $this->assertEquals('Mr. Admin',$principal->getDisplayname());
+ ]);
+ $this->assertEquals('Mr. Admin', $principal->getDisplayname());
}
- public function testGetProperties() {
+ function testGetProperties() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array(
- 'uri' => 'principals/admin',
- '{DAV:}displayname' => 'Mr. Admin',
+ $principal = new Principal($principalBackend, [
+ 'uri' => 'principals/admin',
+ '{DAV:}displayname' => 'Mr. Admin',
'{http://www.example.org/custom}custom' => 'Custom',
'{http://sabredav.org/ns}email-address' => 'admin@example.org',
- ));
+ ]);
- $keys = array(
+ $keys = [
'{DAV:}displayname',
'{http://www.example.org/custom}custom',
'{http://sabredav.org/ns}email-address',
- );
+ ];
$props = $principal->getProperties($keys);
- foreach($keys as $key) $this->assertArrayHasKey($key,$props);
+ foreach ($keys as $key) $this->assertArrayHasKey($key, $props);
- $this->assertEquals('Mr. Admin',$props['{DAV:}displayname']);
+ $this->assertEquals('Mr. Admin', $props['{DAV:}displayname']);
$this->assertEquals('admin@example.org', $props['{http://sabredav.org/ns}email-address']);
}
- public function testUpdateProperties() {
+ function testUpdateProperties() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
- $propPatch = new DAV\PropPatch(array('{DAV:}yourmom' => 'test'));
+ $propPatch = new DAV\PropPatch(['{DAV:}yourmom' => 'test']);
$result = $principal->propPatch($propPatch);
$result = $propPatch->commit();
@@ -84,123 +84,123 @@ class PrincipalTest extends \PHPUnit_Framework_TestCase {
}
- public function testGetPrincipalUrl() {
+ function testGetPrincipalUrl() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals('principals/admin',$principal->getPrincipalUrl());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals('principals/admin', $principal->getPrincipalUrl());
}
- public function testGetAlternateUriSet() {
+ function testGetAlternateUriSet() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array(
- 'uri' => 'principals/admin',
- '{DAV:}displayname' => 'Mr. Admin',
+ $principal = new Principal($principalBackend, [
+ 'uri' => 'principals/admin',
+ '{DAV:}displayname' => 'Mr. Admin',
'{http://www.example.org/custom}custom' => 'Custom',
'{http://sabredav.org/ns}email-address' => 'admin@example.org',
- '{DAV:}alternate-URI-set' => array(
+ '{DAV:}alternate-URI-set' => [
'mailto:admin+1@example.org',
'mailto:admin+2@example.org',
'mailto:admin@example.org',
- ),
- ));
+ ],
+ ]);
- $expected = array(
+ $expected = [
'mailto:admin+1@example.org',
'mailto:admin+2@example.org',
'mailto:admin@example.org',
- );
+ ];
- $this->assertEquals($expected,$principal->getAlternateUriSet());
+ $this->assertEquals($expected, $principal->getAlternateUriSet());
}
- public function testGetAlternateUriSetEmpty() {
+ function testGetAlternateUriSetEmpty() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array(
+ $principal = new Principal($principalBackend, [
'uri' => 'principals/admin',
- ));
+ ]);
- $expected = array();
+ $expected = [];
- $this->assertEquals($expected,$principal->getAlternateUriSet());
+ $this->assertEquals($expected, $principal->getAlternateUriSet());
}
- public function testGetGroupMemberSet() {
+ function testGetGroupMemberSet() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals(array(),$principal->getGroupMemberSet());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals([], $principal->getGroupMemberSet());
}
- public function testGetGroupMembership() {
+ function testGetGroupMembership() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals(array(),$principal->getGroupMembership());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals([], $principal->getGroupMembership());
}
- public function testSetGroupMemberSet() {
+ function testSetGroupMemberSet() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $principal->setGroupMemberSet(array('principals/foo'));
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $principal->setGroupMemberSet(['principals/foo']);
- $this->assertEquals(array(
- 'principals/admin' => array('principals/foo'),
- ), $principalBackend->groupMembers);
+ $this->assertEquals([
+ 'principals/admin' => ['principals/foo'],
+ ], $principalBackend->groupMembers);
}
- public function testGetOwner() {
+ function testGetOwner() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals('principals/admin',$principal->getOwner());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals('principals/admin', $principal->getOwner());
}
- public function testGetGroup() {
+ function testGetGroup() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
$this->assertNull($principal->getGroup());
}
- public function testGetACl() {
+ function testGetACl() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $this->assertEquals(array(
- array(
- 'privilege' => '{DAV:}read',
- 'principal' => '{DAV:}authenticated',
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $this->assertEquals([
+ [
+ 'privilege' => '{DAV:}all',
+ 'principal' => '{DAV:}owner',
'protected' => true,
- )
- ),$principal->getACL());
+ ]
+ ], $principal->getACL());
}
/**
- * @expectedException Sabre\DAV\Exception\MethodNotAllowed
+ * @expectedException \Sabre\DAV\Exception\Forbidden
*/
- public function testSetACl() {
+ function testSetACl() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
- $principal->setACL(array());
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
+ $principal->setACL([]);
}
- public function testGetSupportedPrivilegeSet() {
+ function testGetSupportedPrivilegeSet() {
$principalBackend = new PrincipalBackend\Mock();
- $principal = new Principal($principalBackend, array('uri' => 'principals/admin'));
+ $principal = new Principal($principalBackend, ['uri' => 'principals/admin']);
$this->assertNull($principal->getSupportedPrivilegeSet());
}
diff --git a/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php
index fb73cc16a..2de0ba6a8 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVACL/SimplePluginTest.php
@@ -5,7 +5,6 @@ namespace Sabre\DAVACL;
use Sabre\DAV;
use Sabre\HTTP;
-
require_once 'Sabre/DAVACL/MockPrincipal.php';
require_once 'Sabre/DAVACL/MockACLNode.php';
@@ -14,21 +13,22 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
function testValues() {
$aclPlugin = new Plugin();
- $this->assertEquals('acl',$aclPlugin->getPluginName());
+ $this->assertEquals('acl', $aclPlugin->getPluginName());
$this->assertEquals(
- array('access-control', 'calendarserver-principal-property-search'),
+ ['access-control', 'calendarserver-principal-property-search'],
$aclPlugin->getFeatures()
);
$this->assertEquals(
- array(
+ [
'{DAV:}expand-property',
+ '{DAV:}principal-match',
'{DAV:}principal-property-search',
'{DAV:}principal-search-property-set'
- ),
+ ],
$aclPlugin->getSupportedReportSet(''));
- $this->assertEquals(array('ACL'), $aclPlugin->getMethods(''));
+ $this->assertEquals(['ACL'], $aclPlugin->getMethods(''));
$this->assertEquals(
@@ -39,90 +39,84 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
function testGetFlatPrivilegeSet() {
- $expected = array(
- '{DAV:}all' => array(
- 'privilege' => '{DAV:}all',
- 'abstract' => true,
- 'aggregates' => array(
+ $expected = [
+ '{DAV:}all' => [
+ 'privilege' => '{DAV:}all',
+ 'abstract' => false,
+ 'aggregates' => [
'{DAV:}read',
'{DAV:}write',
- ),
- 'concrete' => null,
- ),
- '{DAV:}read' => array(
- 'privilege' => '{DAV:}read',
- 'abstract' => false,
- 'aggregates' => array(
+ ],
+ 'concrete' => '{DAV:}all',
+ ],
+ '{DAV:}read' => [
+ 'privilege' => '{DAV:}read',
+ 'abstract' => false,
+ 'aggregates' => [
'{DAV:}read-acl',
'{DAV:}read-current-user-privilege-set',
- ),
+ ],
'concrete' => '{DAV:}read',
- ),
- '{DAV:}read-acl' => array(
- 'privilege' => '{DAV:}read-acl',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}read-acl',
- ),
- '{DAV:}read-current-user-privilege-set' => array(
- 'privilege' => '{DAV:}read-current-user-privilege-set',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}read-current-user-privilege-set',
- ),
- '{DAV:}write' => array(
- 'privilege' => '{DAV:}write',
- 'abstract' => false,
- 'aggregates' => array(
- '{DAV:}write-acl',
+ ],
+ '{DAV:}read-acl' => [
+ 'privilege' => '{DAV:}read-acl',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}read-acl',
+ ],
+ '{DAV:}read-current-user-privilege-set' => [
+ 'privilege' => '{DAV:}read-current-user-privilege-set',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}read-current-user-privilege-set',
+ ],
+ '{DAV:}write' => [
+ 'privilege' => '{DAV:}write',
+ 'abstract' => false,
+ 'aggregates' => [
'{DAV:}write-properties',
'{DAV:}write-content',
+ '{DAV:}unlock',
'{DAV:}bind',
'{DAV:}unbind',
- '{DAV:}unlock',
- ),
+ ],
'concrete' => '{DAV:}write',
- ),
- '{DAV:}write-acl' => array(
- 'privilege' => '{DAV:}write-acl',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}write-acl',
- ),
- '{DAV:}write-properties' => array(
- 'privilege' => '{DAV:}write-properties',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}write-properties',
- ),
- '{DAV:}write-content' => array(
- 'privilege' => '{DAV:}write-content',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}write-content',
- ),
- '{DAV:}unlock' => array(
- 'privilege' => '{DAV:}unlock',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}unlock',
- ),
- '{DAV:}bind' => array(
- 'privilege' => '{DAV:}bind',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}bind',
- ),
- '{DAV:}unbind' => array(
- 'privilege' => '{DAV:}unbind',
- 'abstract' => false,
- 'aggregates' => array(),
- 'concrete' => '{DAV:}unbind',
- ),
-
- );
+ ],
+ '{DAV:}write-properties' => [
+ 'privilege' => '{DAV:}write-properties',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}write-properties',
+ ],
+ '{DAV:}write-content' => [
+ 'privilege' => '{DAV:}write-content',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}write-content',
+ ],
+ '{DAV:}unlock' => [
+ 'privilege' => '{DAV:}unlock',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}unlock',
+ ],
+ '{DAV:}bind' => [
+ 'privilege' => '{DAV:}bind',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}bind',
+ ],
+ '{DAV:}unbind' => [
+ 'privilege' => '{DAV:}unbind',
+ 'abstract' => false,
+ 'aggregates' => [],
+ 'concrete' => '{DAV:}unbind',
+ ],
+
+ ];
$plugin = new Plugin();
+ $plugin->allowUnauthenticatedAccess = false;
$server = new DAV\Server();
$server->addPlugin($plugin);
$this->assertEquals($expected, $plugin->getFlatPrivilegeSet(''));
@@ -132,24 +126,26 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
function testCurrentUserPrincipalsNotLoggedIn() {
$acl = new Plugin();
+ $acl->allowUnauthenticatedAccess = false;
$server = new DAV\Server();
$server->addPlugin($acl);
- $this->assertEquals(array(),$acl->getCurrentUserPrincipals());
+ $this->assertEquals([], $acl->getCurrentUserPrincipals());
}
function testCurrentUserPrincipalsSimple() {
- $tree = array(
+ $tree = [
- new DAV\SimpleCollection('principals', array(
- new MockPrincipal('admin','principals/admin'),
- ))
+ new DAV\SimpleCollection('principals', [
+ new MockPrincipal('admin', 'principals/admin'),
+ ])
- );
+ ];
$acl = new Plugin();
+ $acl->allowUnauthenticatedAccess = false;
$server = new DAV\Server($tree);
$server->addPlugin($acl);
@@ -159,24 +155,25 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
//forcing login
$auth->beforeMethod(new HTTP\Request(), new HTTP\Response());
- $this->assertEquals(array('principals/admin'),$acl->getCurrentUserPrincipals());
+ $this->assertEquals(['principals/admin'], $acl->getCurrentUserPrincipals());
}
function testCurrentUserPrincipalsGroups() {
- $tree = array(
+ $tree = [
- new DAV\SimpleCollection('principals', array(
- new MockPrincipal('admin','principals/admin',array('principals/administrators', 'principals/everyone')),
- new MockPrincipal('administrators','principals/administrators',array('principals/groups'), array('principals/admin')),
- new MockPrincipal('everyone','principals/everyone',array(), array('principals/admin')),
- new MockPrincipal('groups','principals/groups',array(), array('principals/administrators')),
- ))
+ new DAV\SimpleCollection('principals', [
+ new MockPrincipal('admin', 'principals/admin', ['principals/administrators', 'principals/everyone']),
+ new MockPrincipal('administrators', 'principals/administrators', ['principals/groups'], ['principals/admin']),
+ new MockPrincipal('everyone', 'principals/everyone', [], ['principals/admin']),
+ new MockPrincipal('groups', 'principals/groups', [], ['principals/administrators']),
+ ])
- );
+ ];
$acl = new Plugin();
+ $acl->allowUnauthenticatedAccess = false;
$server = new DAV\Server($tree);
$server->addPlugin($acl);
@@ -186,75 +183,77 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
//forcing login
$auth->beforeMethod(new HTTP\Request(), new HTTP\Response());
- $expected = array(
+ $expected = [
'principals/admin',
'principals/administrators',
'principals/everyone',
'principals/groups',
- );
+ ];
- $this->assertEquals($expected,$acl->getCurrentUserPrincipals());
+ $this->assertEquals($expected, $acl->getCurrentUserPrincipals());
// The second one should trigger the cache and be identical
- $this->assertEquals($expected,$acl->getCurrentUserPrincipals());
+ $this->assertEquals($expected, $acl->getCurrentUserPrincipals());
}
function testGetACL() {
- $acl = array(
- array(
+ $acl = [
+ [
'principal' => 'principals/admin',
'privilege' => '{DAV:}read',
- ),
- array(
+ ],
+ [
'principal' => 'principals/admin',
'privilege' => '{DAV:}write',
- ),
- );
+ ],
+ ];
- $tree = array(
- new MockACLNode('foo',$acl),
- );
+ $tree = [
+ new MockACLNode('foo', $acl),
+ ];
$server = new DAV\Server($tree);
$aclPlugin = new Plugin();
+ $aclPlugin->allowUnauthenticatedAccess = false;
$server->addPlugin($aclPlugin);
- $this->assertEquals($acl,$aclPlugin->getACL('foo'));
+ $this->assertEquals($acl, $aclPlugin->getACL('foo'));
}
function testGetCurrentUserPrivilegeSet() {
- $acl = array(
- array(
+ $acl = [
+ [
'principal' => 'principals/admin',
'privilege' => '{DAV:}read',
- ),
- array(
+ ],
+ [
'principal' => 'principals/user1',
'privilege' => '{DAV:}read',
- ),
- array(
+ ],
+ [
'principal' => 'principals/admin',
'privilege' => '{DAV:}write',
- ),
- );
+ ],
+ ];
- $tree = array(
- new MockACLNode('foo',$acl),
+ $tree = [
+ new MockACLNode('foo', $acl),
- new DAV\SimpleCollection('principals', array(
- new MockPrincipal('admin','principals/admin'),
- )),
+ new DAV\SimpleCollection('principals', [
+ new MockPrincipal('admin', 'principals/admin'),
+ ]),
- );
+ ];
$server = new DAV\Server($tree);
$aclPlugin = new Plugin();
+ $aclPlugin->allowUnauthenticatedAccess = false;
$server->addPlugin($aclPlugin);
$auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock());
@@ -263,52 +262,51 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
//forcing login
$auth->beforeMethod(new HTTP\Request(), new HTTP\Response());
- $expected = array(
+ $expected = [
'{DAV:}write',
- '{DAV:}write-acl',
'{DAV:}write-properties',
'{DAV:}write-content',
- '{DAV:}bind',
- '{DAV:}unbind',
'{DAV:}unlock',
+ '{DAV:}write-acl',
'{DAV:}read',
'{DAV:}read-acl',
'{DAV:}read-current-user-privilege-set',
- );
+ ];
- $this->assertEquals($expected,$aclPlugin->getCurrentUserPrivilegeSet('foo'));
+ $this->assertEquals($expected, $aclPlugin->getCurrentUserPrivilegeSet('foo'));
}
function testCheckPrivileges() {
- $acl = array(
- array(
+ $acl = [
+ [
'principal' => 'principals/admin',
'privilege' => '{DAV:}read',
- ),
- array(
+ ],
+ [
'principal' => 'principals/user1',
'privilege' => '{DAV:}read',
- ),
- array(
+ ],
+ [
'principal' => 'principals/admin',
'privilege' => '{DAV:}write',
- ),
- );
+ ],
+ ];
- $tree = array(
- new MockACLNode('foo',$acl),
+ $tree = [
+ new MockACLNode('foo', $acl),
- new DAV\SimpleCollection('principals', array(
- new MockPrincipal('admin','principals/admin'),
- )),
+ new DAV\SimpleCollection('principals', [
+ new MockPrincipal('admin', 'principals/admin'),
+ ]),
- );
+ ];
$server = new DAV\Server($tree);
$aclPlugin = new Plugin();
+ $aclPlugin->allowUnauthenticatedAccess = false;
$server->addPlugin($aclPlugin);
$auth = new DAV\Auth\Plugin(new DAV\Auth\Backend\Mock());
@@ -317,11 +315,7 @@ class SimplePluginTest extends \PHPUnit_Framework_TestCase {
//forcing login
//$auth->beforeMethod('GET','/');
- $this->assertFalse($aclPlugin->checkPrivileges('foo', array('{DAV:}read'), Plugin::R_PARENT, false));
+ $this->assertFalse($aclPlugin->checkPrivileges('foo', ['{DAV:}read'], Plugin::R_PARENT, false));
}
}
-
-
-
-
diff --git a/vendor/sabre/dav/tests/Sabre/DAVServerTest.php b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php
index d329b5b05..35f240d23 100644
--- a/vendor/sabre/dav/tests/Sabre/DAVServerTest.php
+++ b/vendor/sabre/dav/tests/Sabre/DAVServerTest.php
@@ -27,6 +27,7 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
protected $setupCalDAVICSExport = false;
protected $setupLocks = false;
protected $setupFiles = false;
+ protected $setupSharing = false;
protected $setupPropertyStorage = false;
/**
@@ -90,6 +91,13 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
protected $locksPlugin;
/**
+ * Sharing plugin.
+ *
+ * @var \Sabre\DAV\Sharing\Plugin
+ */
+ protected $sharingPlugin;
+
+ /*
* @var Sabre\DAV\PropertyStorage\Plugin
*/
protected $propertyStoragePlugin;
@@ -102,6 +110,12 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
function setUp() {
+ $this->initializeEverything();
+
+ }
+
+ function initializeEverything() {
+
$this->setUpBackends();
$this->setUpTree();
@@ -113,6 +127,10 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
$this->caldavPlugin = new CalDAV\Plugin();
$this->server->addPlugin($this->caldavPlugin);
}
+ if ($this->setupCalDAVSharing || $this->setupSharing) {
+ $this->sharingPlugin = new DAV\Sharing\Plugin();
+ $this->server->addPlugin($this->sharingPlugin);
+ }
if ($this->setupCalDAVSharing) {
$this->caldavSharingPlugin = new CalDAV\SharingPlugin();
$this->server->addPlugin($this->caldavSharingPlugin);
@@ -132,10 +150,6 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
$this->carddavPlugin = new CardDAV\Plugin();
$this->server->addPlugin($this->carddavPlugin);
}
- if ($this->setupACL) {
- $this->aclPlugin = new DAVACL\Plugin();
- $this->server->addPlugin($this->aclPlugin);
- }
if ($this->setupLocks) {
$this->locksPlugin = new DAV\Locks\Plugin(
$this->locksBackend
@@ -149,13 +163,15 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
$this->server->addPlugin($this->propertyStoragePlugin);
}
if ($this->autoLogin) {
- $authBackend = new DAV\Auth\Backend\Mock();
- $authBackend->setPrincipal('principals/' . $this->autoLogin);
- $this->authPlugin = new DAV\Auth\Plugin($authBackend);
- $this->server->addPlugin($this->authPlugin);
-
- // This will trigger the actual login procedure
- $this->authPlugin->beforeMethod(new Request(), new Response());
+ $this->autoLogin($this->autoLogin);
+ }
+ if ($this->setupACL) {
+ $this->aclPlugin = new DAVACL\Plugin();
+ if (!$this->autoLogin) {
+ $this->aclPlugin->allowUnauthenticatedAccess = false;
+ }
+ $this->aclPlugin->adminPrincipals = ['principals/admin'];
+ $this->server->addPlugin($this->aclPlugin);
}
}
@@ -166,23 +182,55 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
* You can either pass an instance of Sabre\HTTP\Request, or an array,
* which will then be used as the _SERVER array.
*
+ * If $expectedStatus is set, we'll compare it with the HTTP status of
+ * the returned response. If it doesn't match, we'll immediately fail
+ * the test.
+ *
* @param array|\Sabre\HTTP\Request $request
+ * @param int $expectedStatus
* @return \Sabre\HTTP\Response
*/
- function request($request) {
+ function request($request, $expectedStatus = null) {
if (is_array($request)) {
$request = HTTP\Request::createFromServerArray($request);
}
+ $response = new HTTP\ResponseMock();
+
$this->server->httpRequest = $request;
- $this->server->httpResponse = new HTTP\ResponseMock();
+ $this->server->httpResponse = $response;
$this->server->exec();
+ if ($expectedStatus) {
+ $responseBody = $expectedStatus !== $response->getStatus() ? $response->getBodyAsString() : '';
+ $this->assertEquals($expectedStatus, $response->getStatus(), 'Incorrect HTTP status received for request. Response body: ' . $responseBody);
+ }
return $this->server->httpResponse;
}
/**
+ * This function takes a username and sets the server in a state where
+ * this user is logged in, and no longer requires an authentication check.
+ *
+ * @param string $userName
+ */
+ function autoLogin($userName) {
+ $authBackend = new DAV\Auth\Backend\Mock();
+ $authBackend->setPrincipal('principals/' . $userName);
+ $this->authPlugin = new DAV\Auth\Plugin($authBackend);
+
+ // If the auth plugin already exists, we're removing its hooks:
+ if ($oldAuth = $this->server->getPlugin('auth')) {
+ $this->server->removeListener('beforeMethod', [$oldAuth, 'beforeMethod']);
+ }
+ $this->server->addPlugin($this->authPlugin);
+
+ // This will trigger the actual login procedure
+ $this->authPlugin->beforeMethod(new Request(), new Response());
+ }
+
+ /**
* Override this to provide your own Tree for your test-case.
*/
function setUpTree() {
@@ -200,10 +248,14 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
);
}
- if ($this->setupCardDAV || $this->setupCalDAV) {
+ if ($this->setupCalDAV) {
$this->tree[] = new CalDAV\Principal\Collection(
$this->principalBackend
);
+ } elseif ($this->setupCardDAV || $this->setupACL) {
+ $this->tree[] = new DAVACL\PrincipalCollection(
+ $this->principalBackend
+ );
}
if ($this->setupFiles) {
@@ -231,7 +283,7 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
if ($this->setupCardDAV && is_null($this->carddavBackend)) {
$this->carddavBackend = new CardDAV\Backend\Mock($this->carddavAddressBooks, $this->carddavCards);
}
- if ($this->setupCardDAV || $this->setupCalDAV) {
+ if ($this->setupCardDAV || $this->setupCalDAV || $this->setupACL) {
$this->principalBackend = new DAVACL\PrincipalBackend\Mock();
}
if ($this->setupLocks) {
@@ -244,7 +296,7 @@ abstract class DAVServerTest extends \PHPUnit_Framework_TestCase {
}
- function assertHTTPStatus($expectedStatus, HTTP\Request $req) {
+ function assertHttpStatus($expectedStatus, HTTP\Request $req) {
$resp = $this->request($req);
$this->assertEquals((int)$expectedStatus, (int)$resp->status, 'Incorrect HTTP status received: ' . $resp->body);
diff --git a/vendor/sabre/dav/tests/Sabre/TestUtil.php b/vendor/sabre/dav/tests/Sabre/TestUtil.php
index 20bce1ea0..9df94915f 100644
--- a/vendor/sabre/dav/tests/Sabre/TestUtil.php
+++ b/vendor/sabre/dav/tests/Sabre/TestUtil.php
@@ -11,17 +11,17 @@ class TestUtil {
*/
static function clearTempDir() {
- self::deleteTree(SABRE_TEMPDIR,false);
+ self::deleteTree(SABRE_TEMPDIR, false);
}
- static private function deleteTree($path,$deleteRoot = true) {
+ private static function deleteTree($path, $deleteRoot = true) {
- foreach(scandir($path) as $node) {
+ foreach (scandir($path) as $node) {
- if ($node=='.' || $node=='..') continue;
- $myPath = $path.'/'. $node;
+ if ($node == '.' || $node == '..') continue;
+ $myPath = $path . '/' . $node;
if (is_file($myPath)) {
unlink($myPath);
} else {
@@ -38,8 +38,8 @@ class TestUtil {
static function getMySQLDB() {
try {
- $pdo = new \PDO(SABRE_MYSQLDSN,SABRE_MYSQLUSER,SABRE_MYSQLPASS);
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+ $pdo = new \PDO(SABRE_MYSQLDSN, SABRE_MYSQLUSER, SABRE_MYSQLPASS);
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return $pdo;
} catch (\PDOException $e) {
return null;
@@ -49,10 +49,23 @@ class TestUtil {
static function getSQLiteDB() {
- $pdo = new \PDO('sqlite:'.SABRE_TEMPDIR.'/pdobackend');
- $pdo->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
+ $pdo = new \PDO('sqlite:' . SABRE_TEMPDIR . '/pdobackend');
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
return $pdo;
}
+ static function getPgSqlDB() {
+
+ //try {
+ $pdo = new \PDO(SABRE_PGSQLDSN);
+ $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+ return $pdo;
+ //} catch (\PDOException $e) {
+ // return null;
+ //}
+
+ }
+
+
}
diff --git a/vendor/sabre/dav/tests/bootstrap.php b/vendor/sabre/dav/tests/bootstrap.php
index 325ccd3c7..26eb32aa2 100644
--- a/vendor/sabre/dav/tests/bootstrap.php
+++ b/vendor/sabre/dav/tests/bootstrap.php
@@ -7,28 +7,30 @@ $autoLoader = include __DIR__ . '/../vendor/autoload.php';
// SabreDAV tests auto loading
$autoLoader->add('Sabre\\', __DIR__);
// VObject tests auto loading
-$autoLoader->addPsr4('Sabre\\VObject\\',__DIR__ . '/../vendor/sabre/vobject/tests/VObject');
-$autoLoader->addPsr4('Sabre\\Xml\\',__DIR__ . '/../vendor/sabre/xml/tests/Sabre/Xml');
+$autoLoader->addPsr4('Sabre\\VObject\\', __DIR__ . '/../vendor/sabre/vobject/tests/VObject');
+$autoLoader->addPsr4('Sabre\\Xml\\', __DIR__ . '/../vendor/sabre/xml/tests/Sabre/Xml');
date_default_timezone_set('UTC');
$config = [
'SABRE_TEMPDIR' => dirname(__FILE__) . '/temp/',
- 'SABRE_HASSQLITE' => in_array('sqlite',PDO::getAvailableDrivers()),
- 'SABRE_HASMYSQL' => in_array('mysql',PDO::getAvailableDrivers()),
- 'SABRE_MYSQLDSN' => 'mysql:host=127.0.0.1;dbname=sabredav',
- 'SABRE_MYSQLUSER' => 'root',
+ 'SABRE_HASSQLITE' => in_array('sqlite', PDO::getAvailableDrivers()),
+ 'SABRE_HASMYSQL' => in_array('mysql', PDO::getAvailableDrivers()),
+ 'SABRE_HASPGSQL' => in_array('pgsql', PDO::getAvailableDrivers()),
+ 'SABRE_MYSQLDSN' => 'mysql:host=127.0.0.1;dbname=sabredav_test',
+ 'SABRE_MYSQLUSER' => 'sabredav',
'SABRE_MYSQLPASS' => '',
+ 'SABRE_PGSQLDSN' => 'pgsql:host=localhost;dbname=sabredav_test;user=sabredav;password=sabredav',
];
if (file_exists(__DIR__ . '/config.user.php')) {
include __DIR__ . '/config.user.php';
- foreach($userConfig as $key=>$value) {
+ foreach ($userConfig as $key => $value) {
$config[$key] = $value;
}
}
-foreach($config as $key=>$value) {
+foreach ($config as $key => $value) {
if (!defined($key)) define($key, $value);
}
diff --git a/vendor/sabre/dav/tests/phpunit.xml b/vendor/sabre/dav/tests/phpunit.xml
deleted file mode 100644
index db475f12b..000000000
--- a/vendor/sabre/dav/tests/phpunit.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<phpunit
- colors="true"
- bootstrap="bootstrap.php"
- convertErrorsToExceptions="true"
- convertNoticesToExceptions="true"
- convertWarningsToExceptions="true"
- strict="true"
- >
- <testsuite name="sabre-event">
- <directory>../vendor/sabre/event/tests/</directory>
- </testsuite>
- <testsuite name="sabre-uri">
- <directory>../vendor/sabre/uri/tests/</directory>
- </testsuite>
- <testsuite name="sabre-xml">
- <directory>../vendor/sabre/xml/tests/Sabre/Xml/</directory>
- </testsuite>
- <testsuite name="sabre-http">
- <directory>../vendor/sabre/http/tests/HTTP</directory>
- </testsuite>
- <testsuite name="sabre-vobject">
- <directory>../vendor/sabre/vobject/tests/VObject</directory>
- </testsuite>
-
- <testsuite name="sabre-dav">
- <directory>Sabre/DAV</directory>
- </testsuite>
- <testsuite name="sabre-davacl">
- <directory>Sabre/DAVACL</directory>
- </testsuite>
- <testsuite name="sabre-caldav">
- <directory>Sabre/CalDAV</directory>
- </testsuite>
- <testsuite name="sabre-carddav">
- <directory>Sabre/CardDAV</directory>
- </testsuite>
-
- <filter>
- <whitelist addUncoveredFilesFromWhitelist="true">
- <directory suffix=".php">../lib/</directory>
- <exclude>
- <file>../lib/Sabre/autoload.php</file>
- <file>../lib/Sabre/VObject/includes.php</file>
- </exclude>
- </whitelist>
- </filter>
-</phpunit>
diff --git a/vendor/sabre/vobject/bin/bench.php b/vendor/sabre/vobject/bin/bench.php
index 807b40777..807b40777 100755..100644
--- a/vendor/sabre/vobject/bin/bench.php
+++ b/vendor/sabre/vobject/bin/bench.php
diff --git a/vendor/sabre/vobject/bin/fetch_windows_zones.php b/vendor/sabre/vobject/bin/fetch_windows_zones.php
index 1b1fdc37c..1b1fdc37c 100755..100644
--- a/vendor/sabre/vobject/bin/fetch_windows_zones.php
+++ b/vendor/sabre/vobject/bin/fetch_windows_zones.php
diff --git a/vendor/sabre/vobject/bin/generateicalendardata.php b/vendor/sabre/vobject/bin/generateicalendardata.php
index dfcf18780..dfcf18780 100755..100644
--- a/vendor/sabre/vobject/bin/generateicalendardata.php
+++ b/vendor/sabre/vobject/bin/generateicalendardata.php
diff --git a/vendor/sabre/vobject/bin/mergeduplicates.php b/vendor/sabre/vobject/bin/mergeduplicates.php
index 1662e7bf3..1662e7bf3 100755..100644
--- a/vendor/sabre/vobject/bin/mergeduplicates.php
+++ b/vendor/sabre/vobject/bin/mergeduplicates.php
diff --git a/vendor/sabre/xml/.travis.yml b/vendor/sabre/xml/.travis.yml
index 19a61a2c8..9bba4d451 100644
--- a/vendor/sabre/xml/.travis.yml
+++ b/vendor/sabre/xml/.travis.yml
@@ -4,6 +4,7 @@ php:
- 5.5
- 5.6
- 7
+ - nightly
- hhvm
matrix:
@@ -11,10 +12,14 @@ matrix:
sudo: false
-cache: vendor
+cache:
+ directories:
+ - $HOME/.composer/cache
script:
- ./bin/phpunit --configuration tests/phpunit.xml.dist
- ./bin/sabre-cs-fixer fix . --dry-run --diff
-before_script: composer install
+before_script:
+ - phpenv config-rm xdebug.ini; true
+ - composer install
diff --git a/vendor/sabre/xml/CHANGELOG.md b/vendor/sabre/xml/CHANGELOG.md
index 3d8eb0fcb..a8085401b 100644
--- a/vendor/sabre/xml/CHANGELOG.md
+++ b/vendor/sabre/xml/CHANGELOG.md
@@ -1,6 +1,17 @@
ChangeLog
=========
+1.4.2 (????-??-??)
+------------------
+
+* The `contextStack` in the Reader object is now correctly rolled back in
+ error conditions (@staabm).
+* repeatingElements deserializer now still parses if a bare element name
+ without clark notation was given.
+* `$elementMap` in the Reader now also supports bare element names.
+* `Service::expect()` can now also work with bare element names.
+
+
1.4.1 (2016-03-12)
-----------------
diff --git a/vendor/sabre/xml/lib/Deserializer/functions.php b/vendor/sabre/xml/lib/Deserializer/functions.php
index fe88a6db8..2e5d877e9 100644
--- a/vendor/sabre/xml/lib/Deserializer/functions.php
+++ b/vendor/sabre/xml/lib/Deserializer/functions.php
@@ -14,7 +14,7 @@ use Sabre\Xml\Reader;
* deserializer functions.
*/
-/*
+/**
* The 'keyValue' deserializer parses all child elements, and outputs them as
* a "key=>value" array.
*
@@ -213,7 +213,7 @@ function valueObject(Reader $reader, $className, $namespace) {
}
-/*
+/**
* This deserializer helps you deserialize xml structures that look like
* this:
*
@@ -240,6 +240,9 @@ function valueObject(Reader $reader, $className, $namespace) {
*/
function repeatingElements(Reader $reader, $childElementName) {
+ if ($childElementName[0] !== '{') {
+ $childElementName = '{}' . $childElementName;
+ }
$result = [];
foreach ($reader->parseGetElements() as $element) {
diff --git a/vendor/sabre/xml/lib/Reader.php b/vendor/sabre/xml/lib/Reader.php
index 7cba76c59..f35dc8537 100644
--- a/vendor/sabre/xml/lib/Reader.php
+++ b/vendor/sabre/xml/lib/Reader.php
@@ -142,7 +142,12 @@ class Reader extends XMLReader {
// choice. See:
//
// https://bugs.php.net/bug.php?id=64230
- if (!@$this->read()) return false;
+ if (!@$this->read()) {
+ if (!is_null($elementMap)) {
+ $this->popContext();
+ }
+ return false;
+ }
while (true) {
@@ -152,6 +157,9 @@ class Reader extends XMLReader {
if ($errors) {
libxml_clear_errors();
+ if (!is_null($elementMap)) {
+ $this->popContext();
+ }
throw new LibXMLException($errors);
}
}
@@ -170,6 +178,9 @@ class Reader extends XMLReader {
$this->read();
break 2;
case self::NONE :
+ if (!is_null($elementMap)) {
+ $this->popContext();
+ }
throw new ParseException('We hit the end of the document prematurely. This likely means that some parser "eats" too many elements. Do not attempt to continue parsing.');
default :
// Advance to the next element
@@ -282,8 +293,13 @@ class Reader extends XMLReader {
*/
function getDeserializerForElementName($name) {
+
if (!array_key_exists($name, $this->elementMap)) {
- return ['Sabre\\Xml\\Element\\Base', 'xmlDeserialize'];
+ if (substr($name, 0, 2) == '{}' && array_key_exists(substr($name, 2), $this->elementMap)) {
+ $name = substr($name, 2);
+ } else {
+ return ['Sabre\\Xml\\Element\\Base', 'xmlDeserialize'];
+ }
}
$deserializer = $this->elementMap[$name];
diff --git a/vendor/sabre/xml/lib/Service.php b/vendor/sabre/xml/lib/Service.php
index b2603a4c7..09ee341cf 100644
--- a/vendor/sabre/xml/lib/Service.php
+++ b/vendor/sabre/xml/lib/Service.php
@@ -151,8 +151,14 @@ class Service {
$r->contextUri = $contextUri;
$r->xml($input);
+ $rootElementName = (array)$rootElementName;
+
+ foreach ($rootElementName as &$rEl) {
+ if ($rEl[0] !== '{') $rEl = '{}' . $rEl;
+ }
+
$result = $r->parse();
- if (!in_array($result['name'], (array)$rootElementName, true)) {
+ if (!in_array($result['name'], $rootElementName, true)) {
throw new ParseException('Expected ' . implode(' or ', (array)$rootElementName) . ' but received ' . $result['name'] . ' as the root element');
}
return $result['value'];
diff --git a/view/css/mod_cal.css b/view/css/mod_cal.css
index 184227a91..f0b5c0166 100644
--- a/view/css/mod_cal.css
+++ b/view/css/mod_cal.css
@@ -1,7 +1,3 @@
-.fc-scroller {
- overflow: hidden !important;
-}
-
/* fix borders */
.fc th:first-child,
diff --git a/view/css/mod_events.css b/view/css/mod_events.css
index 184227a91..f0b5c0166 100644
--- a/view/css/mod_events.css
+++ b/view/css/mod_events.css
@@ -1,7 +1,3 @@
-.fc-scroller {
- overflow: hidden !important;
-}
-
/* fix borders */
.fc th:first-child,
diff --git a/view/css/widgets.css b/view/css/widgets.css
index 38809896c..2a7c57f53 100644
--- a/view/css/widgets.css
+++ b/view/css/widgets.css
@@ -11,6 +11,7 @@
width: 100%;
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
+ border-right: 0px;
}
.tags {
diff --git a/view/js/main.js b/view/js/main.js
index f279417d9..2caf5a1dd 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -941,6 +941,11 @@ function dropItem(url, object) {
$('body').css('cursor', 'auto');
});
});
+ return true;
+
+ }
+ else {
+ return false;
}
}
diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css
index c9c85daa3..5768ccbd9 100644
--- a/view/theme/redbasic/css/style.css
+++ b/view/theme/redbasic/css/style.css
@@ -1136,18 +1136,31 @@ margin-right: 50px;
list-style-type: none;
}
+.generic-icons {
+ font-size: 1.2em;
+ color: $toolicon_colour;
+ margin-right: 7px;
+}
+
+.generic-icons:hover {
+ color: $toolicon_colour;
+}
+
.admin-icons {
font-size: 1.2em;
color: $toolicon_colour;
- margin-right: 10px;
+ margin-right: 7px;
}
+.drop-icons,
a .drop-icons {
color: $toolicon_colour;
font-size: 1.2em;
text-decoration: none;
+ cursor: pointer;
}
-
+
+.drop-icons:hover,
a .drop-icons:hover {
color: #FF0000;
}
diff --git a/view/tpl/dreport.tpl b/view/tpl/dreport.tpl
new file mode 100644
index 000000000..7d5524a6a
--- /dev/null
+++ b/view/tpl/dreport.tpl
@@ -0,0 +1,21 @@
+<div class="generic-content-wrapper">
+ <div class="section-title-wrapper">
+ {{if $table == 'item'}}
+ <a href="dreport/push/{{$mid}}"><button class="btn btn-default btn-xs pull-right">{{$push}}</button></a>
+ {{/if}}
+ <h2>{{$title}}</h2>
+ </div>
+
+ <div>
+ <table>
+ {{if $entries}}
+ {{foreach $entries as $e}}
+ <tr>
+ <td width="40%">{{$e.name}}</td>
+ <td width="20%">{{$e.result}}</td>
+ <td width="20%">{{$e.time}}</td>
+ </tr>
+ {{/foreach}}
+ {{/if}}
+ </table>
+</div>
diff --git a/view/tpl/event_head.tpl b/view/tpl/event_head.tpl
index 762bdcbb8..4397c5c9d 100755
--- a/view/tpl/event_head.tpl
+++ b/view/tpl/event_head.tpl
@@ -34,7 +34,13 @@
$('#events-calendar').fullCalendar('option', 'height', 'auto');
}
else {
- $('#events-calendar').fullCalendar('option', 'height', '');
+ if($('main').hasClass('fullscreen')) {
+ $('#calendar').fullCalendar('option', 'height', $(window).height() - $('.section-title-wrapper').outerHeight(true) - 2); // -2 is for border width (.generic-content-wrapper top and bottom) of .generic-content-wrapper
+
+ }
+ else {
+ $('#calendar').fullCalendar('option', 'height', '');
+ }
}
$('#title').text(view.title);
}
diff --git a/view/tpl/jot-header.tpl b/view/tpl/jot-header.tpl
index f3dd8cafe..9953875ef 100755
--- a/view/tpl/jot-header.tpl
+++ b/view/tpl/jot-header.tpl
@@ -7,6 +7,7 @@ var pretext = '{{$pretext}}';
function initEditor(cb){
if (editor==false){
$("#profile-jot-text-loading").spin('small').show();
+ {{$geotag}}
if(plaintext == 'none') {
$("#profile-jot-text-loading").spin(false).hide();
$("#profile-jot-text").css({ 'height': 200, 'color': '#000', 'line-height': 'inherit' });
@@ -362,7 +363,6 @@ function enableOnUser(){
$('#profile-nolocation-wrapper').attr('disabled', true);
}
- {{$geotag}}
var initializeEmbedPhotoDialog = function () {
$('.embed-photo-selected-photo').each(function (index) {
diff --git a/view/tpl/register.tpl b/view/tpl/register.tpl
index 4a827ca16..c84934626 100755
--- a/view/tpl/register.tpl
+++ b/view/tpl/register.tpl
@@ -54,5 +54,8 @@
<button class="btn btn-primary" type="submit" name="submit" id="newchannel-submit-button" value="{{$submit}}">{{$submit}}</button>
<div id="register-submit-end" class="register-field-end"></div>
</form>
+ <br />
+ <div class="descriptive-text">{{$verify_note}}</div>
+
</div>
</div>