From 9b0a5f80b87265a251c7e2a3a63bebd5b408336e Mon Sep 17 00:00:00 2001 From: Yoann Lecuyer Date: Wed, 11 May 2016 18:14:34 -0500 Subject: [PATCH] Added bower missing dependencies (#94) --- public/vendor/fullcalendar/.bower.json | 60 + public/vendor/fullcalendar/CHANGELOG.md | 945 + public/vendor/fullcalendar/CONTRIBUTING.md | 128 + public/vendor/fullcalendar/LICENSE.txt | 20 + public/vendor/fullcalendar/README.md | 10 + public/vendor/fullcalendar/bower.json | 51 + .../vendor/fullcalendar/dist/fullcalendar.css | 1265 + .../vendor/fullcalendar/dist/fullcalendar.js | 12568 +++ .../fullcalendar/dist/fullcalendar.min.css | 5 + .../fullcalendar/dist/fullcalendar.min.js | 2482 + .../fullcalendar/dist/fullcalendar.print.css | 208 + public/vendor/fullcalendar/dist/gcal.js | 180 + public/vendor/fullcalendar/dist/lang-all.js | 4 + public/vendor/fullcalendar/dist/lang/ar-ma.js | 1 + public/vendor/fullcalendar/dist/lang/ar-sa.js | 1 + public/vendor/fullcalendar/dist/lang/ar-tn.js | 1 + public/vendor/fullcalendar/dist/lang/ar.js | 1 + public/vendor/fullcalendar/dist/lang/bg.js | 1 + public/vendor/fullcalendar/dist/lang/ca.js | 1 + public/vendor/fullcalendar/dist/lang/cs.js | 1 + public/vendor/fullcalendar/dist/lang/da.js | 1 + public/vendor/fullcalendar/dist/lang/de-at.js | 1 + public/vendor/fullcalendar/dist/lang/de.js | 1 + public/vendor/fullcalendar/dist/lang/el.js | 1 + public/vendor/fullcalendar/dist/lang/en-au.js | 1 + public/vendor/fullcalendar/dist/lang/en-ca.js | 1 + public/vendor/fullcalendar/dist/lang/en-gb.js | 1 + public/vendor/fullcalendar/dist/lang/en-ie.js | 1 + public/vendor/fullcalendar/dist/lang/en-nz.js | 1 + public/vendor/fullcalendar/dist/lang/es.js | 1 + public/vendor/fullcalendar/dist/lang/fa.js | 1 + public/vendor/fullcalendar/dist/lang/fi.js | 1 + public/vendor/fullcalendar/dist/lang/fr-ca.js | 1 + public/vendor/fullcalendar/dist/lang/fr-ch.js | 1 + public/vendor/fullcalendar/dist/lang/fr.js | 1 + public/vendor/fullcalendar/dist/lang/he.js | 1 + public/vendor/fullcalendar/dist/lang/hi.js | 1 + public/vendor/fullcalendar/dist/lang/hr.js | 1 + public/vendor/fullcalendar/dist/lang/hu.js | 1 + public/vendor/fullcalendar/dist/lang/id.js | 1 + public/vendor/fullcalendar/dist/lang/is.js | 1 + public/vendor/fullcalendar/dist/lang/it.js | 1 + public/vendor/fullcalendar/dist/lang/ja.js | 1 + public/vendor/fullcalendar/dist/lang/ko.js | 1 + public/vendor/fullcalendar/dist/lang/lt.js | 1 + public/vendor/fullcalendar/dist/lang/lv.js | 1 + public/vendor/fullcalendar/dist/lang/nb.js | 1 + public/vendor/fullcalendar/dist/lang/nl.js | 1 + public/vendor/fullcalendar/dist/lang/pl.js | 1 + public/vendor/fullcalendar/dist/lang/pt-br.js | 1 + public/vendor/fullcalendar/dist/lang/pt.js | 1 + public/vendor/fullcalendar/dist/lang/ro.js | 1 + public/vendor/fullcalendar/dist/lang/ru.js | 1 + public/vendor/fullcalendar/dist/lang/sk.js | 1 + public/vendor/fullcalendar/dist/lang/sl.js | 1 + .../vendor/fullcalendar/dist/lang/sr-cyrl.js | 1 + public/vendor/fullcalendar/dist/lang/sr.js | 1 + public/vendor/fullcalendar/dist/lang/sv.js | 1 + public/vendor/fullcalendar/dist/lang/th.js | 1 + public/vendor/fullcalendar/dist/lang/tr.js | 1 + public/vendor/fullcalendar/dist/lang/uk.js | 1 + public/vendor/fullcalendar/dist/lang/vi.js | 1 + public/vendor/fullcalendar/dist/lang/zh-cn.js | 1 + public/vendor/fullcalendar/dist/lang/zh-tw.js | 1 + public/vendor/jquery-backstretch/.bower.json | 30 + public/vendor/jquery-backstretch/.gitignore | 2 + public/vendor/jquery-backstretch/LICENSE-MIT | 22 + public/vendor/jquery-backstretch/README.md | 136 + public/vendor/jquery-backstretch/bower.json | 20 + .../jquery-backstretch/examples/basic.html | 63 + .../jquery-backstretch/examples/click.html | 67 + .../jquery-backstretch/examples/coffee.jpg | Bin 0 -> 422753 bytes .../jquery-backstretch/examples/dome.jpg | Bin 0 -> 691127 bytes .../examples/pot-holder.jpg | Bin 0 -> 835455 bytes .../examples/slideshow.html | 55 + public/vendor/jquery-backstretch/grunt.js | 61 + .../jquery-backstretch/jquery.backstretch.js | 377 + .../jquery.backstretch.min.js | 4 + .../jquery-backstretch/libs/jquery-loader.js | 14 + .../jquery-backstretch/libs/jquery/jquery.js | 9472 ++ .../jquery-backstretch/libs/qunit/qunit.css | 232 + .../jquery-backstretch/libs/qunit/qunit.js | 1659 + public/vendor/jquery-backstretch/package.json | 29 + .../src/jquery.backstretch.js | 381 + .../jquery-backstretch/test/backstretch.html | 31 + .../test/backstretch_test.js | 65 + .../vendor/jquery-backstretch/test/image1.jpg | Bin 0 -> 691127 bytes .../vendor/jquery-backstretch/test/image2.jpg | Bin 0 -> 422753 bytes public/vendor/jquery-minicolors/.bower.json | 34 + public/vendor/jquery-minicolors/bower.json | 25 + .../vendor/jquery-minicolors/component.json | 19 + public/vendor/jquery-minicolors/composer.json | 20 + .../vendor/jquery-minicolors/config.codekit | 947 + public/vendor/jquery-minicolors/index.html | 725 + .../jquery-minicolors/jquery.minicolors.css | 327 + .../jquery-minicolors/jquery.minicolors.js | 1135 + .../jquery.minicolors.min.js | 11 + .../jquery-minicolors/jquery.minicolors.png | Bin 0 -> 68627 bytes public/vendor/jquery-minicolors/package.json | 24 + public/vendor/jquery-minicolors/readme.md | 9 + .../jquery-minicolors/without-bootstrap.html | 185 + public/vendor/moment/.bower.json | 33 + public/vendor/moment/CHANGELOG.md | 535 + public/vendor/moment/LICENSE | 22 + public/vendor/moment/README.md | 58 + public/vendor/moment/bower.json | 22 + public/vendor/moment/locale/af.js | 73 + public/vendor/moment/locale/ar-ma.js | 60 + public/vendor/moment/locale/ar-sa.js | 104 + public/vendor/moment/locale/ar-tn.js | 58 + public/vendor/moment/locale/ar.js | 137 + public/vendor/moment/locale/az.js | 105 + public/vendor/moment/locale/be.js | 134 + public/vendor/moment/locale/bg.js | 90 + public/vendor/moment/locale/bn.js | 119 + public/vendor/moment/locale/bo.js | 119 + public/vendor/moment/locale/br.js | 108 + public/vendor/moment/locale/bs.js | 143 + public/vendor/moment/locale/ca.js | 81 + public/vendor/moment/locale/cs.js | 171 + public/vendor/moment/locale/cv.js | 63 + public/vendor/moment/locale/cy.js | 80 + public/vendor/moment/locale/da.js | 60 + public/vendor/moment/locale/de-at.js | 79 + public/vendor/moment/locale/de.js | 78 + public/vendor/moment/locale/dv.js | 99 + public/vendor/moment/locale/el.js | 98 + public/vendor/moment/locale/en-au.js | 66 + public/vendor/moment/locale/en-ca.js | 63 + public/vendor/moment/locale/en-gb.js | 67 + public/vendor/moment/locale/en-ie.js | 67 + public/vendor/moment/locale/en-nz.js | 66 + public/vendor/moment/locale/eo.js | 73 + public/vendor/moment/locale/es.js | 81 + public/vendor/moment/locale/et.js | 80 + public/vendor/moment/locale/eu.js | 66 + public/vendor/moment/locale/fa.js | 106 + public/vendor/moment/locale/fi.js | 107 + public/vendor/moment/locale/fo.js | 60 + public/vendor/moment/locale/fr-ca.js | 60 + public/vendor/moment/locale/fr-ch.js | 64 + public/vendor/moment/locale/fr.js | 64 + public/vendor/moment/locale/fy.js | 73 + public/vendor/moment/locale/gd.js | 76 + public/vendor/moment/locale/gl.js | 77 + public/vendor/moment/locale/he.js | 99 + public/vendor/moment/locale/hi.js | 124 + public/vendor/moment/locale/hr.js | 145 + public/vendor/moment/locale/hu.js | 109 + public/vendor/moment/locale/hy-am.js | 95 + public/vendor/moment/locale/id.js | 83 + public/vendor/moment/locale/is.js | 127 + public/vendor/moment/locale/it.js | 70 + public/vendor/moment/locale/ja.js | 76 + public/vendor/moment/locale/jv.js | 83 + public/vendor/moment/locale/ka.js | 89 + public/vendor/moment/locale/kk.js | 87 + public/vendor/moment/locale/km.js | 58 + public/vendor/moment/locale/ko.js | 68 + public/vendor/moment/locale/ky.js | 88 + public/vendor/moment/locale/lb.js | 136 + public/vendor/moment/locale/lo.js | 70 + public/vendor/moment/locale/lt.js | 116 + public/vendor/moment/locale/lv.js | 97 + public/vendor/moment/locale/me.js | 111 + public/vendor/moment/locale/mk.js | 90 + public/vendor/moment/locale/ml.js | 81 + public/vendor/moment/locale/mr.js | 159 + public/vendor/moment/locale/ms-my.js | 82 + public/vendor/moment/locale/ms.js | 82 + public/vendor/moment/locale/my.js | 93 + public/vendor/moment/locale/nb.js | 63 + public/vendor/moment/locale/ne.js | 123 + public/vendor/moment/locale/nl.js | 73 + public/vendor/moment/locale/nn.js | 60 + public/vendor/moment/locale/pa-in.js | 124 + public/vendor/moment/locale/pl.js | 105 + public/vendor/moment/locale/pt-br.js | 61 + public/vendor/moment/locale/pt.js | 65 + public/vendor/moment/locale/ro.js | 75 + public/vendor/moment/locale/ru.js | 175 + public/vendor/moment/locale/se.js | 61 + public/vendor/moment/locale/si.js | 71 + public/vendor/moment/locale/sk.js | 150 + public/vendor/moment/locale/sl.js | 162 + public/vendor/moment/locale/sq.js | 70 + public/vendor/moment/locale/sr-cyrl.js | 110 + public/vendor/moment/locale/sr.js | 110 + public/vendor/moment/locale/ss.js | 89 + public/vendor/moment/locale/sv.js | 69 + public/vendor/moment/locale/sw.js | 59 + public/vendor/moment/locale/ta.js | 129 + public/vendor/moment/locale/te.js | 89 + public/vendor/moment/locale/th.js | 67 + public/vendor/moment/locale/tl-ph.js | 62 + public/vendor/moment/locale/tlh.js | 120 + public/vendor/moment/locale/tr.js | 90 + public/vendor/moment/locale/tzl.js | 91 + public/vendor/moment/locale/tzm-latn.js | 58 + public/vendor/moment/locale/tzm.js | 58 + public/vendor/moment/locale/uk.js | 146 + public/vendor/moment/locale/uz.js | 58 + public/vendor/moment/locale/vi.js | 79 + public/vendor/moment/locale/x-pseudo.js | 68 + public/vendor/moment/locale/zh-cn.js | 127 + public/vendor/moment/locale/zh-tw.js | 101 + public/vendor/moment/min/locales.js | 8021 ++ public/vendor/moment/min/locales.min.js | 73 + .../vendor/moment/min/moment-with-locales.js | 12051 +++ .../moment/min/moment-with-locales.min.js | 76 + public/vendor/moment/min/moment.min.js | 7 + public/vendor/moment/min/tests.js | 72632 ++++++++++++++++ public/vendor/moment/moment.d.ts | 512 + public/vendor/moment/moment.js | 4040 + .../moment/src/lib/create/check-overflow.js | 34 + .../moment/src/lib/create/date-from-array.js | 21 + .../moment/src/lib/create/from-anything.js | 101 + .../moment/src/lib/create/from-array.js | 136 + .../moment/src/lib/create/from-object.js | 16 + .../src/lib/create/from-string-and-array.js | 50 + .../src/lib/create/from-string-and-format.js | 107 + .../moment/src/lib/create/from-string.js | 120 + public/vendor/moment/src/lib/create/local.js | 5 + .../moment/src/lib/create/parsing-flags.js | 24 + public/vendor/moment/src/lib/create/utc.js | 5 + public/vendor/moment/src/lib/create/valid.js | 42 + public/vendor/moment/src/lib/duration/abs.js | 18 + .../moment/src/lib/duration/add-subtract.js | 21 + public/vendor/moment/src/lib/duration/as.js | 55 + .../vendor/moment/src/lib/duration/bubble.js | 61 + .../moment/src/lib/duration/constructor.js | 41 + .../vendor/moment/src/lib/duration/create.js | 118 + .../moment/src/lib/duration/duration.js | 12 + public/vendor/moment/src/lib/duration/get.js | 25 + .../moment/src/lib/duration/humanize.js | 64 + .../moment/src/lib/duration/iso-string.js | 52 + .../moment/src/lib/duration/prototype.js | 48 + public/vendor/moment/src/lib/format/format.js | 91 + .../vendor/moment/src/lib/locale/calendar.js | 15 + .../moment/src/lib/locale/constructor.js | 5 + public/vendor/moment/src/lib/locale/en.js | 15 + .../vendor/moment/src/lib/locale/formats.js | 23 + .../vendor/moment/src/lib/locale/invalid.js | 5 + public/vendor/moment/src/lib/locale/lists.js | 92 + public/vendor/moment/src/lib/locale/locale.js | 39 + .../vendor/moment/src/lib/locale/locales.js | 164 + .../vendor/moment/src/lib/locale/ordinal.js | 7 + .../moment/src/lib/locale/pre-post-format.js | 3 + .../vendor/moment/src/lib/locale/prototype.js | 87 + .../vendor/moment/src/lib/locale/relative.js | 29 + public/vendor/moment/src/lib/locale/set.js | 38 + .../moment/src/lib/moment/add-subtract.js | 54 + .../vendor/moment/src/lib/moment/calendar.js | 21 + public/vendor/moment/src/lib/moment/clone.js | 5 + .../vendor/moment/src/lib/moment/compare.js | 59 + .../moment/src/lib/moment/constructor.js | 74 + .../moment/src/lib/moment/creation-data.js | 9 + public/vendor/moment/src/lib/moment/diff.js | 62 + public/vendor/moment/src/lib/moment/format.js | 32 + public/vendor/moment/src/lib/moment/from.js | 17 + .../vendor/moment/src/lib/moment/get-set.js | 43 + public/vendor/moment/src/lib/moment/locale.js | 34 + .../vendor/moment/src/lib/moment/min-max.js | 63 + public/vendor/moment/src/lib/moment/moment.js | 28 + public/vendor/moment/src/lib/moment/now.js | 3 + .../vendor/moment/src/lib/moment/prototype.js | 149 + .../moment/src/lib/moment/start-end-of.js | 59 + .../vendor/moment/src/lib/moment/to-type.js | 34 + public/vendor/moment/src/lib/moment/to.js | 17 + public/vendor/moment/src/lib/moment/valid.js | 15 + public/vendor/moment/src/lib/parse/regex.js | 54 + public/vendor/moment/src/lib/parse/token.js | 32 + public/vendor/moment/src/lib/units/aliases.js | 29 + .../vendor/moment/src/lib/units/constants.js | 9 + .../moment/src/lib/units/day-of-month.js | 32 + .../moment/src/lib/units/day-of-week.js | 331 + .../moment/src/lib/units/day-of-year.js | 32 + public/vendor/moment/src/lib/units/hour.js | 134 + .../moment/src/lib/units/millisecond.js | 64 + public/vendor/moment/src/lib/units/minute.js | 24 + public/vendor/moment/src/lib/units/month.js | 261 + public/vendor/moment/src/lib/units/offset.js | 219 + public/vendor/moment/src/lib/units/quarter.js | 27 + public/vendor/moment/src/lib/units/second.js | 24 + .../vendor/moment/src/lib/units/timestamp.js | 20 + .../vendor/moment/src/lib/units/timezone.js | 16 + public/vendor/moment/src/lib/units/units.js | 20 + .../src/lib/units/week-calendar-utils.js | 65 + .../vendor/moment/src/lib/units/week-year.js | 100 + public/vendor/moment/src/lib/units/week.js | 61 + public/vendor/moment/src/lib/units/year.js | 70 + .../vendor/moment/src/lib/utils/abs-ceil.js | 7 + .../vendor/moment/src/lib/utils/abs-floor.js | 7 + .../vendor/moment/src/lib/utils/abs-round.js | 7 + .../moment/src/lib/utils/compare-arrays.js | 16 + .../vendor/moment/src/lib/utils/defaults.js | 10 + .../vendor/moment/src/lib/utils/deprecate.js | 40 + public/vendor/moment/src/lib/utils/extend.js | 19 + .../moment/src/lib/utils/has-own-prop.js | 3 + public/vendor/moment/src/lib/utils/hooks.js | 13 + .../vendor/moment/src/lib/utils/index-of.js | 18 + .../vendor/moment/src/lib/utils/is-array.js | 3 + public/vendor/moment/src/lib/utils/is-date.js | 3 + .../moment/src/lib/utils/is-function.js | 3 + .../vendor/moment/src/lib/utils/is-object.js | 3 + .../moment/src/lib/utils/is-undefined.js | 3 + public/vendor/moment/src/lib/utils/keys.js | 19 + public/vendor/moment/src/lib/utils/map.js | 7 + public/vendor/moment/src/lib/utils/some.js | 19 + public/vendor/moment/src/lib/utils/to-int.js | 12 + .../vendor/moment/src/lib/utils/zero-fill.js | 7 + public/vendor/moment/src/locale/af.js | 63 + public/vendor/moment/src/locale/ar-ma.js | 51 + public/vendor/moment/src/locale/ar-sa.js | 95 + public/vendor/moment/src/locale/ar-tn.js | 49 + public/vendor/moment/src/locale/ar.js | 128 + public/vendor/moment/src/locale/az.js | 96 + public/vendor/moment/src/locale/be.js | 125 + public/vendor/moment/src/locale/bg.js | 81 + public/vendor/moment/src/locale/bn.js | 110 + public/vendor/moment/src/locale/bo.js | 110 + public/vendor/moment/src/locale/br.js | 99 + public/vendor/moment/src/locale/bs.js | 134 + public/vendor/moment/src/locale/ca.js | 72 + public/vendor/moment/src/locale/cs.js | 162 + public/vendor/moment/src/locale/cv.js | 53 + public/vendor/moment/src/locale/cy.js | 71 + public/vendor/moment/src/locale/da.js | 51 + public/vendor/moment/src/locale/de-at.js | 69 + public/vendor/moment/src/locale/de.js | 68 + public/vendor/moment/src/locale/dv.js | 89 + public/vendor/moment/src/locale/el.js | 86 + public/vendor/moment/src/locale/en-au.js | 57 + public/vendor/moment/src/locale/en-ca.js | 53 + public/vendor/moment/src/locale/en-gb.js | 58 + public/vendor/moment/src/locale/en-ie.js | 58 + public/vendor/moment/src/locale/en-nz.js | 56 + public/vendor/moment/src/locale/eo.js | 64 + public/vendor/moment/src/locale/es.js | 72 + public/vendor/moment/src/locale/et.js | 71 + public/vendor/moment/src/locale/eu.js | 57 + public/vendor/moment/src/locale/fa.js | 97 + public/vendor/moment/src/locale/fi.js | 98 + public/vendor/moment/src/locale/fo.js | 51 + public/vendor/moment/src/locale/fr-ca.js | 51 + public/vendor/moment/src/locale/fr-ch.js | 55 + public/vendor/moment/src/locale/fr.js | 55 + public/vendor/moment/src/locale/fy.js | 64 + public/vendor/moment/src/locale/gd.js | 67 + public/vendor/moment/src/locale/gl.js | 68 + public/vendor/moment/src/locale/he.js | 90 + public/vendor/moment/src/locale/hi.js | 115 + public/vendor/moment/src/locale/hr.js | 136 + public/vendor/moment/src/locale/hu.js | 100 + public/vendor/moment/src/locale/hy-am.js | 86 + public/vendor/moment/src/locale/id.js | 74 + public/vendor/moment/src/locale/is.js | 118 + public/vendor/moment/src/locale/it.js | 61 + public/vendor/moment/src/locale/ja.js | 67 + public/vendor/moment/src/locale/jv.js | 73 + public/vendor/moment/src/locale/ka.js | 80 + public/vendor/moment/src/locale/kk.js | 77 + public/vendor/moment/src/locale/km.js | 49 + public/vendor/moment/src/locale/ko.js | 59 + public/vendor/moment/src/locale/ky.js | 78 + public/vendor/moment/src/locale/lb.js | 127 + public/vendor/moment/src/locale/lo.js | 61 + public/vendor/moment/src/locale/lt.js | 107 + public/vendor/moment/src/locale/lv.js | 88 + public/vendor/moment/src/locale/me.js | 101 + public/vendor/moment/src/locale/mk.js | 81 + public/vendor/moment/src/locale/ml.js | 72 + public/vendor/moment/src/locale/mr.js | 150 + public/vendor/moment/src/locale/ms-my.js | 73 + public/vendor/moment/src/locale/ms.js | 73 + public/vendor/moment/src/locale/my.js | 84 + public/vendor/moment/src/locale/nb.js | 54 + public/vendor/moment/src/locale/ne.js | 114 + public/vendor/moment/src/locale/nl.js | 64 + public/vendor/moment/src/locale/nn.js | 51 + public/vendor/moment/src/locale/pa-in.js | 115 + public/vendor/moment/src/locale/pl.js | 95 + public/vendor/moment/src/locale/pt-br.js | 52 + public/vendor/moment/src/locale/pt.js | 56 + public/vendor/moment/src/locale/ro.js | 66 + public/vendor/moment/src/locale/ru.js | 165 + public/vendor/moment/src/locale/se.js | 51 + public/vendor/moment/src/locale/si.js | 61 + public/vendor/moment/src/locale/sk.js | 141 + public/vendor/moment/src/locale/sl.js | 152 + public/vendor/moment/src/locale/sq.js | 61 + public/vendor/moment/src/locale/sr-cyrl.js | 101 + public/vendor/moment/src/locale/sr.js | 101 + public/vendor/moment/src/locale/ss.js | 80 + public/vendor/moment/src/locale/sv.js | 60 + public/vendor/moment/src/locale/sw.js | 50 + public/vendor/moment/src/locale/ta.js | 120 + public/vendor/moment/src/locale/te.js | 79 + public/vendor/moment/src/locale/th.js | 58 + public/vendor/moment/src/locale/tl-ph.js | 53 + public/vendor/moment/src/locale/tlh.js | 110 + public/vendor/moment/src/locale/tr.js | 81 + public/vendor/moment/src/locale/tzl.js | 82 + public/vendor/moment/src/locale/tzm-latn.js | 49 + public/vendor/moment/src/locale/tzm.js | 49 + public/vendor/moment/src/locale/uk.js | 137 + public/vendor/moment/src/locale/uz.js | 49 + public/vendor/moment/src/locale/vi.js | 70 + public/vendor/moment/src/locale/x-pseudo.js | 58 + public/vendor/moment/src/locale/zh-cn.js | 118 + public/vendor/moment/src/locale/zh-tw.js | 91 + public/vendor/moment/src/moment.js | 75 + public/vendor/moment/templates/amd-named.js | 7 + public/vendor/moment/templates/amd.js | 7 + public/vendor/moment/templates/default.js | 5 + public/vendor/moment/templates/globals.js | 5 + .../vendor/moment/templates/locale-header.js | 6 + public/vendor/moment/templates/test-header.js | 6 + 418 files changed, 154060 insertions(+) create mode 100644 public/vendor/fullcalendar/.bower.json create mode 100644 public/vendor/fullcalendar/CHANGELOG.md create mode 100644 public/vendor/fullcalendar/CONTRIBUTING.md create mode 100644 public/vendor/fullcalendar/LICENSE.txt create mode 100644 public/vendor/fullcalendar/README.md create mode 100644 public/vendor/fullcalendar/bower.json create mode 100644 public/vendor/fullcalendar/dist/fullcalendar.css create mode 100644 public/vendor/fullcalendar/dist/fullcalendar.js create mode 100644 public/vendor/fullcalendar/dist/fullcalendar.min.css create mode 100644 public/vendor/fullcalendar/dist/fullcalendar.min.js create mode 100644 public/vendor/fullcalendar/dist/fullcalendar.print.css create mode 100644 public/vendor/fullcalendar/dist/gcal.js create mode 100644 public/vendor/fullcalendar/dist/lang-all.js create mode 100644 public/vendor/fullcalendar/dist/lang/ar-ma.js create mode 100644 public/vendor/fullcalendar/dist/lang/ar-sa.js create mode 100644 public/vendor/fullcalendar/dist/lang/ar-tn.js create mode 100644 public/vendor/fullcalendar/dist/lang/ar.js create mode 100644 public/vendor/fullcalendar/dist/lang/bg.js create mode 100644 public/vendor/fullcalendar/dist/lang/ca.js create mode 100644 public/vendor/fullcalendar/dist/lang/cs.js create mode 100644 public/vendor/fullcalendar/dist/lang/da.js create mode 100644 public/vendor/fullcalendar/dist/lang/de-at.js create mode 100644 public/vendor/fullcalendar/dist/lang/de.js create mode 100644 public/vendor/fullcalendar/dist/lang/el.js create mode 100644 public/vendor/fullcalendar/dist/lang/en-au.js create mode 100644 public/vendor/fullcalendar/dist/lang/en-ca.js create mode 100644 public/vendor/fullcalendar/dist/lang/en-gb.js create mode 100644 public/vendor/fullcalendar/dist/lang/en-ie.js create mode 100644 public/vendor/fullcalendar/dist/lang/en-nz.js create mode 100644 public/vendor/fullcalendar/dist/lang/es.js create mode 100644 public/vendor/fullcalendar/dist/lang/fa.js create mode 100644 public/vendor/fullcalendar/dist/lang/fi.js create mode 100644 public/vendor/fullcalendar/dist/lang/fr-ca.js create mode 100644 public/vendor/fullcalendar/dist/lang/fr-ch.js create mode 100644 public/vendor/fullcalendar/dist/lang/fr.js create mode 100644 public/vendor/fullcalendar/dist/lang/he.js create mode 100644 public/vendor/fullcalendar/dist/lang/hi.js create mode 100644 public/vendor/fullcalendar/dist/lang/hr.js create mode 100644 public/vendor/fullcalendar/dist/lang/hu.js create mode 100644 public/vendor/fullcalendar/dist/lang/id.js create mode 100644 public/vendor/fullcalendar/dist/lang/is.js create mode 100644 public/vendor/fullcalendar/dist/lang/it.js create mode 100644 public/vendor/fullcalendar/dist/lang/ja.js create mode 100644 public/vendor/fullcalendar/dist/lang/ko.js create mode 100644 public/vendor/fullcalendar/dist/lang/lt.js create mode 100644 public/vendor/fullcalendar/dist/lang/lv.js create mode 100644 public/vendor/fullcalendar/dist/lang/nb.js create mode 100644 public/vendor/fullcalendar/dist/lang/nl.js create mode 100644 public/vendor/fullcalendar/dist/lang/pl.js create mode 100644 public/vendor/fullcalendar/dist/lang/pt-br.js create mode 100644 public/vendor/fullcalendar/dist/lang/pt.js create mode 100644 public/vendor/fullcalendar/dist/lang/ro.js create mode 100644 public/vendor/fullcalendar/dist/lang/ru.js create mode 100644 public/vendor/fullcalendar/dist/lang/sk.js create mode 100644 public/vendor/fullcalendar/dist/lang/sl.js create mode 100644 public/vendor/fullcalendar/dist/lang/sr-cyrl.js create mode 100644 public/vendor/fullcalendar/dist/lang/sr.js create mode 100644 public/vendor/fullcalendar/dist/lang/sv.js create mode 100644 public/vendor/fullcalendar/dist/lang/th.js create mode 100644 public/vendor/fullcalendar/dist/lang/tr.js create mode 100644 public/vendor/fullcalendar/dist/lang/uk.js create mode 100644 public/vendor/fullcalendar/dist/lang/vi.js create mode 100644 public/vendor/fullcalendar/dist/lang/zh-cn.js create mode 100644 public/vendor/fullcalendar/dist/lang/zh-tw.js create mode 100644 public/vendor/jquery-backstretch/.bower.json create mode 100644 public/vendor/jquery-backstretch/.gitignore create mode 100644 public/vendor/jquery-backstretch/LICENSE-MIT create mode 100644 public/vendor/jquery-backstretch/README.md create mode 100644 public/vendor/jquery-backstretch/bower.json create mode 100755 public/vendor/jquery-backstretch/examples/basic.html create mode 100755 public/vendor/jquery-backstretch/examples/click.html create mode 100755 public/vendor/jquery-backstretch/examples/coffee.jpg create mode 100644 public/vendor/jquery-backstretch/examples/dome.jpg create mode 100755 public/vendor/jquery-backstretch/examples/pot-holder.jpg create mode 100755 public/vendor/jquery-backstretch/examples/slideshow.html create mode 100644 public/vendor/jquery-backstretch/grunt.js create mode 100644 public/vendor/jquery-backstretch/jquery.backstretch.js create mode 100644 public/vendor/jquery-backstretch/jquery.backstretch.min.js create mode 100644 public/vendor/jquery-backstretch/libs/jquery-loader.js create mode 100644 public/vendor/jquery-backstretch/libs/jquery/jquery.js create mode 100644 public/vendor/jquery-backstretch/libs/qunit/qunit.css create mode 100644 public/vendor/jquery-backstretch/libs/qunit/qunit.js create mode 100644 public/vendor/jquery-backstretch/package.json create mode 100644 public/vendor/jquery-backstretch/src/jquery.backstretch.js create mode 100644 public/vendor/jquery-backstretch/test/backstretch.html create mode 100644 public/vendor/jquery-backstretch/test/backstretch_test.js create mode 100644 public/vendor/jquery-backstretch/test/image1.jpg create mode 100755 public/vendor/jquery-backstretch/test/image2.jpg create mode 100644 public/vendor/jquery-minicolors/.bower.json create mode 100644 public/vendor/jquery-minicolors/bower.json create mode 100644 public/vendor/jquery-minicolors/component.json create mode 100644 public/vendor/jquery-minicolors/composer.json create mode 100644 public/vendor/jquery-minicolors/config.codekit create mode 100644 public/vendor/jquery-minicolors/index.html create mode 100644 public/vendor/jquery-minicolors/jquery.minicolors.css create mode 100644 public/vendor/jquery-minicolors/jquery.minicolors.js create mode 100644 public/vendor/jquery-minicolors/jquery.minicolors.min.js create mode 100644 public/vendor/jquery-minicolors/jquery.minicolors.png create mode 100644 public/vendor/jquery-minicolors/package.json create mode 100755 public/vendor/jquery-minicolors/readme.md create mode 100644 public/vendor/jquery-minicolors/without-bootstrap.html create mode 100644 public/vendor/moment/.bower.json create mode 100644 public/vendor/moment/CHANGELOG.md create mode 100644 public/vendor/moment/LICENSE create mode 100644 public/vendor/moment/README.md create mode 100644 public/vendor/moment/bower.json create mode 100644 public/vendor/moment/locale/af.js create mode 100644 public/vendor/moment/locale/ar-ma.js create mode 100644 public/vendor/moment/locale/ar-sa.js create mode 100644 public/vendor/moment/locale/ar-tn.js create mode 100644 public/vendor/moment/locale/ar.js create mode 100644 public/vendor/moment/locale/az.js create mode 100644 public/vendor/moment/locale/be.js create mode 100644 public/vendor/moment/locale/bg.js create mode 100644 public/vendor/moment/locale/bn.js create mode 100644 public/vendor/moment/locale/bo.js create mode 100644 public/vendor/moment/locale/br.js create mode 100644 public/vendor/moment/locale/bs.js create mode 100644 public/vendor/moment/locale/ca.js create mode 100644 public/vendor/moment/locale/cs.js create mode 100644 public/vendor/moment/locale/cv.js create mode 100644 public/vendor/moment/locale/cy.js create mode 100644 public/vendor/moment/locale/da.js create mode 100644 public/vendor/moment/locale/de-at.js create mode 100644 public/vendor/moment/locale/de.js create mode 100644 public/vendor/moment/locale/dv.js create mode 100644 public/vendor/moment/locale/el.js create mode 100644 public/vendor/moment/locale/en-au.js create mode 100644 public/vendor/moment/locale/en-ca.js create mode 100644 public/vendor/moment/locale/en-gb.js create mode 100644 public/vendor/moment/locale/en-ie.js create mode 100644 public/vendor/moment/locale/en-nz.js create mode 100644 public/vendor/moment/locale/eo.js create mode 100644 public/vendor/moment/locale/es.js create mode 100644 public/vendor/moment/locale/et.js create mode 100644 public/vendor/moment/locale/eu.js create mode 100644 public/vendor/moment/locale/fa.js create mode 100644 public/vendor/moment/locale/fi.js create mode 100644 public/vendor/moment/locale/fo.js create mode 100644 public/vendor/moment/locale/fr-ca.js create mode 100644 public/vendor/moment/locale/fr-ch.js create mode 100644 public/vendor/moment/locale/fr.js create mode 100644 public/vendor/moment/locale/fy.js create mode 100644 public/vendor/moment/locale/gd.js create mode 100644 public/vendor/moment/locale/gl.js create mode 100644 public/vendor/moment/locale/he.js create mode 100644 public/vendor/moment/locale/hi.js create mode 100644 public/vendor/moment/locale/hr.js create mode 100644 public/vendor/moment/locale/hu.js create mode 100644 public/vendor/moment/locale/hy-am.js create mode 100644 public/vendor/moment/locale/id.js create mode 100644 public/vendor/moment/locale/is.js create mode 100644 public/vendor/moment/locale/it.js create mode 100644 public/vendor/moment/locale/ja.js create mode 100644 public/vendor/moment/locale/jv.js create mode 100644 public/vendor/moment/locale/ka.js create mode 100644 public/vendor/moment/locale/kk.js create mode 100644 public/vendor/moment/locale/km.js create mode 100644 public/vendor/moment/locale/ko.js create mode 100644 public/vendor/moment/locale/ky.js create mode 100644 public/vendor/moment/locale/lb.js create mode 100644 public/vendor/moment/locale/lo.js create mode 100644 public/vendor/moment/locale/lt.js create mode 100644 public/vendor/moment/locale/lv.js create mode 100644 public/vendor/moment/locale/me.js create mode 100644 public/vendor/moment/locale/mk.js create mode 100644 public/vendor/moment/locale/ml.js create mode 100644 public/vendor/moment/locale/mr.js create mode 100644 public/vendor/moment/locale/ms-my.js create mode 100644 public/vendor/moment/locale/ms.js create mode 100644 public/vendor/moment/locale/my.js create mode 100644 public/vendor/moment/locale/nb.js create mode 100644 public/vendor/moment/locale/ne.js create mode 100644 public/vendor/moment/locale/nl.js create mode 100644 public/vendor/moment/locale/nn.js create mode 100644 public/vendor/moment/locale/pa-in.js create mode 100644 public/vendor/moment/locale/pl.js create mode 100644 public/vendor/moment/locale/pt-br.js create mode 100644 public/vendor/moment/locale/pt.js create mode 100644 public/vendor/moment/locale/ro.js create mode 100644 public/vendor/moment/locale/ru.js create mode 100644 public/vendor/moment/locale/se.js create mode 100644 public/vendor/moment/locale/si.js create mode 100644 public/vendor/moment/locale/sk.js create mode 100644 public/vendor/moment/locale/sl.js create mode 100644 public/vendor/moment/locale/sq.js create mode 100644 public/vendor/moment/locale/sr-cyrl.js create mode 100644 public/vendor/moment/locale/sr.js create mode 100644 public/vendor/moment/locale/ss.js create mode 100644 public/vendor/moment/locale/sv.js create mode 100644 public/vendor/moment/locale/sw.js create mode 100644 public/vendor/moment/locale/ta.js create mode 100644 public/vendor/moment/locale/te.js create mode 100644 public/vendor/moment/locale/th.js create mode 100644 public/vendor/moment/locale/tl-ph.js create mode 100644 public/vendor/moment/locale/tlh.js create mode 100644 public/vendor/moment/locale/tr.js create mode 100644 public/vendor/moment/locale/tzl.js create mode 100644 public/vendor/moment/locale/tzm-latn.js create mode 100644 public/vendor/moment/locale/tzm.js create mode 100644 public/vendor/moment/locale/uk.js create mode 100644 public/vendor/moment/locale/uz.js create mode 100644 public/vendor/moment/locale/vi.js create mode 100644 public/vendor/moment/locale/x-pseudo.js create mode 100644 public/vendor/moment/locale/zh-cn.js create mode 100644 public/vendor/moment/locale/zh-tw.js create mode 100644 public/vendor/moment/min/locales.js create mode 100644 public/vendor/moment/min/locales.min.js create mode 100644 public/vendor/moment/min/moment-with-locales.js create mode 100644 public/vendor/moment/min/moment-with-locales.min.js create mode 100644 public/vendor/moment/min/moment.min.js create mode 100644 public/vendor/moment/min/tests.js create mode 100644 public/vendor/moment/moment.d.ts create mode 100644 public/vendor/moment/moment.js create mode 100644 public/vendor/moment/src/lib/create/check-overflow.js create mode 100644 public/vendor/moment/src/lib/create/date-from-array.js create mode 100644 public/vendor/moment/src/lib/create/from-anything.js create mode 100644 public/vendor/moment/src/lib/create/from-array.js create mode 100644 public/vendor/moment/src/lib/create/from-object.js create mode 100644 public/vendor/moment/src/lib/create/from-string-and-array.js create mode 100644 public/vendor/moment/src/lib/create/from-string-and-format.js create mode 100644 public/vendor/moment/src/lib/create/from-string.js create mode 100644 public/vendor/moment/src/lib/create/local.js create mode 100644 public/vendor/moment/src/lib/create/parsing-flags.js create mode 100644 public/vendor/moment/src/lib/create/utc.js create mode 100644 public/vendor/moment/src/lib/create/valid.js create mode 100644 public/vendor/moment/src/lib/duration/abs.js create mode 100644 public/vendor/moment/src/lib/duration/add-subtract.js create mode 100644 public/vendor/moment/src/lib/duration/as.js create mode 100644 public/vendor/moment/src/lib/duration/bubble.js create mode 100644 public/vendor/moment/src/lib/duration/constructor.js create mode 100644 public/vendor/moment/src/lib/duration/create.js create mode 100644 public/vendor/moment/src/lib/duration/duration.js create mode 100644 public/vendor/moment/src/lib/duration/get.js create mode 100644 public/vendor/moment/src/lib/duration/humanize.js create mode 100644 public/vendor/moment/src/lib/duration/iso-string.js create mode 100644 public/vendor/moment/src/lib/duration/prototype.js create mode 100644 public/vendor/moment/src/lib/format/format.js create mode 100644 public/vendor/moment/src/lib/locale/calendar.js create mode 100644 public/vendor/moment/src/lib/locale/constructor.js create mode 100644 public/vendor/moment/src/lib/locale/en.js create mode 100644 public/vendor/moment/src/lib/locale/formats.js create mode 100644 public/vendor/moment/src/lib/locale/invalid.js create mode 100644 public/vendor/moment/src/lib/locale/lists.js create mode 100644 public/vendor/moment/src/lib/locale/locale.js create mode 100644 public/vendor/moment/src/lib/locale/locales.js create mode 100644 public/vendor/moment/src/lib/locale/ordinal.js create mode 100644 public/vendor/moment/src/lib/locale/pre-post-format.js create mode 100644 public/vendor/moment/src/lib/locale/prototype.js create mode 100644 public/vendor/moment/src/lib/locale/relative.js create mode 100644 public/vendor/moment/src/lib/locale/set.js create mode 100644 public/vendor/moment/src/lib/moment/add-subtract.js create mode 100644 public/vendor/moment/src/lib/moment/calendar.js create mode 100644 public/vendor/moment/src/lib/moment/clone.js create mode 100644 public/vendor/moment/src/lib/moment/compare.js create mode 100644 public/vendor/moment/src/lib/moment/constructor.js create mode 100644 public/vendor/moment/src/lib/moment/creation-data.js create mode 100644 public/vendor/moment/src/lib/moment/diff.js create mode 100644 public/vendor/moment/src/lib/moment/format.js create mode 100644 public/vendor/moment/src/lib/moment/from.js create mode 100644 public/vendor/moment/src/lib/moment/get-set.js create mode 100644 public/vendor/moment/src/lib/moment/locale.js create mode 100644 public/vendor/moment/src/lib/moment/min-max.js create mode 100644 public/vendor/moment/src/lib/moment/moment.js create mode 100644 public/vendor/moment/src/lib/moment/now.js create mode 100644 public/vendor/moment/src/lib/moment/prototype.js create mode 100644 public/vendor/moment/src/lib/moment/start-end-of.js create mode 100644 public/vendor/moment/src/lib/moment/to-type.js create mode 100644 public/vendor/moment/src/lib/moment/to.js create mode 100644 public/vendor/moment/src/lib/moment/valid.js create mode 100644 public/vendor/moment/src/lib/parse/regex.js create mode 100644 public/vendor/moment/src/lib/parse/token.js create mode 100644 public/vendor/moment/src/lib/units/aliases.js create mode 100644 public/vendor/moment/src/lib/units/constants.js create mode 100644 public/vendor/moment/src/lib/units/day-of-month.js create mode 100644 public/vendor/moment/src/lib/units/day-of-week.js create mode 100644 public/vendor/moment/src/lib/units/day-of-year.js create mode 100644 public/vendor/moment/src/lib/units/hour.js create mode 100644 public/vendor/moment/src/lib/units/millisecond.js create mode 100644 public/vendor/moment/src/lib/units/minute.js create mode 100644 public/vendor/moment/src/lib/units/month.js create mode 100644 public/vendor/moment/src/lib/units/offset.js create mode 100644 public/vendor/moment/src/lib/units/quarter.js create mode 100644 public/vendor/moment/src/lib/units/second.js create mode 100644 public/vendor/moment/src/lib/units/timestamp.js create mode 100644 public/vendor/moment/src/lib/units/timezone.js create mode 100644 public/vendor/moment/src/lib/units/units.js create mode 100644 public/vendor/moment/src/lib/units/week-calendar-utils.js create mode 100644 public/vendor/moment/src/lib/units/week-year.js create mode 100644 public/vendor/moment/src/lib/units/week.js create mode 100644 public/vendor/moment/src/lib/units/year.js create mode 100644 public/vendor/moment/src/lib/utils/abs-ceil.js create mode 100644 public/vendor/moment/src/lib/utils/abs-floor.js create mode 100644 public/vendor/moment/src/lib/utils/abs-round.js create mode 100644 public/vendor/moment/src/lib/utils/compare-arrays.js create mode 100644 public/vendor/moment/src/lib/utils/defaults.js create mode 100644 public/vendor/moment/src/lib/utils/deprecate.js create mode 100644 public/vendor/moment/src/lib/utils/extend.js create mode 100644 public/vendor/moment/src/lib/utils/has-own-prop.js create mode 100644 public/vendor/moment/src/lib/utils/hooks.js create mode 100644 public/vendor/moment/src/lib/utils/index-of.js create mode 100644 public/vendor/moment/src/lib/utils/is-array.js create mode 100644 public/vendor/moment/src/lib/utils/is-date.js create mode 100644 public/vendor/moment/src/lib/utils/is-function.js create mode 100644 public/vendor/moment/src/lib/utils/is-object.js create mode 100644 public/vendor/moment/src/lib/utils/is-undefined.js create mode 100644 public/vendor/moment/src/lib/utils/keys.js create mode 100644 public/vendor/moment/src/lib/utils/map.js create mode 100644 public/vendor/moment/src/lib/utils/some.js create mode 100644 public/vendor/moment/src/lib/utils/to-int.js create mode 100644 public/vendor/moment/src/lib/utils/zero-fill.js create mode 100644 public/vendor/moment/src/locale/af.js create mode 100644 public/vendor/moment/src/locale/ar-ma.js create mode 100644 public/vendor/moment/src/locale/ar-sa.js create mode 100644 public/vendor/moment/src/locale/ar-tn.js create mode 100644 public/vendor/moment/src/locale/ar.js create mode 100644 public/vendor/moment/src/locale/az.js create mode 100644 public/vendor/moment/src/locale/be.js create mode 100644 public/vendor/moment/src/locale/bg.js create mode 100644 public/vendor/moment/src/locale/bn.js create mode 100644 public/vendor/moment/src/locale/bo.js create mode 100644 public/vendor/moment/src/locale/br.js create mode 100644 public/vendor/moment/src/locale/bs.js create mode 100644 public/vendor/moment/src/locale/ca.js create mode 100644 public/vendor/moment/src/locale/cs.js create mode 100644 public/vendor/moment/src/locale/cv.js create mode 100644 public/vendor/moment/src/locale/cy.js create mode 100644 public/vendor/moment/src/locale/da.js create mode 100644 public/vendor/moment/src/locale/de-at.js create mode 100644 public/vendor/moment/src/locale/de.js create mode 100644 public/vendor/moment/src/locale/dv.js create mode 100644 public/vendor/moment/src/locale/el.js create mode 100644 public/vendor/moment/src/locale/en-au.js create mode 100644 public/vendor/moment/src/locale/en-ca.js create mode 100644 public/vendor/moment/src/locale/en-gb.js create mode 100644 public/vendor/moment/src/locale/en-ie.js create mode 100644 public/vendor/moment/src/locale/en-nz.js create mode 100644 public/vendor/moment/src/locale/eo.js create mode 100644 public/vendor/moment/src/locale/es.js create mode 100644 public/vendor/moment/src/locale/et.js create mode 100644 public/vendor/moment/src/locale/eu.js create mode 100644 public/vendor/moment/src/locale/fa.js create mode 100644 public/vendor/moment/src/locale/fi.js create mode 100644 public/vendor/moment/src/locale/fo.js create mode 100644 public/vendor/moment/src/locale/fr-ca.js create mode 100644 public/vendor/moment/src/locale/fr-ch.js create mode 100644 public/vendor/moment/src/locale/fr.js create mode 100644 public/vendor/moment/src/locale/fy.js create mode 100644 public/vendor/moment/src/locale/gd.js create mode 100644 public/vendor/moment/src/locale/gl.js create mode 100644 public/vendor/moment/src/locale/he.js create mode 100644 public/vendor/moment/src/locale/hi.js create mode 100644 public/vendor/moment/src/locale/hr.js create mode 100644 public/vendor/moment/src/locale/hu.js create mode 100644 public/vendor/moment/src/locale/hy-am.js create mode 100644 public/vendor/moment/src/locale/id.js create mode 100644 public/vendor/moment/src/locale/is.js create mode 100644 public/vendor/moment/src/locale/it.js create mode 100644 public/vendor/moment/src/locale/ja.js create mode 100644 public/vendor/moment/src/locale/jv.js create mode 100644 public/vendor/moment/src/locale/ka.js create mode 100644 public/vendor/moment/src/locale/kk.js create mode 100644 public/vendor/moment/src/locale/km.js create mode 100644 public/vendor/moment/src/locale/ko.js create mode 100644 public/vendor/moment/src/locale/ky.js create mode 100644 public/vendor/moment/src/locale/lb.js create mode 100644 public/vendor/moment/src/locale/lo.js create mode 100644 public/vendor/moment/src/locale/lt.js create mode 100644 public/vendor/moment/src/locale/lv.js create mode 100644 public/vendor/moment/src/locale/me.js create mode 100644 public/vendor/moment/src/locale/mk.js create mode 100644 public/vendor/moment/src/locale/ml.js create mode 100644 public/vendor/moment/src/locale/mr.js create mode 100644 public/vendor/moment/src/locale/ms-my.js create mode 100644 public/vendor/moment/src/locale/ms.js create mode 100644 public/vendor/moment/src/locale/my.js create mode 100644 public/vendor/moment/src/locale/nb.js create mode 100644 public/vendor/moment/src/locale/ne.js create mode 100644 public/vendor/moment/src/locale/nl.js create mode 100644 public/vendor/moment/src/locale/nn.js create mode 100644 public/vendor/moment/src/locale/pa-in.js create mode 100644 public/vendor/moment/src/locale/pl.js create mode 100644 public/vendor/moment/src/locale/pt-br.js create mode 100644 public/vendor/moment/src/locale/pt.js create mode 100644 public/vendor/moment/src/locale/ro.js create mode 100644 public/vendor/moment/src/locale/ru.js create mode 100644 public/vendor/moment/src/locale/se.js create mode 100644 public/vendor/moment/src/locale/si.js create mode 100644 public/vendor/moment/src/locale/sk.js create mode 100644 public/vendor/moment/src/locale/sl.js create mode 100644 public/vendor/moment/src/locale/sq.js create mode 100644 public/vendor/moment/src/locale/sr-cyrl.js create mode 100644 public/vendor/moment/src/locale/sr.js create mode 100644 public/vendor/moment/src/locale/ss.js create mode 100644 public/vendor/moment/src/locale/sv.js create mode 100644 public/vendor/moment/src/locale/sw.js create mode 100644 public/vendor/moment/src/locale/ta.js create mode 100644 public/vendor/moment/src/locale/te.js create mode 100644 public/vendor/moment/src/locale/th.js create mode 100644 public/vendor/moment/src/locale/tl-ph.js create mode 100644 public/vendor/moment/src/locale/tlh.js create mode 100644 public/vendor/moment/src/locale/tr.js create mode 100644 public/vendor/moment/src/locale/tzl.js create mode 100644 public/vendor/moment/src/locale/tzm-latn.js create mode 100644 public/vendor/moment/src/locale/tzm.js create mode 100644 public/vendor/moment/src/locale/uk.js create mode 100644 public/vendor/moment/src/locale/uz.js create mode 100644 public/vendor/moment/src/locale/vi.js create mode 100644 public/vendor/moment/src/locale/x-pseudo.js create mode 100644 public/vendor/moment/src/locale/zh-cn.js create mode 100644 public/vendor/moment/src/locale/zh-tw.js create mode 100644 public/vendor/moment/src/moment.js create mode 100644 public/vendor/moment/templates/amd-named.js create mode 100644 public/vendor/moment/templates/amd.js create mode 100644 public/vendor/moment/templates/default.js create mode 100644 public/vendor/moment/templates/globals.js create mode 100644 public/vendor/moment/templates/locale-header.js create mode 100644 public/vendor/moment/templates/test-header.js diff --git a/public/vendor/fullcalendar/.bower.json b/public/vendor/fullcalendar/.bower.json new file mode 100644 index 00000000..23523c21 --- /dev/null +++ b/public/vendor/fullcalendar/.bower.json @@ -0,0 +1,60 @@ +{ + "name": "fullcalendar", + "title": "FullCalendar", + "version": "2.7.1", + "description": "Full-sized drag & drop event calendar", + "keywords": [ + "calendar", + "event", + "full-sized", + "jquery-plugin" + ], + "homepage": "http://fullcalendar.io/", + "bugs": "http://fullcalendar.io/wiki/Reporting-Bugs/", + "repository": { + "type": "git", + "url": "https://github.com/fullcalendar/fullcalendar.git" + }, + "license": "MIT", + "author": { + "name": "Adam Shaw", + "email": "arshaw@arshaw.com", + "url": "http://arshaw.com/" + }, + "copyright": "2016 Adam Shaw", + "dependencies": { + "jquery": ">=1.7.1", + "moment": ">=2.5.0" + }, + "devDependencies": { + "jquery-ui": ">=1.11.1", + "jquery-simulate": "~1.0.1", + "jasmine-jquery": "~2.0.3", + "jasmine-fixture": "~1.2.0", + "moment-timezone": "~0.2.1", + "bootstrap": "~3.2.0", + "jquery-mockjax": "~2.1.1" + }, + "main": [ + "dist/fullcalendar.js", + "dist/fullcalendar.css" + ], + "ignore": [ + "*", + "**/.*", + "!/dist/**", + "!/README.*", + "!/LICENSE.*", + "!/CHANGELOG.*", + "!/CONTRIBUTING.*" + ], + "_release": "2.7.1", + "_resolution": { + "type": "version", + "tag": "v2.7.1", + "commit": "c0cf46d19d632bf4402ef7198b3619ad63953582" + }, + "_source": "https://github.com/arshaw/fullcalendar.git", + "_target": "^2.7.1", + "_originalSource": "fullcalendar" +} \ No newline at end of file diff --git a/public/vendor/fullcalendar/CHANGELOG.md b/public/vendor/fullcalendar/CHANGELOG.md new file mode 100644 index 00000000..b90afbb7 --- /dev/null +++ b/public/vendor/fullcalendar/CHANGELOG.md @@ -0,0 +1,945 @@ + +v2.7.1 (2016-05-01) +------------------- + +- dayClick not firing on touch devices (#3138) +- icons for prev/next not working in MS Edge (#2852) +- fix bad languages troubles with firewalls (#3133, #3132) +- update all dev dependencies (#3145, #3010, #2901, #251) +- git-ignore npm debug logs (#3011) +- misc automated test updates (#3139, #3147) +- Google Calendar htmlLink not always defined (#2844) + + +v2.7.0 (2016-04-23) +------------------- + +touch device support (#994): + - smoother scrolling + - interactions initiated via "long press": + - event drag-n-drop + - event resize + - time-range selecting + - `longPressDelay` + + +v2.6.1 (2016-02-17) +------------------- + +- make `nowIndicator` positioning refresh on window resize + + +v2.6.0 (2016-01-07) +------------------- + +- current time indicator (#414) +- bundled with most recent version of moment (2.11.0) +- UMD wrapper around lang files now handles commonjs (#2918) +- fix bug where external event dragging would not respect eventOverlap +- fix bug where external event dropping would not render the whole-day highlight + + +v2.5.0 (2015-11-30) +------------------- + +- internal timezone refactor. fixes #2396, #2900, #2945, #2711 +- internal "grid" system refactor. improved API for plugins. + + +v2.4.0 (2015-08-16) +------------------- + +- add new buttons to the header via `customButtons` ([225]) +- control stacking order of events via `eventOrder` ([364]) +- control frequency of slot text via `slotLabelInterval` ([946]) +- `displayEventTime` ([1904]) +- `on` and `off` methods ([1910]) +- renamed `axisFormat` to `slotLabelFormat` + +[225]: https://code.google.com/p/fullcalendar/issues/detail?id=225 +[364]: https://code.google.com/p/fullcalendar/issues/detail?id=364 +[946]: https://code.google.com/p/fullcalendar/issues/detail?id=946 +[1904]: https://code.google.com/p/fullcalendar/issues/detail?id=1904 +[1910]: https://code.google.com/p/fullcalendar/issues/detail?id=1910 + + +v2.3.2 (2015-06-14) +------------------- + +- minor code adjustment in preparation for plugins + + +v2.3.1 (2015-03-08) +------------------- + +- Fix week view column title for en-gb ([PR220]) +- Publish to NPM ([2447]) +- Detangle bower from npm package ([PR179]) + +[PR220]: https://github.com/arshaw/fullcalendar/pull/220 +[2447]: https://code.google.com/p/fullcalendar/issues/detail?id=2447 +[PR179]: https://github.com/arshaw/fullcalendar/pull/179 + + +v2.3.0 (2015-02-21) +------------------- + +- internal refactoring in preparation for other views +- businessHours now renders on whole-days in addition to timed areas +- events in "more" popover not sorted by time ([2385]) +- avoid using moment's deprecated zone method ([2443]) +- destroying the calendar sometimes causes all window resize handlers to be unbound ([2432]) +- multiple calendars on one page, can't accept external elements after navigating ([2433]) +- accept external events from jqui sortable ([1698]) +- external jqui drop processed before reverting ([1661]) +- IE8 fix: month view renders incorrectly ([2428]) +- IE8 fix: eventLimit:true wouldn't activate "more" link ([2330]) +- IE8 fix: dragging an event with an href +- IE8 fix: invisible element while dragging agenda view events +- IE8 fix: erratic external element dragging + +[2385]: https://code.google.com/p/fullcalendar/issues/detail?id=2385 +[2443]: https://code.google.com/p/fullcalendar/issues/detail?id=2443 +[2432]: https://code.google.com/p/fullcalendar/issues/detail?id=2432 +[2433]: https://code.google.com/p/fullcalendar/issues/detail?id=2433 +[1698]: https://code.google.com/p/fullcalendar/issues/detail?id=1698 +[1661]: https://code.google.com/p/fullcalendar/issues/detail?id=1661 +[2428]: https://code.google.com/p/fullcalendar/issues/detail?id=2428 +[2330]: https://code.google.com/p/fullcalendar/issues/detail?id=2330 + + +v2.2.7 (2015-02-10) +------------------- + +- view.title wasn't defined in viewRender callback ([2407]) +- FullCalendar versions >= 2.2.5 brokenness with Moment versions <= 2.8.3 ([2417]) +- Support Bokmal Norwegian language specifically ([2427]) + +[2407]: https://code.google.com/p/fullcalendar/issues/detail?id=2407 +[2417]: https://code.google.com/p/fullcalendar/issues/detail?id=2417 +[2427]: https://code.google.com/p/fullcalendar/issues/detail?id=2427 + + +v2.2.6 (2015-01-11) +------------------- + +- Compatibility with Moment v2.9. Was breaking GCal plugin ([2408]) +- View object's `title` property mistakenly omitted ([2407]) +- Single-day views with hiddens days could cause prev/next misbehavior ([2406]) +- Don't let the current date ever be a hidden day (solves [2395]) +- Hebrew locale ([2157]) + +[2408]: https://code.google.com/p/fullcalendar/issues/detail?id=2408 +[2407]: https://code.google.com/p/fullcalendar/issues/detail?id=2407 +[2406]: https://code.google.com/p/fullcalendar/issues/detail?id=2406 +[2395]: https://code.google.com/p/fullcalendar/issues/detail?id=2395 +[2157]: https://code.google.com/p/fullcalendar/issues/detail?id=2157 + + +v2.2.5 (2014-12-30) +------------------- + +- `buttonText` specified for custom views via the `views` option + - bugfix: wrong default value, couldn't override default + - feature: default value taken from locale + + +v2.2.4 (2014-12-29) +------------------- + +- Arbitrary durations for basic/agenda views with the `views` option ([692]) +- Specify view-specific options using the `views` option. fixes [2283] +- Deprecate view-option-hashes +- Formalize and expose View API ([1055]) +- updateEvent method, more intuitive behavior. fixes [2194] + +[692]: https://code.google.com/p/fullcalendar/issues/detail?id=692 +[2283]: https://code.google.com/p/fullcalendar/issues/detail?id=2283 +[1055]: https://code.google.com/p/fullcalendar/issues/detail?id=1055 +[2194]: https://code.google.com/p/fullcalendar/issues/detail?id=2194 + + +v2.2.3 (2014-11-26) +------------------- + +- removeEventSource with Google Calendar object source, would not remove ([2368]) +- Events with invalid end dates are still accepted and rendered ([2350], [2237], [2296]) +- Bug when rendering business hours and navigating away from original view ([2365]) +- Links to Google Calendar events will use current timezone ([2122]) +- Google Calendar plugin works with timezone names that have spaces +- Google Calendar plugin accepts person email addresses as calendar IDs +- Internally use numeric sort instead of alphanumeric sort ([2370]) + +[2368]: https://code.google.com/p/fullcalendar/issues/detail?id=2368 +[2350]: https://code.google.com/p/fullcalendar/issues/detail?id=2350 +[2237]: https://code.google.com/p/fullcalendar/issues/detail?id=2237 +[2296]: https://code.google.com/p/fullcalendar/issues/detail?id=2296 +[2365]: https://code.google.com/p/fullcalendar/issues/detail?id=2365 +[2122]: https://code.google.com/p/fullcalendar/issues/detail?id=2122 +[2370]: https://code.google.com/p/fullcalendar/issues/detail?id=2370 + + +v2.2.2 (2014-11-19) +------------------- + +- Fixes to Google Calendar API V3 code + - wouldn't recognize a lone-string Google Calendar ID if periods before the @ symbol + - removeEventSource wouldn't work when given a Google Calendar ID + + +v2.2.1 (2014-11-19) +------------------- + +- Migrate Google Calendar plugin to use V3 of the API ([1526]) + +[1526]: https://code.google.com/p/fullcalendar/issues/detail?id=1526 + + +v2.2.0 (2014-11-14) +------------------- + +- Background events. Event object's `rendering` property ([144], [1286]) +- `businessHours` option ([144]) +- Controlling where events can be dragged/resized and selections can go ([396], [1286], [2253]) + - `eventOverlap`, `selectOverlap`, and similar + - `eventConstraint`, `selectConstraint`, and similar +- Improvements to dragging and dropping external events ([2004]) + - Associating with real event data. used with `eventReceive` + - Associating a `duration` +- Performance boost for moment creation + - Be aware, FullCalendar-specific methods now attached directly to global moment.fn + - Helps with [issue 2259][2259] +- Reintroduced forgotten `dropAccept` option ([2312]) + +[144]: https://code.google.com/p/fullcalendar/issues/detail?id=144 +[396]: https://code.google.com/p/fullcalendar/issues/detail?id=396 +[1286]: https://code.google.com/p/fullcalendar/issues/detail?id=1286 +[2004]: https://code.google.com/p/fullcalendar/issues/detail?id=2004 +[2253]: https://code.google.com/p/fullcalendar/issues/detail?id=2253 +[2259]: https://code.google.com/p/fullcalendar/issues/detail?id=2259 +[2312]: https://code.google.com/p/fullcalendar/issues/detail?id=2312 + + +v2.1.1 (2014-08-29) +------------------- + +- removeEventSource not working with array ([2203]) +- mouseout not triggered after mouseover+updateEvent ([829]) +- agenda event's render with no href, not clickable ([2263]) + +[2203]: https://code.google.com/p/fullcalendar/issues/detail?id=2203 +[829]: https://code.google.com/p/fullcalendar/issues/detail?id=829 +[2263]: https://code.google.com/p/fullcalendar/issues/detail?id=2263 + + +v2.1.0 (2014-08-25) +------------------- + +Large code refactor with better OOP, better code reuse, and more comments. +**No more reliance on jQuery UI** for event dragging, resizing, or anything else. + +Significant changes to HTML/CSS skeleton: +- Leverages tables for liquid rendering of days and events. No costly manual repositioning ([809]) +- **Backwards-incompatibilities**: + - **Many classNames have changed. Custom CSS will likely need to be adjusted.** + - IE7 definitely not supported anymore + - In `eventRender` callback, `element` will not be attached to DOM yet + - Events are styled to be one line by default ([1992]). Can be undone through custom CSS, + but not recommended (might get gaps [like this][111] in certain situations). + +A "more..." link when there are too many events on a day ([304]). Works with month and basic views +as well as the all-day section of the agenda views. New options: +- `eventLimit`. a number or `true` +- `eventLimitClick`. the `"popover`" value will reveal all events in a raised panel (the default) +- `eventLimitText` +- `dayPopoverFormat` + +Changes related to height and scrollbars: +- `aspectRatio`/`height`/`contentHeight` values will be honored *no matter what* + - If too many events causing too much vertical space, scrollbars will be used ([728]). + This is default behavior for month view (**backwards-incompatibility**) + - If too few slots in agenda view, view will stretch to be the correct height ([2196]) +- `'auto'` value for `height`/`contentHeight` options. If content is too tall, the view will + vertically stretch to accomodate and no scrollbars will be used ([521]). +- Tall weeks in month view will borrow height from other weeks ([243]) +- Automatically scroll the view then dragging/resizing an event ([1025], [2078]) +- New `fixedWeekCount` option to determines the number of weeks in month view + - Supersedes `weekMode` (**deprecated**). Instead, use a combination of `fixedWeekCount` and + one of the height options, possibly with an `'auto'` value + +Much nicer, glitch-free rendering of calendar *for printers* ([35]). Things you might not expect: +- Buttons will become hidden +- Agenda views display a flat list of events where the time slots would be + +Other issues resolved along the way: +- Space on right side of agenda events configurable through CSS ([204]) +- Problem with window resize ([259]) +- Events sorting stays consistent across weeks ([510]) +- Agenda's columns misaligned on wide screens ([511]) +- Run `selectHelper` through `eventRender` callbacks ([629]) +- Keyboard access, tabbing ([637]) +- Run resizing events through `eventRender` ([714]) +- Resize an event to a different day in agenda views ([736]) +- Allow selection across days in agenda views ([778]) +- Mouseenter delegated event not working on event elements ([936]) +- Agenda event dragging, snapping to different columns is erratic ([1101]) +- Android browser cuts off Day view at 8 PM with no scroll bar ([1203]) +- Don't fire `eventMouseover`/`eventMouseout` while dragging/resizing ([1297]) +- Customize the resize handle text ("=") ([1326]) +- If agenda event is too short, don't overwrite `.fc-event-time` ([1700]) +- Zooming calendar causes events to misalign ([1996]) +- Event destroy callback on event removal ([2017]) +- Agenda views, when RTL, should have axis on right ([2132]) +- Make header buttons more accessibile ([2151]) +- daySelectionMousedown should interpret OSX ctrl+click as a right mouse click ([2169]) +- Best way to display time text on multi-day events *with times* ([2172]) +- Eliminate table use for header layout ([2186]) +- Event delegation used for event-related callbacks (like `eventClick`). Speedier. + +[35]: https://code.google.com/p/fullcalendar/issues/detail?id=35 +[204]: https://code.google.com/p/fullcalendar/issues/detail?id=204 +[243]: https://code.google.com/p/fullcalendar/issues/detail?id=243 +[259]: https://code.google.com/p/fullcalendar/issues/detail?id=259 +[304]: https://code.google.com/p/fullcalendar/issues/detail?id=304 +[510]: https://code.google.com/p/fullcalendar/issues/detail?id=510 +[511]: https://code.google.com/p/fullcalendar/issues/detail?id=511 +[521]: https://code.google.com/p/fullcalendar/issues/detail?id=521 +[629]: https://code.google.com/p/fullcalendar/issues/detail?id=629 +[637]: https://code.google.com/p/fullcalendar/issues/detail?id=637 +[714]: https://code.google.com/p/fullcalendar/issues/detail?id=714 +[728]: https://code.google.com/p/fullcalendar/issues/detail?id=728 +[736]: https://code.google.com/p/fullcalendar/issues/detail?id=736 +[778]: https://code.google.com/p/fullcalendar/issues/detail?id=778 +[809]: https://code.google.com/p/fullcalendar/issues/detail?id=809 +[936]: https://code.google.com/p/fullcalendar/issues/detail?id=936 +[1025]: https://code.google.com/p/fullcalendar/issues/detail?id=1025 +[1101]: https://code.google.com/p/fullcalendar/issues/detail?id=1101 +[1203]: https://code.google.com/p/fullcalendar/issues/detail?id=1203 +[1297]: https://code.google.com/p/fullcalendar/issues/detail?id=1297 +[1326]: https://code.google.com/p/fullcalendar/issues/detail?id=1326 +[1700]: https://code.google.com/p/fullcalendar/issues/detail?id=1700 +[1992]: https://code.google.com/p/fullcalendar/issues/detail?id=1992 +[1996]: https://code.google.com/p/fullcalendar/issues/detail?id=1996 +[2017]: https://code.google.com/p/fullcalendar/issues/detail?id=2017 +[2078]: https://code.google.com/p/fullcalendar/issues/detail?id=2078 +[2132]: https://code.google.com/p/fullcalendar/issues/detail?id=2132 +[2151]: https://code.google.com/p/fullcalendar/issues/detail?id=2151 +[2169]: https://code.google.com/p/fullcalendar/issues/detail?id=2169 +[2172]: https://code.google.com/p/fullcalendar/issues/detail?id=2172 +[2186]: https://code.google.com/p/fullcalendar/issues/detail?id=2186 +[2196]: https://code.google.com/p/fullcalendar/issues/detail?id=2196 +[111]: https://code.google.com/p/fullcalendar/issues/detail?id=111 + + +v2.0.3 (2014-08-15) +------------------- + +- moment-2.8.1 compatibility ([2221]) +- relative path in bower.json ([PR 117]) +- upgraded jquery-ui and misc dev dependencies + +[2221]: https://code.google.com/p/fullcalendar/issues/detail?id=2221 +[PR 117]: https://github.com/arshaw/fullcalendar/pull/177 + + +v2.0.2 (2014-06-24) +------------------- + +- bug with persisting addEventSource calls ([2191]) +- bug with persisting removeEvents calls with an array source ([2187]) +- bug with removeEvents method when called with 0 removes all events ([2082]) + +[2191]: https://code.google.com/p/fullcalendar/issues/detail?id=2191 +[2187]: https://code.google.com/p/fullcalendar/issues/detail?id=2187 +[2082]: https://code.google.com/p/fullcalendar/issues/detail?id=2082 + + +v2.0.1 (2014-06-15) +------------------- + +- `delta` parameters reintroduced in `eventDrop` and `eventResize` handlers ([2156]) + - **Note**: this changes the argument order for `revertFunc` +- wrongfully triggering a windowResize when resizing an agenda view event ([1116]) +- `this` values in event drag-n-drop/resize handlers consistently the DOM node ([1177]) +- `displayEventEnd` - v2 workaround to force display of an end time ([2090]) +- don't modify passed-in eventSource items ([954]) +- destroy method now removes fc-ltr class ([2033]) +- weeks of last/next month still visible when weekends are hidden ([2095]) +- fixed memory leak when destroying calendar with selectable/droppable ([2137]) +- Icelandic language ([2180]) +- Bahasa Indonesia language ([PR 172]) + +[1116]: https://code.google.com/p/fullcalendar/issues/detail?id=1116 +[1177]: https://code.google.com/p/fullcalendar/issues/detail?id=1177 +[2090]: https://code.google.com/p/fullcalendar/issues/detail?id=2090 +[954]: https://code.google.com/p/fullcalendar/issues/detail?id=954 +[2033]: https://code.google.com/p/fullcalendar/issues/detail?id=2033 +[2095]: https://code.google.com/p/fullcalendar/issues/detail?id=2095 +[2137]: https://code.google.com/p/fullcalendar/issues/detail?id=2137 +[2156]: https://code.google.com/p/fullcalendar/issues/detail?id=2156 +[2180]: https://code.google.com/p/fullcalendar/issues/detail?id=2180 +[PR 172]: https://github.com/arshaw/fullcalendar/pull/172 + + +v2.0.0 (2014-06-01) +------------------- + +Internationalization support, timezone support, and [MomentJS] integration. Extensive changes, many +of which are backwards incompatible. + +[Full list of changes][Upgrading-to-v2] | [Affected Issues][Date-Milestone] + +An automated testing framework has been set up ([Karma] + [Jasmine]) and tests have been written +which cover about half of FullCalendar's functionality. Special thanks to @incre-d, @vidbina, and +@sirrocco for the help. + +In addition, the main development repo has been repurposed to also include the built distributable +JS/CSS for the project and will serve as the new [Bower] endpoint. + +[MomentJS]: http://momentjs.com/ +[Upgrading-to-v2]: http://arshaw.com/fullcalendar/wiki/Upgrading-to-v2/ +[Date-Milestone]: https://code.google.com/p/fullcalendar/issues/list?can=1&q=milestone%3Ddate +[Karma]: http://karma-runner.github.io/ +[Jasmine]: http://jasmine.github.io/ +[Bower]: http://bower.io/ + + +v1.6.4 (2013-09-01) +------------------- + +- better algorithm for positioning timed agenda events ([1115]) +- `slotEventOverlap` option to tweak timed agenda event overlapping ([218]) +- selection bug when slot height is customized ([1035]) +- supply view argument in `loading` callback ([1018]) +- fixed week number not displaying in agenda views ([1951]) +- fixed fullCalendar not initializing with no options ([1356]) +- NPM's `package.json`, no more warnings or errors ([1762]) +- building the bower component should output `bower.json` instead of `component.json` ([PR 125]) +- use bower internally for fetching new versions of jQuery and jQuery UI + +[1115]: https://code.google.com/p/fullcalendar/issues/detail?id=1115 +[218]: https://code.google.com/p/fullcalendar/issues/detail?id=218 +[1035]: https://code.google.com/p/fullcalendar/issues/detail?id=1035 +[1018]: https://code.google.com/p/fullcalendar/issues/detail?id=1018 +[1951]: https://code.google.com/p/fullcalendar/issues/detail?id=1951 +[1356]: https://code.google.com/p/fullcalendar/issues/detail?id=1356 +[1762]: https://code.google.com/p/fullcalendar/issues/detail?id=1762 +[PR 125]: https://github.com/arshaw/fullcalendar/pull/125 + + +v1.6.3 (2013-08-10) +------------------- + +- `viewRender` callback ([PR 15]) +- `viewDestroy` callback ([PR 15]) +- `eventDestroy` callback ([PR 111]) +- `handleWindowResize` option ([PR 54]) +- `eventStartEditable`/`startEditable` options ([PR 49]) +- `eventDurationEditable`/`durationEditable` options ([PR 49]) +- specify function for `$.ajax` `data` parameter for JSON event sources ([PR 59]) +- fixed bug with agenda event dropping in wrong column ([PR 55]) +- easier event element z-index customization ([PR 58]) +- classNames on past/future days ([PR 88]) +- allow `null`/`undefined` event titles ([PR 84]) +- small optimize for agenda event rendering ([PR 56]) +- deprecated: + - `viewDisplay` + - `disableDragging` + - `disableResizing` +- bundled with latest jQuery (1.10.2) and jQuery UI (1.10.3) + +[PR 15]: https://github.com/arshaw/fullcalendar/pull/15 +[PR 111]: https://github.com/arshaw/fullcalendar/pull/111 +[PR 54]: https://github.com/arshaw/fullcalendar/pull/54 +[PR 49]: https://github.com/arshaw/fullcalendar/pull/49 +[PR 59]: https://github.com/arshaw/fullcalendar/pull/59 +[PR 55]: https://github.com/arshaw/fullcalendar/pull/55 +[PR 58]: https://github.com/arshaw/fullcalendar/pull/58 +[PR 88]: https://github.com/arshaw/fullcalendar/pull/88 +[PR 84]: https://github.com/arshaw/fullcalendar/pull/84 +[PR 56]: https://github.com/arshaw/fullcalendar/pull/56 + + +v1.6.2 (2013-07-18) +------------------- + +- `hiddenDays` option ([686]) +- bugfix: when `eventRender` returns `false`, incorrect stacking of events ([762]) +- bugfix: couldn't change `event.backgroundImage` when calling `updateEvent` (thx @stephenharris) + +[686]: https://code.google.com/p/fullcalendar/issues/detail?id=686 +[762]: https://code.google.com/p/fullcalendar/issues/detail?id=762 + + +v1.6.1 (2013-04-14) +------------------- + +- fixed event inner content overflow bug ([1783]) +- fixed table header className bug [1772] +- removed text-shadow on events (better for general use, thx @tkrotoff) + +[1783]: https://code.google.com/p/fullcalendar/issues/detail?id=1783 +[1772]: https://code.google.com/p/fullcalendar/issues/detail?id=1772 + + +v1.6.0 (2013-03-18) +------------------- + +- visual facelift, with bootstrap-inspired buttons and colors +- simplified HTML/CSS for events and buttons +- `dayRender`, for modifying a day cell ([191], thx @althaus) +- week numbers on side of calendar ([295]) + - `weekNumber` + - `weekNumberCalculation` + - `weekNumberTitle` + - `W` formatting variable +- finer snapping granularity for agenda view events ([495], thx @ms-doodle-com) +- `eventAfterAllRender` ([753], thx @pdrakeweb) +- `eventDataTransform` (thx @joeyspo) +- `data-date` attributes on cells (thx @Jae) +- expose `$.fullCalendar.dateFormatters` +- when clicking fast on buttons, prevent text selection +- bundled with latest jQuery (1.9.1) and jQuery UI (1.10.2) +- Grunt/Lumbar build system for internal development +- build for Bower package manager +- build for jQuery plugin site + +[191]: https://code.google.com/p/fullcalendar/issues/detail?id=191 +[295]: https://code.google.com/p/fullcalendar/issues/detail?id=295 +[495]: https://code.google.com/p/fullcalendar/issues/detail?id=495 +[753]: https://code.google.com/p/fullcalendar/issues/detail?id=753 + + +v1.5.4 (2012-09-05) +------------------- + +- made compatible with jQuery 1.8.* (thx @archaeron) +- bundled with jQuery 1.8.1 and jQuery UI 1.8.23 + + +v1.5.3 (2012-02-06) +------------------- + +- fixed dragging issue with jQuery UI 1.8.16 ([1168]) +- bundled with jQuery 1.7.1 and jQuery UI 1.8.17 + +[1168]: https://code.google.com/p/fullcalendar/issues/detail?id=1168 + + +v1.5.2 (2011-08-21) +------------------- + +- correctly process UTC "Z" ISO8601 date strings ([750]) + +[750]: https://code.google.com/p/fullcalendar/issues/detail?id=750 + + +v1.5.1 (2011-04-09) +------------------- + +- more flexible ISO8601 date parsing ([814]) +- more flexible parsing of UNIX timestamps ([826]) +- FullCalendar now buildable from source on a Mac ([795]) +- FullCalendar QA'd in FF4 ([883]) +- upgraded to jQuery 1.5.2 (which supports IE9) and jQuery UI 1.8.11 + +[814]: https://code.google.com/p/fullcalendar/issues/detail?id=814 +[826]: https://code.google.com/p/fullcalendar/issues/detail?id=826 +[795]: https://code.google.com/p/fullcalendar/issues/detail?id=795 +[883]: https://code.google.com/p/fullcalendar/issues/detail?id=883 + + +v1.5 (2011-03-19) +----------------- + +- slicker default styling for buttons +- reworked a lot of the calendar's HTML and accompanying CSS (solves [327] and [395]) +- more printer-friendly (fullcalendar-print.css) +- fullcalendar now inherits styles from jquery-ui themes differently. + styles for buttons are distinct from styles for calendar cells. + (solves [299]) +- can now color events through FullCalendar options and Event-Object properties ([117]) + THIS IS NOW THE PREFERRED METHOD OF COLORING EVENTS (as opposed to using className and CSS) + - FullCalendar options: + - eventColor (changes both background and border) + - eventBackgroundColor + - eventBorderColor + - eventTextColor + - Event-Object options: + - color (changes both background and border) + - backgroundColor + - borderColor + - textColor +- can now specify an event source as an *object* with a `url` property (json feed) or + an `events` property (function or array) with additional properties that will + be applied to the entire event source: + - color (changes both background and border) + - backgroudColor + - borderColor + - textColor + - className + - editable + - allDayDefault + - ignoreTimezone + - startParam (for a feed) + - endParam (for a feed) + - ANY OF THE JQUERY $.ajax OPTIONS + allows for easily changing from GET to POST and sending additional parameters ([386]) + allows for easily attaching ajax handlers such as `error` ([754]) + allows for turning caching on ([355]) +- Google Calendar feeds are now specified differently: + - specify a simple string of your feed's URL + - specify an *object* with a `url` property of your feed's URL. + you can include any of the new Event-Source options in this object. + - the old `$.fullCalendar.gcalFeed` method still works +- no more IE7 SSL popup ([504]) +- remove `cacheParam` - use json event source `cache` option instead +- latest jquery/jquery-ui + +[327]: https://code.google.com/p/fullcalendar/issues/detail?id=327 +[395]: https://code.google.com/p/fullcalendar/issues/detail?id=395 +[299]: https://code.google.com/p/fullcalendar/issues/detail?id=299 +[117]: https://code.google.com/p/fullcalendar/issues/detail?id=117 +[386]: https://code.google.com/p/fullcalendar/issues/detail?id=386 +[754]: https://code.google.com/p/fullcalendar/issues/detail?id=754 +[355]: https://code.google.com/p/fullcalendar/issues/detail?id=355 +[504]: https://code.google.com/p/fullcalendar/issues/detail?id=504 + + +v1.4.11 (2011-02-22) +-------------------- + +- fixed rerenderEvents bug ([790]) +- fixed bug with faulty dragging of events from all-day slot in agenda views +- bundled with jquery 1.5 and jquery-ui 1.8.9 + +[790]: https://code.google.com/p/fullcalendar/issues/detail?id=790 + + +v1.4.10 (2011-01-02) +-------------------- + +- fixed bug with resizing event to different week in 5-day month view ([740]) +- fixed bug with events not sticking after a removeEvents call ([757]) +- fixed bug with underlying parseTime method, and other uses of parseInt ([688]) + +[740]: https://code.google.com/p/fullcalendar/issues/detail?id=740 +[757]: https://code.google.com/p/fullcalendar/issues/detail?id=757 +[688]: https://code.google.com/p/fullcalendar/issues/detail?id=688 + + +v1.4.9 (2010-11-16) +------------------- + +- new algorithm for vertically stacking events ([111]) +- resizing an event to a different week ([306]) +- bug: some events not rendered with consecutive calls to addEventSource ([679]) + +[111]: https://code.google.com/p/fullcalendar/issues/detail?id=111 +[306]: https://code.google.com/p/fullcalendar/issues/detail?id=306 +[679]: https://code.google.com/p/fullcalendar/issues/detail?id=679 + + +v1.4.8 (2010-10-16) +------------------- + +- ignoreTimezone option (set to `false` to process UTC offsets in ISO8601 dates) +- bugfixes + - event refetching not being called under certain conditions ([417], [554]) + - event refetching being called multiple times under certain conditions ([586], [616]) + - selection cannot be triggered by right mouse button ([558]) + - agenda view left axis sized incorrectly ([465]) + - IE js error when calendar is too narrow ([517]) + - agenda view looks strange when no scrollbars ([235]) + - improved parsing of ISO8601 dates with UTC offsets +- $.fullCalendar.version +- an internal refactor of the code, for easier future development and modularity + +[417]: https://code.google.com/p/fullcalendar/issues/detail?id=417 +[554]: https://code.google.com/p/fullcalendar/issues/detail?id=554 +[586]: https://code.google.com/p/fullcalendar/issues/detail?id=586 +[616]: https://code.google.com/p/fullcalendar/issues/detail?id=616 +[558]: https://code.google.com/p/fullcalendar/issues/detail?id=558 +[465]: https://code.google.com/p/fullcalendar/issues/detail?id=465 +[517]: https://code.google.com/p/fullcalendar/issues/detail?id=517 +[235]: https://code.google.com/p/fullcalendar/issues/detail?id=235 + + +v1.4.7 (2010-07-05) +------------------- + +- "dropping" external objects onto the calendar + - droppable (boolean, to turn on/off) + - dropAccept (to filter which events the calendar will accept) + - drop (trigger) +- selectable options can now be specified with a View Option Hash +- bugfixes + - dragged & reverted events having wrong time text ([406]) + - bug rendering events that have an endtime with seconds, but no hours/minutes ([477]) + - gotoDate date overflow bug ([429]) + - wrong date reported when clicking on edge of last column in agenda views [412] +- support newlines in event titles +- select/unselect callbacks now passes native js event + +[406]: https://code.google.com/p/fullcalendar/issues/detail?id=406 +[477]: https://code.google.com/p/fullcalendar/issues/detail?id=477 +[429]: https://code.google.com/p/fullcalendar/issues/detail?id=429 +[412]: https://code.google.com/p/fullcalendar/issues/detail?id=412 + + +v1.4.6 (2010-05-31) +------------------- + +- "selecting" days or timeslots + - options: selectable, selectHelper, unselectAuto, unselectCancel + - callbacks: select, unselect + - methods: select, unselect +- when dragging an event, the highlighting reflects the duration of the event +- code compressing by Google Closure Compiler +- bundled with jQuery 1.4.2 and jQuery UI 1.8.1 + + +v1.4.5 (2010-02-21) +------------------- + +- lazyFetching option, which can force the calendar to fetch events on every view/date change +- scroll state of agenda views are preserved when switching back to view +- bugfixes + - calling methods on an uninitialized fullcalendar throws error + - IE6/7 bug where an entire view becomes invisible ([320]) + - error when rendering a hidden calendar (in jquery ui tabs for example) in IE ([340]) + - interconnected bugs related to calendar resizing and scrollbars + - when switching views or clicking prev/next, calendar would "blink" ([333]) + - liquid-width calendar's events shifted (depending on initial height of browser) ([341]) + - more robust underlying algorithm for calendar resizing + +[320]: https://code.google.com/p/fullcalendar/issues/detail?id=320 +[340]: https://code.google.com/p/fullcalendar/issues/detail?id=340 +[333]: https://code.google.com/p/fullcalendar/issues/detail?id=333 +[341]: https://code.google.com/p/fullcalendar/issues/detail?id=341 + + +v1.4.4 (2010-02-03) +------------------- + +- optimized event rendering in all views (events render in 1/10 the time) +- gotoDate() does not force the calendar to unnecessarily rerender +- render() method now correctly readjusts height + + +v1.4.3 (2009-12-22) +------------------- + +- added destroy method +- Google Calendar event pages respect currentTimezone +- caching now handled by jQuery's ajax +- protection from setting aspectRatio to zero +- bugfixes + - parseISO8601 and DST caused certain events to display day before + - button positioning problem in IE6 + - ajax event source removed after recently being added, events still displayed + - event not displayed when end is an empty string + - dynamically setting calendar height when no events have been fetched, throws error + + +v1.4.2 (2009-12-02) +------------------- + +- eventAfterRender trigger +- getDate & getView methods +- height & contentHeight options (explicitly sets the pixel height) +- minTime & maxTime options (restricts shown hours in agenda view) +- getters [for all options] and setters [for height, contentHeight, and aspectRatio ONLY! stay tuned..] +- render method now readjusts calendar's size +- bugfixes + - lightbox scripts that use iframes (like fancybox) + - day-of-week classNames were off when firstDay=1 + - guaranteed space on right side of agenda events (even when stacked) + - accepts ISO8601 dates with a space (instead of 'T') + + +v1.4.1 (2009-10-31) +------------------- + +- can exclude weekends with new 'weekends' option +- gcal feed 'currentTimezone' option +- bugfixes + - year/month/date option sometimes wouldn't set correctly (depending on current date) + - daylight savings issue caused agenda views to start at 1am (for BST users) +- cleanup of gcal.js code + + +v1.4 (2009-10-19) +----------------- + +- agendaWeek and agendaDay views +- added some options for agenda views: + - allDaySlot + - allDayText + - firstHour + - slotMinutes + - defaultEventMinutes + - axisFormat +- modified some existing options/triggers to work with agenda views: + - dragOpacity and timeFormat can now accept a "View Hash" (a new concept) + - dayClick now has an allDay parameter + - eventDrop now has an an allDay parameter + (this will affect those who use revertFunc, adjust parameter list) +- added 'prevYear' and 'nextYear' for buttons in header +- minor change for theme users, ui-state-hover not applied to active/inactive buttons +- added event-color-changing example in docs +- better defaults for right-to-left themed button icons + + +v1.3.2 (2009-10-13) +------------------- + +- Bugfixes (please upgrade from 1.3.1!) + - squashed potential infinite loop when addMonths and addDays + is called with an invalid date + - $.fullCalendar.parseDate() now correctly parses IETF format + - when switching views, the 'today' button sticks inactive, fixed +- gotoDate now can accept a single Date argument +- documentation for changes in 1.3.1 and 1.3.2 now on website + + +v1.3.1 (2009-09-30) +------------------- + +- Important Bugfixes (please upgrade from 1.3!) + - When current date was late in the month, for long months, and prev/next buttons + were clicked in month-view, some months would be skipped/repeated + - In certain time zones, daylight savings time would cause certain days + to be misnumbered in month-view +- Subtle change in way week interval is chosen when switching from month to basicWeek/basicDay view +- Added 'allDayDefault' option +- Added 'changeView' and 'render' methods + + +v1.3 (2009-09-21) +----------------- + +- different 'views': month/basicWeek/basicDay +- more flexible 'header' system for buttons +- themable by jQuery UI themes +- resizable events (require jQuery UI resizable plugin) +- rescoped & rewritten CSS, enhanced default look +- cleaner css & rendering techniques for right-to-left +- reworked options & API to support multiple views / be consistent with jQuery UI +- refactoring of entire codebase + - broken into different JS & CSS files, assembled w/ build scripts + - new test suite for new features, uses firebug-lite +- refactored docs +- Options + - + date + - + defaultView + - + aspectRatio + - + disableResizing + - + monthNames (use instead of $.fullCalendar.monthNames) + - + monthNamesShort (use instead of $.fullCalendar.monthAbbrevs) + - + dayNames (use instead of $.fullCalendar.dayNames) + - + dayNamesShort (use instead of $.fullCalendar.dayAbbrevs) + - + theme + - + buttonText + - + buttonIcons + - x draggable -> editable/disableDragging + - x fixedWeeks -> weekMode + - x abbrevDayHeadings -> columnFormat + - x buttons/title -> header + - x eventDragOpacity -> dragOpacity + - x eventRevertDuration -> dragRevertDuration + - x weekStart -> firstDay + - x rightToLeft -> isRTL + - x showTime (use 'allDay' CalEvent property instead) +- Triggered Actions + - + eventResizeStart + - + eventResizeStop + - + eventResize + - x monthDisplay -> viewDisplay + - x resize -> windowResize + - 'eventDrop' params changed, can revert if ajax cuts out +- CalEvent Properties + - x showTime -> allDay + - x draggable -> editable + - 'end' is now INCLUSIVE when allDay=true + - 'url' now produces a real tag, more native clicking/tab behavior +- Methods: + - + renderEvent + - x prevMonth -> prev + - x nextMonth -> next + - x prevYear/nextYear -> moveDate + - x refresh -> rerenderEvents/refetchEvents + - x removeEvent -> removeEvents + - x getEventsByID -> clientEvents +- Utilities: + - 'formatDate' format string completely changed (inspired by jQuery UI datepicker + datejs) + - 'formatDates' added to support date-ranges +- Google Calendar Options: + - x draggable -> editable +- Bugfixes + - gcal extension fetched 25 results max, now fetches all + + +v1.2.1 (2009-06-29) +------------------- + +- bugfixes + - allows and corrects invalid end dates for events + - doesn't throw an error in IE while rendering when display:none + - fixed 'loading' callback when used w/ multiple addEventSource calls + - gcal className can now be an array + + +v1.2 (2009-05-31) +----------------- + +- expanded API + - 'className' CalEvent attribute + - 'source' CalEvent attribute + - dynamically get/add/remove/update events of current month + - locale improvements: change month/day name text + - better date formatting ($.fullCalendar.formatDate) + - multiple 'event sources' allowed + - dynamically add/remove event sources +- options for prevYear and nextYear buttons +- docs have been reworked (include addition of Google Calendar docs) +- changed behavior of parseDate for number strings + (now interpets as unix timestamp, not MS times) +- bugfixes + - rightToLeft month start bug + - off-by-one errors with month formatting commands + - events from previous months sticking when clicking prev/next quickly +- Google Calendar API changed to work w/ multiple event sources + - can also provide 'className' and 'draggable' options +- date utilties moved from $ to $.fullCalendar +- more documentation in source code +- minified version of fullcalendar.js +- test suit (available from svn) +- top buttons now use `' + ) + .click(function(ev) { + // don't process clicks for disabled buttons + if (!button.hasClass(tm + '-state-disabled')) { + + buttonClick(ev); + + // after the click action, if the button becomes the "active" tab, or disabled, + // it should never have a hover class, so remove it now. + if ( + button.hasClass(tm + '-state-active') || + button.hasClass(tm + '-state-disabled') + ) { + button.removeClass(tm + '-state-hover'); + } + } + }) + .mousedown(function() { + // the *down* effect (mouse pressed in). + // only on buttons that are not the "active" tab, or disabled + button + .not('.' + tm + '-state-active') + .not('.' + tm + '-state-disabled') + .addClass(tm + '-state-down'); + }) + .mouseup(function() { + // undo the *down* effect + button.removeClass(tm + '-state-down'); + }) + .hover( + function() { + // the *hover* effect. + // only on buttons that are not the "active" tab, or disabled + button + .not('.' + tm + '-state-active') + .not('.' + tm + '-state-disabled') + .addClass(tm + '-state-hover'); + }, + function() { + // undo the *hover* effect + button + .removeClass(tm + '-state-hover') + .removeClass(tm + '-state-down'); // if mouseleave happens before mouseup + } + ); + + groupChildren = groupChildren.add(button); + } + } + }); + + if (isOnlyButtons) { + groupChildren + .first().addClass(tm + '-corner-left').end() + .last().addClass(tm + '-corner-right').end(); + } + + if (groupChildren.length > 1) { + groupEl = $('
'); + if (isOnlyButtons) { + groupEl.addClass('fc-button-group'); + } + groupEl.append(groupChildren); + sectionEl.append(groupEl); + } + else { + sectionEl.append(groupChildren); // 1 or 0 children + } + }); + } + + return sectionEl; + } + + + function updateTitle(text) { + el.find('h2').text(text); + } + + + function activateButton(buttonName) { + el.find('.fc-' + buttonName + '-button') + .addClass(tm + '-state-active'); + } + + + function deactivateButton(buttonName) { + el.find('.fc-' + buttonName + '-button') + .removeClass(tm + '-state-active'); + } + + + function disableButton(buttonName) { + el.find('.fc-' + buttonName + '-button') + .attr('disabled', 'disabled') + .addClass(tm + '-state-disabled'); + } + + + function enableButton(buttonName) { + el.find('.fc-' + buttonName + '-button') + .removeAttr('disabled') + .removeClass(tm + '-state-disabled'); + } + + + function getViewsWithButtons() { + return viewsWithButtons; + } + +} + +;; + +FC.sourceNormalizers = []; +FC.sourceFetchers = []; + +var ajaxDefaults = { + dataType: 'json', + cache: false +}; + +var eventGUID = 1; + + +function EventManager(options) { // assumed to be a calendar + var t = this; + + + // exports + t.isFetchNeeded = isFetchNeeded; + t.fetchEvents = fetchEvents; + t.addEventSource = addEventSource; + t.removeEventSource = removeEventSource; + t.updateEvent = updateEvent; + t.renderEvent = renderEvent; + t.removeEvents = removeEvents; + t.clientEvents = clientEvents; + t.mutateEvent = mutateEvent; + t.normalizeEventDates = normalizeEventDates; + t.normalizeEventTimes = normalizeEventTimes; + + + // imports + var reportEvents = t.reportEvents; + + + // locals + var stickySource = { events: [] }; + var sources = [ stickySource ]; + var rangeStart, rangeEnd; + var currentFetchID = 0; + var pendingSourceCnt = 0; + var cache = []; // holds events that have already been expanded + + + $.each( + (options.events ? [ options.events ] : []).concat(options.eventSources || []), + function(i, sourceInput) { + var source = buildEventSource(sourceInput); + if (source) { + sources.push(source); + } + } + ); + + + + /* Fetching + -----------------------------------------------------------------------------*/ + + + // start and end are assumed to be unzoned + function isFetchNeeded(start, end) { + return !rangeStart || // nothing has been fetched yet? + start < rangeStart || end > rangeEnd; // is part of the new range outside of the old range? + } + + + function fetchEvents(start, end) { + rangeStart = start; + rangeEnd = end; + cache = []; + var fetchID = ++currentFetchID; + var len = sources.length; + pendingSourceCnt = len; + for (var i=0; i= eventStart && range.end <= eventEnd; + } + + + // Does the event's date range intersect with the given range? + // start/end already assumed to have stripped zones :( + function eventIntersectsRange(event, range) { + var eventStart = event.start.clone().stripZone(); + var eventEnd = t.getEventEnd(event).stripZone(); + + return range.start < eventEnd && range.end > eventStart; + } + + + t.getEventCache = function() { + return cache; + }; + +} + + +// Returns a list of events that the given event should be compared against when being considered for a move to +// the specified span. Attached to the Calendar's prototype because EventManager is a mixin for a Calendar. +Calendar.prototype.getPeerEvents = function(span, event) { + var cache = this.getEventCache(); + var peerEvents = []; + var i, otherEvent; + + for (i = 0; i < cache.length; i++) { + otherEvent = cache[i]; + if ( + !event || + event._id !== otherEvent._id // don't compare the event to itself or other related [repeating] events + ) { + peerEvents.push(otherEvent); + } + } + + return peerEvents; +}; + + +// updates the "backup" properties, which are preserved in order to compute diffs later on. +function backupEventDates(event) { + event._allDay = event.allDay; + event._start = event.start.clone(); + event._end = event.end ? event.end.clone() : null; +} + +;; + +/* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells. +----------------------------------------------------------------------------------------------------------------------*/ +// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting. +// It is responsible for managing width/height. + +var BasicView = FC.BasicView = View.extend({ + + scroller: null, + + dayGridClass: DayGrid, // class the dayGrid will be instantiated from (overridable by subclasses) + dayGrid: null, // the main subcomponent that does most of the heavy lifting + + dayNumbersVisible: false, // display day numbers on each day cell? + weekNumbersVisible: false, // display week numbers along the side? + + weekNumberWidth: null, // width of all the week-number cells running down the side + + headContainerEl: null, // div that hold's the dayGrid's rendered date header + headRowEl: null, // the fake row element of the day-of-week header + + + initialize: function() { + this.dayGrid = this.instantiateDayGrid(); + + this.scroller = new Scroller({ + overflowX: 'hidden', + overflowY: 'auto' + }); + }, + + + // Generates the DayGrid object this view needs. Draws from this.dayGridClass + instantiateDayGrid: function() { + // generate a subclass on the fly with BasicView-specific behavior + // TODO: cache this subclass + var subclass = this.dayGridClass.extend(basicDayGridMethods); + + return new subclass(this); + }, + + + // Sets the display range and computes all necessary dates + setRange: function(range) { + View.prototype.setRange.call(this, range); // call the super-method + + this.dayGrid.breakOnWeeks = /year|month|week/.test(this.intervalUnit); // do before setRange + this.dayGrid.setRange(range); + }, + + + // Compute the value to feed into setRange. Overrides superclass. + computeRange: function(date) { + var range = View.prototype.computeRange.call(this, date); // get value from the super-method + + // year and month views should be aligned with weeks. this is already done for week + if (/year|month/.test(range.intervalUnit)) { + range.start.startOf('week'); + range.start = this.skipHiddenDays(range.start); + + // make end-of-week if not already + if (range.end.weekday()) { + range.end.add(1, 'week').startOf('week'); + range.end = this.skipHiddenDays(range.end, -1, true); // exclusively move backwards + } + } + + return range; + }, + + + // Renders the view into `this.el`, which should already be assigned + renderDates: function() { + + this.dayNumbersVisible = this.dayGrid.rowCnt > 1; // TODO: make grid responsible + 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 dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container'); + var dayGridEl = $('
').appendTo(dayGridContainerEl); + this.el.find('.fc-body > tr > td').append(dayGridContainerEl); + + this.dayGrid.setElement(dayGridEl); + this.dayGrid.renderDates(this.hasRigidRows()); + }, + + + // render the day-of-week headers + renderHead: function() { + this.headContainerEl = + this.el.find('.fc-head-container') + .html(this.dayGrid.renderHeadHtml()); + this.headRowEl = this.headContainerEl.find('.fc-row'); + }, + + + // Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering, + // always completely kill the dayGrid's rendering. + unrenderDates: function() { + this.dayGrid.unrenderDates(); + this.dayGrid.removeElement(); + this.scroller.destroy(); + }, + + + renderBusinessHours: function() { + this.dayGrid.renderBusinessHours(); + }, + + + // Builds the HTML skeleton for the view. + // The day-grid component will render inside of a container defined by this HTML. + renderSkeletonHtml: function() { + return '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
'; + }, + + + // Generates an HTML attribute string for setting the width of the week number column, if it is known + weekNumberStyleAttr: function() { + if (this.weekNumberWidth !== null) { + return 'style="width:' + this.weekNumberWidth + 'px"'; + } + return ''; + }, + + + // Determines whether each row should have a constant height + hasRigidRows: function() { + var eventLimit = this.opt('eventLimit'); + return eventLimit && typeof eventLimit !== 'number'; + }, + + + /* Dimensions + ------------------------------------------------------------------------------------------------------------------*/ + + + // Refreshes the horizontal dimensions of the view + updateWidth: function() { + if (this.weekNumbersVisible) { + // Make sure all week number cells running down the side have the same width. + // Record the width for cells created later. + this.weekNumberWidth = matchCellWidths( + this.el.find('.fc-week-number') + ); + } + }, + + + // Adjusts the vertical dimensions of the view to the specified values + setHeight: function(totalHeight, isAuto) { + var eventLimit = this.opt('eventLimit'); + var scrollerHeight; + var scrollbarWidths; + + // reset all heights to be natural + this.scroller.clear(); + uncompensateScroll(this.headRowEl); + + this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed + + // is the event limit a constant level number? + if (eventLimit && typeof eventLimit === 'number') { + this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after + } + + // distribute the height to the rows + // (totalHeight is a "recommended" value if isAuto) + scrollerHeight = this.computeScrollerHeight(totalHeight); + this.setGridHeight(scrollerHeight, isAuto); + + // is the event limit dynamically calculated? + if (eventLimit && typeof eventLimit !== 'number') { + this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set + } + + if (!isAuto) { // should we force dimensions of the scroll container? + + this.scroller.setHeight(scrollerHeight); + scrollbarWidths = this.scroller.getScrollbarWidths(); + + if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? + + compensateScroll(this.headRowEl, scrollbarWidths); + + // doing the scrollbar compensation might have created text overflow which created more height. redo + scrollerHeight = this.computeScrollerHeight(totalHeight); + this.scroller.setHeight(scrollerHeight); + } + + // guarantees the same scrollbar widths + this.scroller.lockOverflow(scrollbarWidths); + } + }, + + + // given a desired total height of the view, returns what the height of the scroller should be + computeScrollerHeight: function(totalHeight) { + return totalHeight - + subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller + }, + + + // Sets the height of just the DayGrid component in this view + setGridHeight: function(height, isAuto) { + if (isAuto) { + undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding + } + else { + distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows + } + }, + + + /* Scroll + ------------------------------------------------------------------------------------------------------------------*/ + + + queryScroll: function() { + return this.scroller.getScrollTop(); + }, + + + setScroll: function(top) { + this.scroller.setScrollTop(top); + }, + + + /* Hit Areas + ------------------------------------------------------------------------------------------------------------------*/ + // forward all hit-related method calls to dayGrid + + + prepareHits: function() { + this.dayGrid.prepareHits(); + }, + + + releaseHits: function() { + this.dayGrid.releaseHits(); + }, + + + queryHit: function(left, top) { + return this.dayGrid.queryHit(left, top); + }, + + + getHitSpan: function(hit) { + return this.dayGrid.getHitSpan(hit); + }, + + + getHitEl: function(hit) { + return this.dayGrid.getHitEl(hit); + }, + + + /* Events + ------------------------------------------------------------------------------------------------------------------*/ + + + // Renders the given events onto the view and populates the segments array + renderEvents: function(events) { + this.dayGrid.renderEvents(events); + + this.updateHeight(); // must compensate for events that overflow the row + }, + + + // Retrieves all segment objects that are rendered in the view + getEventSegs: function() { + return this.dayGrid.getEventSegs(); + }, + + + // Unrenders all event elements and clears internal segment data + unrenderEvents: function() { + this.dayGrid.unrenderEvents(); + + // we DON'T need to call updateHeight() because: + // A) a renderEvents() call always happens after this, which will eventually call updateHeight() + // B) in IE8, this causes a flash whenever events are rerendered + }, + + + /* Dragging (for both events and external elements) + ------------------------------------------------------------------------------------------------------------------*/ + + + // A returned value of `true` signals that a mock "helper" event has been rendered. + renderDrag: function(dropLocation, seg) { + return this.dayGrid.renderDrag(dropLocation, seg); + }, + + + unrenderDrag: function() { + this.dayGrid.unrenderDrag(); + }, + + + /* Selection + ------------------------------------------------------------------------------------------------------------------*/ + + + // Renders a visual indication of a selection + renderSelection: function(span) { + this.dayGrid.renderSelection(span); + }, + + + // Unrenders a visual indications of a selection + unrenderSelection: function() { + this.dayGrid.unrenderSelection(); + } + +}); + + +// Methods that will customize the rendering behavior of the BasicView's dayGrid +var basicDayGridMethods = { + + + // Generates the HTML that will go before the day-of week header cells + renderHeadIntroHtml: function() { + var view = this.view; + + if (view.weekNumbersVisible) { + return '' + + '' + + '' + // needed for matchCellWidths + htmlEscape(view.opt('weekNumberTitle')) + + '' + + ''; + } + + return ''; + }, + + + // Generates the HTML that will go before content-skeleton cells that display the day/week numbers + renderNumberIntroHtml: function(row) { + var view = this.view; + + if (view.weekNumbersVisible) { + return '' + + '' + + '' + // needed for matchCellWidths + this.getCellDate(row, 0).format('w') + + '' + + ''; + } + + return ''; + }, + + + // Generates the HTML that goes before the day bg cells for each day-row + renderBgIntroHtml: function() { + var view = this.view; + + if (view.weekNumbersVisible) { + return ''; + } + + return ''; + }, + + + // Generates the HTML that goes before every other type of row generated by DayGrid. + // Affects helper-skeleton and highlight-skeleton rows. + renderIntroHtml: function() { + var view = this.view; + + if (view.weekNumbersVisible) { + return ''; + } + + return ''; + } + +}; + +;; + +/* A month view with day cells running in rows (one-per-week) and columns +----------------------------------------------------------------------------------------------------------------------*/ + +var MonthView = FC.MonthView = BasicView.extend({ + + // Produces information about what range to display + computeRange: function(date) { + var range = BasicView.prototype.computeRange.call(this, date); // get value from super-method + var rowCnt; + + // ensure 6 weeks + if (this.isFixedWeeks()) { + rowCnt = Math.ceil(range.end.diff(range.start, 'weeks', true)); // could be partial weeks due to hiddenDays + range.end.add(6 - rowCnt, 'weeks'); + } + + return range; + }, + + + // Overrides the default BasicView behavior to have special multi-week auto-height logic + setGridHeight: function(height, isAuto) { + + isAuto = isAuto || this.opt('weekMode') === 'variable'; // LEGACY: weekMode is deprecated + + // if auto, make the height of each row the height that it would be if there were 6 weeks + if (isAuto) { + height *= this.rowCnt / 6; + } + + distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows + }, + + + isFixedWeeks: function() { + var weekMode = this.opt('weekMode'); // LEGACY: weekMode is deprecated + if (weekMode) { + return weekMode === 'fixed'; // if any other type of weekMode, assume NOT fixed + } + + return this.opt('fixedWeekCount'); + } + +}); + +;; + +fcViews.basic = { + 'class': BasicView +}; + +fcViews.basicDay = { + type: 'basic', + duration: { days: 1 } +}; + +fcViews.basicWeek = { + type: 'basic', + duration: { weeks: 1 } +}; + +fcViews.month = { + 'class': MonthView, + duration: { months: 1 }, // important for prev/next + defaults: { + fixedWeekCount: true + } +}; +;; + +/* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically. +----------------------------------------------------------------------------------------------------------------------*/ +// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on). +// Responsible for managing width/height. + +var AgendaView = FC.AgendaView = View.extend({ + + scroller: null, + + timeGridClass: TimeGrid, // class used to instantiate the timeGrid. subclasses can override + timeGrid: null, // the main time-grid subcomponent of this view + + dayGridClass: DayGrid, // class used to instantiate the dayGrid. subclasses can override + dayGrid: null, // the "all-day" subcomponent. if all-day is turned off, this will be null + + axisWidth: null, // the width of the time axis running down the side + + headContainerEl: null, // div that hold's the timeGrid's rendered date header + noScrollRowEls: null, // set of fake row elements that must compensate when scroller has scrollbars + + // when the time-grid isn't tall enough to occupy the given height, we render an
underneath + bottomRuleEl: null, + + + initialize: function() { + this.timeGrid = this.instantiateTimeGrid(); + + if (this.opt('allDaySlot')) { // should we display the "all-day" area? + this.dayGrid = this.instantiateDayGrid(); // the all-day subcomponent of this view + } + + this.scroller = new Scroller({ + overflowX: 'hidden', + overflowY: 'auto' + }); + }, + + + // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass + instantiateTimeGrid: function() { + var subclass = this.timeGridClass.extend(agendaTimeGridMethods); + + return new subclass(this); + }, + + + // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass + instantiateDayGrid: function() { + var subclass = this.dayGridClass.extend(agendaDayGridMethods); + + return new subclass(this); + }, + + + /* Rendering + ------------------------------------------------------------------------------------------------------------------*/ + + + // Sets the display range and computes all necessary dates + setRange: function(range) { + View.prototype.setRange.call(this, range); // call the super-method + + this.timeGrid.setRange(range); + if (this.dayGrid) { + this.dayGrid.setRange(range); + } + }, + + + // Renders the view into `this.el`, which has already been assigned + renderDates: function() { + + this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml()); + this.renderHead(); + + this.scroller.render(); + var timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container'); + var timeGridEl = $('
').appendTo(timeGridWrapEl); + this.el.find('.fc-body > tr > td').append(timeGridWrapEl); + + this.timeGrid.setElement(timeGridEl); + this.timeGrid.renderDates(); + + // the
that sometimes displays under the time-grid + this.bottomRuleEl = $('
') + .appendTo(this.timeGrid.el); // inject it into the time-grid + + if (this.dayGrid) { + this.dayGrid.setElement(this.el.find('.fc-day-grid')); + this.dayGrid.renderDates(); + + // have the day-grid extend it's coordinate area over the
dividing the two grids + this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight(); + } + + this.noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); // fake rows not within the scroller + }, + + + // render the day-of-week headers + renderHead: function() { + this.headContainerEl = + this.el.find('.fc-head-container') + .html(this.timeGrid.renderHeadHtml()); + }, + + + // Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering, + // always completely kill each grid's rendering. + unrenderDates: function() { + this.timeGrid.unrenderDates(); + this.timeGrid.removeElement(); + + if (this.dayGrid) { + this.dayGrid.unrenderDates(); + this.dayGrid.removeElement(); + } + + this.scroller.destroy(); + }, + + + // Builds the HTML skeleton for the view. + // The day-grid and time-grid components will render inside containers defined by this HTML. + renderSkeletonHtml: function() { + return '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' + + (this.dayGrid ? + '
' + + '
' : + '' + ) + + '
'; + }, + + + // Generates an HTML attribute string for setting the width of the axis, if it is known + axisStyleAttr: function() { + if (this.axisWidth !== null) { + return 'style="width:' + this.axisWidth + 'px"'; + } + return ''; + }, + + + /* Business Hours + ------------------------------------------------------------------------------------------------------------------*/ + + + renderBusinessHours: function() { + this.timeGrid.renderBusinessHours(); + + if (this.dayGrid) { + this.dayGrid.renderBusinessHours(); + } + }, + + + unrenderBusinessHours: function() { + this.timeGrid.unrenderBusinessHours(); + + if (this.dayGrid) { + this.dayGrid.unrenderBusinessHours(); + } + }, + + + /* Now Indicator + ------------------------------------------------------------------------------------------------------------------*/ + + + getNowIndicatorUnit: function() { + return this.timeGrid.getNowIndicatorUnit(); + }, + + + renderNowIndicator: function(date) { + this.timeGrid.renderNowIndicator(date); + }, + + + unrenderNowIndicator: function() { + this.timeGrid.unrenderNowIndicator(); + }, + + + /* Dimensions + ------------------------------------------------------------------------------------------------------------------*/ + + + updateSize: function(isResize) { + this.timeGrid.updateSize(isResize); + + View.prototype.updateSize.call(this, isResize); // call the super-method + }, + + + // Refreshes the horizontal dimensions of the view + updateWidth: function() { + // make all axis cells line up, and record the width so newly created axis cells will have it + this.axisWidth = matchCellWidths(this.el.find('.fc-axis')); + }, + + + // Adjusts the vertical dimensions of the view to the specified values + setHeight: function(totalHeight, isAuto) { + var eventLimit; + var scrollerHeight; + var scrollbarWidths; + + // reset all dimensions back to the original state + this.bottomRuleEl.hide(); // .show() will be called later if this
is necessary + this.scroller.clear(); // sets height to 'auto' and clears overflow + uncompensateScroll(this.noScrollRowEls); + + // limit number of events in the all-day area + if (this.dayGrid) { + this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed + + eventLimit = this.opt('eventLimit'); + if (eventLimit && typeof eventLimit !== 'number') { + eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number + } + if (eventLimit) { + this.dayGrid.limitRows(eventLimit); + } + } + + if (!isAuto) { // should we force dimensions of the scroll container? + + scrollerHeight = this.computeScrollerHeight(totalHeight); + this.scroller.setHeight(scrollerHeight); + scrollbarWidths = this.scroller.getScrollbarWidths(); + + if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars? + + // make the all-day and header rows lines up + compensateScroll(this.noScrollRowEls, scrollbarWidths); + + // the scrollbar compensation might have changed text flow, which might affect height, so recalculate + // and reapply the desired height to the scroller. + scrollerHeight = this.computeScrollerHeight(totalHeight); + this.scroller.setHeight(scrollerHeight); + } + + // guarantees the same scrollbar widths + this.scroller.lockOverflow(scrollbarWidths); + + // if there's any space below the slats, show the horizontal rule. + // this won't cause any new overflow, because lockOverflow already called. + if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) { + this.bottomRuleEl.show(); + } + } + }, + + + // given a desired total height of the view, returns what the height of the scroller should be + computeScrollerHeight: function(totalHeight) { + return totalHeight - + subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller + }, + + + /* Scroll + ------------------------------------------------------------------------------------------------------------------*/ + + + // Computes the initial pre-configured scroll state prior to allowing the user to change it + computeInitialScroll: function() { + var scrollTime = moment.duration(this.opt('scrollTime')); + var top = this.timeGrid.computeTimeTop(scrollTime); + + // zoom can give weird floating-point values. rather scroll a little bit further + top = Math.ceil(top); + + if (top) { + top++; // to overcome top border that slots beyond the first have. looks better + } + + return top; + }, + + + queryScroll: function() { + return this.scroller.getScrollTop(); + }, + + + setScroll: function(top) { + this.scroller.setScrollTop(top); + }, + + + /* Hit Areas + ------------------------------------------------------------------------------------------------------------------*/ + // forward all hit-related method calls to the grids (dayGrid might not be defined) + + + prepareHits: function() { + this.timeGrid.prepareHits(); + if (this.dayGrid) { + this.dayGrid.prepareHits(); + } + }, + + + releaseHits: function() { + this.timeGrid.releaseHits(); + if (this.dayGrid) { + this.dayGrid.releaseHits(); + } + }, + + + queryHit: function(left, top) { + var hit = this.timeGrid.queryHit(left, top); + + if (!hit && this.dayGrid) { + hit = this.dayGrid.queryHit(left, top); + } + + return hit; + }, + + + getHitSpan: function(hit) { + // TODO: hit.component is set as a hack to identify where the hit came from + return hit.component.getHitSpan(hit); + }, + + + getHitEl: function(hit) { + // TODO: hit.component is set as a hack to identify where the hit came from + return hit.component.getHitEl(hit); + }, + + + /* Events + ------------------------------------------------------------------------------------------------------------------*/ + + + // Renders events onto the view and populates the View's segment array + renderEvents: function(events) { + var dayEvents = []; + var timedEvents = []; + var daySegs = []; + var timedSegs; + var i; + + // separate the events into all-day and timed + for (i = 0; i < events.length; i++) { + if (events[i].allDay) { + dayEvents.push(events[i]); + } + else { + timedEvents.push(events[i]); + } + } + + // render the events in the subcomponents + timedSegs = this.timeGrid.renderEvents(timedEvents); + if (this.dayGrid) { + daySegs = this.dayGrid.renderEvents(dayEvents); + } + + // the all-day area is flexible and might have a lot of events, so shift the height + this.updateHeight(); + }, + + + // Retrieves all segment objects that are rendered in the view + getEventSegs: function() { + return this.timeGrid.getEventSegs().concat( + this.dayGrid ? this.dayGrid.getEventSegs() : [] + ); + }, + + + // Unrenders all event elements and clears internal segment data + unrenderEvents: function() { + + // unrender the events in the subcomponents + this.timeGrid.unrenderEvents(); + if (this.dayGrid) { + this.dayGrid.unrenderEvents(); + } + + // we DON'T need to call updateHeight() because: + // A) a renderEvents() call always happens after this, which will eventually call updateHeight() + // B) in IE8, this causes a flash whenever events are rerendered + }, + + + /* Dragging (for events and external elements) + ------------------------------------------------------------------------------------------------------------------*/ + + + // A returned value of `true` signals that a mock "helper" event has been rendered. + renderDrag: function(dropLocation, seg) { + if (dropLocation.start.hasTime()) { + return this.timeGrid.renderDrag(dropLocation, seg); + } + else if (this.dayGrid) { + return this.dayGrid.renderDrag(dropLocation, seg); + } + }, + + + unrenderDrag: function() { + this.timeGrid.unrenderDrag(); + if (this.dayGrid) { + this.dayGrid.unrenderDrag(); + } + }, + + + /* Selection + ------------------------------------------------------------------------------------------------------------------*/ + + + // Renders a visual indication of a selection + renderSelection: function(span) { + if (span.start.hasTime() || span.end.hasTime()) { + this.timeGrid.renderSelection(span); + } + else if (this.dayGrid) { + this.dayGrid.renderSelection(span); + } + }, + + + // Unrenders a visual indications of a selection + unrenderSelection: function() { + this.timeGrid.unrenderSelection(); + if (this.dayGrid) { + this.dayGrid.unrenderSelection(); + } + } + +}); + + +// Methods that will customize the rendering behavior of the AgendaView's timeGrid +// TODO: move into TimeGrid +var agendaTimeGridMethods = { + + + // Generates the HTML that will go before the day-of week header cells + renderHeadIntroHtml: function() { + var view = this.view; + var weekText; + + if (view.opt('weekNumbers')) { + weekText = this.start.format(view.opt('smallWeekFormat')); + + return '' + + '' + + '' + // needed for matchCellWidths + htmlEscape(weekText) + + '' + + ''; + } + else { + return ''; + } + }, + + + // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column. + renderBgIntroHtml: function() { + var view = this.view; + + return ''; + }, + + + // Generates the HTML that goes before all other types of cells. + // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. + renderIntroHtml: function() { + var view = this.view; + + return ''; + } + +}; + + +// Methods that will customize the rendering behavior of the AgendaView's dayGrid +var agendaDayGridMethods = { + + + // Generates the HTML that goes before the all-day cells + renderBgIntroHtml: function() { + var view = this.view; + + return '' + + '' + + '' + // needed for matchCellWidths + (view.opt('allDayHtml') || htmlEscape(view.opt('allDayText'))) + + '' + + ''; + }, + + + // Generates the HTML that goes before all other types of cells. + // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid. + renderIntroHtml: function() { + var view = this.view; + + return ''; + } + +}; + +;; + +var AGENDA_ALL_DAY_EVENT_LIMIT = 5; + +// potential nice values for the slot-duration and interval-duration +// from largest to smallest +var AGENDA_STOCK_SUB_DURATIONS = [ + { hours: 1 }, + { minutes: 30 }, + { minutes: 15 }, + { seconds: 30 }, + { seconds: 15 } +]; + +fcViews.agenda = { + 'class': AgendaView, + defaults: { + allDaySlot: true, + allDayText: 'all-day', + slotDuration: '00:30:00', + minTime: '00:00:00', + maxTime: '24:00:00', + slotEventOverlap: true // a bad name. confused with overlap/constraint system + } +}; + +fcViews.agendaDay = { + type: 'agenda', + duration: { days: 1 } +}; + +fcViews.agendaWeek = { + type: 'agenda', + duration: { weeks: 1 } +}; +;; + +return FC; // export for Node/CommonJS +}); \ No newline at end of file diff --git a/public/vendor/fullcalendar/dist/fullcalendar.min.css b/public/vendor/fullcalendar/dist/fullcalendar.min.css new file mode 100644 index 00000000..94120eca --- /dev/null +++ b/public/vendor/fullcalendar/dist/fullcalendar.min.css @@ -0,0 +1,5 @@ +/*! + * FullCalendar v2.7.1 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}.fc-touch .fc-event .fc-resizer{display:none}.fc-touch .fc-event.fc-selected .fc-resizer{display:block}.fc-expander{position:relative}.fc-touch .fc-event .fc-resizer:before,.fc-touch .fc-expander: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-cursor .fc-h-event .fc-resizer{width:7px;top:-1px;bottom:-1px}.fc-touch .fc-h-event .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-touch.fc-ltr .fc-h-event .fc-start-resizer,.fc-touch.fc-rtl .fc-h-event .fc-end-resizer{margin-left:-4px}.fc-touch.fc-ltr .fc-h-event .fc-end-resizer,.fc-touch.fc-rtl .fc-h-event .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-cursor.fc-ltr .fc-day-grid-event .fc-start-resizer,.fc-cursor.fc-rtl .fc-day-grid-event .fc-end-resizer{margin-left:-2px}.fc-cursor.fc-ltr .fc-day-grid-event .fc-end-resizer,.fc-cursor.fc-rtl .fc-day-grid-event .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-cursor .fc-time-grid-event .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-cursor .fc-time-grid-event .fc-resizer:after{content:"="}.fc-touch .fc-time-grid-event .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/public/vendor/fullcalendar/dist/fullcalendar.min.js b/public/vendor/fullcalendar/dist/fullcalendar.min.js new file mode 100644 index 00000000..fe0d597a --- /dev/null +++ b/public/vendor/fullcalendar/dist/fullcalendar.min.js @@ -0,0 +1,2482 @@ +/*! + * FullCalendar v2.7.1 + * Docs & License: http://fullcalendar.io/ + * (c) 2016 Adam Shaw + */ +!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?// Node/CommonJS +module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){ +// Merges an array of option objects into a single object +function c(a){return U(a,Va)} +// Given options specified for the calendar's constructor, massages any legacy options into a non-legacy form. +// Converts View-Option-Hashes into the View-Specific-Options format. +function d(b){var c,d={views:b.views||{}}; +// iterate through all option override properties (except `views`) +return a.each(b,function(b,e){"views"!=b&&( +// could the value be a legacy View-Option-Hash? +a.isPlainObject(e)&&!/(time|duration|interval)$/i.test(b)&&-1==a.inArray(b,Va)?(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}/* FullCalendar-specific DOM Utilities +----------------------------------------------------------------------------------------------------------------------*/ +// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left +// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that. +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})} +// Undoes compensateScroll and restores all borders/margins +function f(a){a.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})} +// Make the mouse cursor express that an event is not allowed in the current area +function g(){a("body").addClass("fc-not-allowed")} +// Returns the mouse cursor to its original look +function h(){a("body").removeClass("fc-not-allowed")} +// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate. +// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering +// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and +// reduces the available height. +function i(b,c,d){ +// *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions, +// and it is better to be shorter than taller, to avoid creating unnecessary scrollbars. +var e=Math.floor(c/b.length),f=Math.floor(c-e*(b.length-1)),g=[],h=[],i=[],k=0;j(b),// give all elements their natural height +// find elements that are below the recommended height (expandable). +// important to query for heights in a single first pass (to avoid reflow oscillation). +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())): +// this element stretches past recommended height (non-expandable). mark the space as occupied. +k+=l}), +// readjust the recommended height to only consider the height available to non-maxed-out rows. +d&&(c-=k,e=Math.floor(c/g.length),f=Math.floor(c-e*(g.length-1))), +// assign heights to all expandable elements +a(g).each(function(b,c){var d=b===g.length-1?f:e,j=h[b],k=i[b],l=d-(j-k);// subtract the margin/padding +d>j&&// we check this again because redistribution might have changed things +a(c).height(l)})} +// Undoes distrubuteHeight, restoring all els to their natural height +function j(a){a.height("")} +// Given `els`, a jQuery set of cells, find the cell with the largest natural width and set the widths of all the +// cells to be that width. +// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline +function k(b){var c=0;// sometimes not accurate of width the text needs to stay on one line. insurance +return b.find("> span").each(function(b,d){var e=a(d).outerWidth();e>c&&(c=e)}),c++,b.width(c),c} +// Given one element that resides inside another, +// Subtracts the height of the inner element from the outer element. +function l(a,b){var c,d=a.add(b);// undo hack +// effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked +// grab the dimensions +return d.css({position:"relative",// cause a reflow, which will force fresh dimension recalculation +left:-1}),c=a.outerHeight()-b.outerHeight(),d.css({position:"",left:""}),c} +// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51 +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)} +// Queries the outer bounding area of a jQuery element. +// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). +// Origin is optional. +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()}} +// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding. +// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). +// Origin is optional. +// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. +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,// clientWidth includes padding but NOT scrollbars +top:f,bottom:f+a[0].clientHeight}} +// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars. +// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive). +// Origin is optional. +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()}} +// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element. +// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser. +function q(a){var b=a.innerWidth()-a[0].clientWidth,c={left:0,right:0,top:0,bottom:a.innerHeight()-a[0].clientHeight};// is the scrollbar on the left side? +return r()&&"rtl"==a.css("direction")?c.left=b:c.right=b,c}function r(){// responsible for caching the computation +return null===Wa&&(Wa=s()),Wa}function s(){// creates an offscreen test element, then removes it +var b=a("
").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;// is the inner div shifted to accommodate a left scrollbar? +return b.remove(),d} +// Retrieves a jQuery element's computed CSS value as a floating-point number. +// If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero. +function t(a,b){return parseFloat(a.css(b))||0} +// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) +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)} +// Stops a mouse/touch event from doing it's native browser action +function z(a){a.preventDefault()} +// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false +function A(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.lefti&&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} +// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time. +// Moments will have their timezones normalized. +function J(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days"),ms:a.time()-c.time()})} +// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations. +function K(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days")})} +// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding. +function L(a,c,d){// returnFloat=true +return b.duration(Math.round(a.diff(c,d,!0)),d)} +// Computes the unit name of the largest whole-unit period of time. +// For example, 48 hours will be "days" whereas 49 hours will be "hours". +// Accepts start/end, a range object, or an original duration object. +function M(a,b){var c,d,e;for(c=0;c=1&&fa(e)));c++);return d} +// Computes the number of units (like "hours") in the given range. +// Range can be a {start,end} object, separate start/end args, or a Duration. +// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling +// of month-diffing logic (which tends to vary from version to version). +function N(a,c,d){return null!=d?d.diff(c,a,!0):b.isDuration(c)?c.as(a):c.end.diff(c.start,a,!0)} +// Intelligently divides a range (specified by a start/end params) by a duration +function O(a,b,c){var d;return R(c)?(b-a)/c:(d=c.asMonths(),Math.abs(d)>=1&&fa(d)?b.diff(a,"months",!0)/d:b.diff(a,"days",!0)/c.asDays())} +// Intelligently divides one duration by another +function P(a,b){var c,d;return R(a)||R(b)?a/b:(c=a.asMonths(),d=b.asMonths(),Math.abs(c)>=1&&fa(c)&&Math.abs(d)>=1&&fa(d)?c/d:a.asDays()/b.asDays())} +// Intelligently multiplies a duration by a number +function Q(a,c){var d;return R(a)?b.duration(a*c):(d=a.asMonths(),Math.abs(d)>=1&&fa(d)?b.duration({months:d*c}):b.duration({days:a.asDays()*c}))} +// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms) +function R(a){return Boolean(a.hours()||a.minutes()||a.seconds()||a.milliseconds())}function S(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date} +// Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00" +function T(a){return/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(a)} +// Merges an array of objects into a single object. +// The second argument allows for an array of property names who's object values will be merged together. +function U(a,b){var c,d,e,f,g,h,i={};if(b)for(c=0;c=0;f--)if(g=a[f][d],"object"==typeof g)e.unshift(g);else if(void 0!==g){i[d]=g;// if there were no objects, this value will be used +break} +// if the trailing values were objects, use the merged value +e.length&&(i[d]=U(e))} +// copy values into the destination, going from last to first +for(c=a.length-1;c>=0;c--){h=a[c];for(d in h)d in i||(// if already assigned by previous props or complex props, don't reassign +i[d]=h[d])}return i} +// Create an object that has the given prototype. Just like Object.create +function V(a){var b=function(){};return b.prototype=a,new b}function W(a,b){for(var c in a)Y(a,c)&&(b[c]=a[c])} +// Copies over certain methods with the same names as Object.prototype methods. Overcomes an IE<=8 bug: +// https://developer.mozilla.org/en-US/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug +function X(a,b){var c,d,e=["constructor","toString","valueOf"];for(c=0;c/g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g,"
")}function ba(a){return a.replace(/&.*?;/g,"")} +// Given a hash of CSS properties, returns a string of CSS. +// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values. +function ca(b){var c=[];return a.each(b,function(a,b){null!=b&&c.push(a+":"+b)}),c.join(";")}function da(a){return a.charAt(0).toUpperCase()+a.slice(1)}function ea(a,b){// for .sort() +return a-b}function fa(a){return a%1===0} +// Returns a method bound to the given object context. +// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with +// different contexts as identical when binding/unbinding events. +function ga(a,b){var c=a[b];return function(){return c.apply(a,arguments)}} +// Returns a function, that, as long as it continues to be invoked, will not +// be triggered. The function will be called after it stops being called for +// N milliseconds. If `immediate` is passed, trigger the function on the +// leading edge, instead of the trailing. +// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714 +function ha(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}} +// Builds an enhanced moment from args. When given an existing moment, it clones. When given a +// native Date, or called with no arguments (the current time), the resulting moment will be local. +// Anything else needs to be "parsed" (a string or an array), and will be affected by: +// parseAsUTC - if there is no zone information, should we parse the input in UTC? +// parseZone - if there is zone information, should we force the zone of the moment? +function ia(c,d,e){var f,g,h,i,j=c[0],k=1==c.length&&"string"==typeof j;// flag for extended functionality +// clone it +// "parsing" is required +// accept strings like '2014-05', but convert to the first of the month +// for when we pass it on to moment's constructor +// no time part? +// arrays have no timezone information, so assume ambiguous zone +// otherwise, probably a string with a format +// let's record the inputted zone somehow +return b.isMoment(j)?(i=b.apply(null,c),ka(j,i)):S(j)||void 0===j?i=b.apply(null,c):(f=!1,g=!1,k?bb.test(j)?(j+="-01",c=[j],f=!0,g=!0):(h=cb.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} +// Misc Internals +// ------------------------------------------------------------------------------------------------- +// given an array of moment-like inputs, return a parallel array w/ moments similarly ambiguated. +// for example, of one moment has ambig time, but not others, all moments will have their time stripped. +// set `preserveTime` to `true` to keep times, but only normalize zone ambiguity. +// returns the original moments if no modifications are necessary. +function ja(a,c){var d,e,f=!1,g=!1,h=a.length,i=[]; +// parse inputs into real moments and query their ambig flags +for(d=0;h>d;d++)e=a[d],b.isMoment(e)||(e=Ta.moment.parseZone(e)),f=f||e._ambigTime,g=g||e._ambigZone,i.push(e); +// strip each moment down to lowest common ambiguity +// use clones to avoid modifying the original moments +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} +// Transfers all the flags related to ambiguous time/zone from the `src` moment to the `dest` moment +// TODO: look into moment.momentProperties for this. +function ka(a,b){a._ambigTime?b._ambigTime=!0:b._ambigTime&&(b._ambigTime=!1),a._ambigZone?b._ambigZone=!0:b._ambigZone&&(b._ambigZone=!1)} +// Sets the year/month/date/etc values of the moment from the given array. +// Inefficient because it calls each individual setter. +function la(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)} +// Single Date Formatting +// ------------------------------------------------------------------------------------------------- +// call this if you want Moment's original format method to be used +function ma(a,b){return eb.format.call(a,b)} +// Formats `date` with a Moment formatting string, but allow our non-zero areas and +// additional token. +function na(a,b){return oa(a,ta(b))}function oa(a,b){var c,d="";for(c=0;c "MMMM D YYYY" +// BTW, this is not important for `formatDate` because it is impossible to put custom tokens +// or non-zero areas in Moment's localized format strings. +return a=Ta.moment.parseZone(a),b=Ta.moment.parseZone(b),f=(a.localeData||a.lang).call(a),c=f.longDateFormat(c)||c,d=d||" - ",ra(a,b,ta(c),d,e)}// expose +function ra(a,b,c,d,e){var f,g,h,i,j=a.clone().stripZone(),k=b.clone().stripZone(),l="",m="",n="",o="",p=""; +// Start at the leftmost side of the formatting string and continue until you hit a token +// that is not the same between dates. +for(g=0;gg&&(f=sa(a,b,j,k,c[h]),f!==!1);h--)m=f+m; +// The area in the middle is different for both of the dates. +// Collect them distinctly so we can jam them together later. +for(i=g;h>=i;i++)n+=pa(a,c[i]),o+=pa(b,c[i]);return(n||o)&&(p=e?o+d+n:n+d+o),l+p+m} +// TODO: week maybe? +// Given a formatting chunk, and given that both dates are similar in the regard the +// formatting chunk is concerned, format date1 against `chunk`. Otherwise, return `false`. +function sa(a,b,c,d,e){var f,g;return"string"==typeof e?e:(f=e.token)&&(g=gb[f.charAt(0)],g&&c.isSame(d,g))?ma(a,f):!1}function ta(a){return a in hb?hb[a]:hb[a]=ua(a)} +// Break the formatting string into an array of chunks +function ua(a){for(var b,c=[],d=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;b=d.exec(a);)b[1]?// a literal string inside [ ... ] +c.push(b[1]):b[2]?// non-zero formatting inside ( ... ) +c.push({maybe:ua(b[2])}):b[3]?// a formatting token +c.push({token:b[3]}):b[5]&&// an unenclosed literal string +c.push(b[5]);return c}// export +// Class that all other classes will inherit from +function va(){}function wa(a,b){var c; +// ensure a constructor for the subclass, forwarding all arguments to the super-constructor if it doesn't exist +// build the base prototype for the subclass, which is an new object chained to the superclass's prototype +// copy each member variable/method onto the the subclass's prototype +// hack for IE8 +// copy over all class variables/methods to the subclass, such as `extend` and `mixin` +return Y(b,"constructor")&&(c=b.constructor),"function"!=typeof c&&(c=b.constructor=function(){a.apply(this,arguments)}),c.prototype=V(a.prototype),W(b,c.prototype),X(b,c.prototype),W(a,c),c}function xa(a,b){W(b,a.prototype)} +// Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component. +// Two null values will be considered equal, as two "out of the component" states are the same. +function ya(a,b){return a||b?a&&b?a.component===b.component&&za(a,b)&&za(b,a):!1:!0} +// Returns true if all of subHit's non-standard properties are within superHit +function za(a,b){for(var c in a)if(!/^(component|left|right|top|bottom)$/.test(c)&&a[c]!==b[c])return!1;return!0}/* Utilities +----------------------------------------------------------------------------------------------------------------------*/ +function Aa(a){// returns true if background OR inverse-background +var b=Ca(a);return"background"===b||"inverse-background"===b}// export +function Ba(a){return"inverse-background"===Ca(a)}function Ca(a){return _((a.source||{}).rendering,a.rendering)}function Da(a){var b,c,d={};for(b=0;b=a.leftCol)return!0;return!1} +// A cmp function for determining the leftmost event +function Ha(a,b){return a.leftCol-b.leftCol} +// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is +// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. +function Ia(a){var b,c,d,e=[];for(b=0;bb.top&&a.top").prependTo(c),R=N.header=new Qa(N,O),S=R.render(),S&&c.prepend(S),i(O.defaultView),O.handleWindowResize&&(Y=ha(m,O.windowResizeDelay),a(window).resize(Y))}function g(){W&&W.removeElement(),R.removeElement(),T.remove(),c.removeClass("fc fc-touch fc-cursor fc-ltr fc-rtl fc-unthemed ui-widget"),Y&&a(window).unbind("resize",Y)}function h(){return c.is(":visible")} +// View Rendering +// ----------------------------------------------------------------------------------- +// Renders a view because of a date change, view-type change, or for the first time. +// If not given a viewType, keep the current view but render different dates. +function i(b){ca++, +// if viewType is changing, remove the old view's rendering +W&&b&&W.type!==b&&(R.deactivateButton(W.type),H(),// prevent a scroll jump when view element is removed +W.removeElement(),W=N.view=null), +// if viewType changed, or the view was never created, create a fresh view +!W&&b&&(W=N.view=ba[b]||(ba[b]=N.instantiateView(b)),W.setElement(a("
").appendTo(T)),R.activateButton(b)),W&&(Z=W.massageCurrentDate(Z),W.displaying&&Z.isWithin(W.intervalStart,W.intervalEnd)||h()&&(W.display(Z),I(),u(),v(),q())),I(),// undo any lone freezeContentHeight calls +ca--}function j(a){// isResize=true. will poll getSuggestedViewHeight() and isHeightAuto() +return h()?(a&&l(),ca++,W.updateSize(!0),ca--,!0):void 0}function k(){h()&&l()}function l(){// assumes elementVisible +X="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&&W.start&&j(!0)&&W.trigger("windowResize",aa)}/* Event Fetching/Rendering + -----------------------------------------------------------------------------*/ +// TODO: going forward, most of this stuff should be directly handled by the view +function n(){// can be called as an API method +p(),// so that events are cleared before user starts waiting for AJAX +r()}function o(){// destroys old events if previously rendered +h()&&(H(),W.displayEvents(da),I())}function p(){H(),W.clearEvents(),I()}function q(){!O.lazyFetching||$(W.start,W.end)?r():o()}function r(){_(W.start,W.end)} +// called when event data arrives +function s(a){da=a,o()} +// called when a single event's data has been changed +function t(){o()}/* Header Updating + -----------------------------------------------------------------------------*/ +function u(){R.updateTitle(W.title)}function v(){var a=N.getNow();a.isWithin(W.intervalStart,W.intervalEnd)?R.disableButton("today"):R.enableButton("today")}/* Selection + -----------------------------------------------------------------------------*/ +// this public method receives start/end dates in any format, with any timezone +function w(a,b){W.select(N.buildSelectSpan.apply(N,arguments))}function x(){// safe to be called before renderView +W&&W.unselect()}/* Date + -----------------------------------------------------------------------------*/ +function y(){Z=W.computePrevDate(Z),i()}function z(){Z=W.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()} +// Forces navigation to a view for the given date. +// `viewType` can be a specific view name or a generic one like "week" or "day". +function F(a,b){var c;b=b||"day",c=N.getViewSpec(b)||N.getUnitViewSpec(b),Z=a.clone(),i(c?c.type:null)} +// for external API +function G(){return N.applyTimezone(Z)}function H(){T.css({width:"100%",height:T.height(),overflow:"hidden"})}function I(){T.css({width:"",height:"",overflow:""})}/* Misc + -----------------------------------------------------------------------------*/ +function J(){return N}function K(){return W}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){// overrides the Emitter's trigger method :( +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; +// Exports +// ----------------------------------------------------------------------------------- +N.render=e,N.destroy=g,N.refetchEvents=n,N.reportEvents=s,N.reportEventChange=t,N.rerenderEvents=o,// `renderEvents` serves as a rerender. an API method +N.changeView=i,// `renderView` will switch to another view +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; +// Language-data Internals +// ----------------------------------------------------------------------------------- +// Apply overrides to the current language's data +var P=V(// make a cheap copy +Pa(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=V(P._week);// _week: { dow: # } +Q.dow=O.firstDay,P._week=Q} +// assign a normalized value, to be used by our .week() moment extension +P._fullCalendar_weekCalc=function(a){return"function"==typeof a?a:"local"===a?a:"iso"===a||"ISO"===a?"ISO":void 0}(O.weekNumberCalculation), +// Calendar-specific Date Utilities +// ----------------------------------------------------------------------------------- +N.defaultAllDayEventDuration=b.duration(O.defaultAllDayEventDuration),N.defaultTimedEventDuration=b.duration(O.defaultTimedEventDuration), +// Builds a moment using the settings of the current calendar: timezone and language. +// Accepts anything the vanilla moment() constructor accepts. +N.moment=function(){var a; +// Force the moment to be local, because FC.moment doesn't guarantee it. +// don't give ambiguously-timed moments a local zone +// moment 2.8 and above +// pre-moment-2.8 +return"local"===O.timezone?(a=Ta.moment.apply(null,arguments),a.hasTime()&&a.local()):a="UTC"===O.timezone?Ta.moment.utc.apply(null,arguments):Ta.moment.parseZone.apply(null,arguments),"_locale"in a?a._locale=P:a._lang=P,a}, +// Returns a boolean about whether or not the calendar knows how to calculate +// the timezone offset of arbitrary dates in the current timezone. +N.getIsAmbigTimezone=function(){return"local"!==O.timezone&&"UTC"!==O.timezone}, +// Returns a copy of the given date in the current timezone. Has no effect on dates without times. +N.applyTimezone=function(a){if(!a.hasTime())return a.clone();var b,c=N.moment(a.toArray()),d=a.time()-c.time(); +// Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396) +// is the time result different than expected? +// add milliseconds +// does it match perfectly now? +return d&&(b=c.clone().add(d),a.time()-b.time()===0&&(c=b)),c}, +// Returns a moment for the current date, as defined by the client's computer or from the `now` option. +// Will return an moment with an ambiguous timezone. +N.getNow=function(){var a=O.now;return"function"==typeof a&&(a=a()),N.moment(a).stripZone()}, +// Get an event's normalized end date. If not present, calculate it from the defaults. +N.getEventEnd=function(a){return a.end?a.end.clone():N.getDefaultEventEnd(a.allDay,a.start)}, +// Given an event's allDay status and start date, return what its fallback end date should be. +// TODO: rename to computeDefaultEventEnd +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}, +// Produces a human-readable string for the given duration. +// Side-effect: changes the locale of the given duration. +N.humanizeDuration=function(a){return(a.locale||a.lang).call(a,O.lang).humanize()}, +// Imports +// ----------------------------------------------------------------------------------- +Ra.call(N,O);var R,S,T,U,W,X,Y,Z,$=N.isFetchNeeded,_=N.fetchEvents,aa=c[0],ba={},ca=0,da=[];// unzoned +// Main Rendering +// ----------------------------------------------------------------------------------- +// compute the initial ambig-timezone date +Z=null!=O.defaultDate?N.moment(O.defaultDate).stripZone():N.getNow(),N.getSuggestedViewHeight=function(){return void 0===X&&k(),X},N.isHeightAuto=function(){return"auto"===O.contentHeight||"auto"===O.height},N.freezeContentHeight=H,N.unfreezeContentHeight=I,N.initialize()}function Oa(b){a.each(zb,function(a,c){null==b[a]&&(b[a]=c(b))})} +// Returns moment's internal locale data. If doesn't exist, returns English. +// Works with moment-pre-2.8 +function Pa(a){var c=b.localeData||b.langData;return c.call(b,a)||c.call(b,"en")}/* Top toolbar area with buttons and title +----------------------------------------------------------------------------------------------------------------------*/ +// TODO: rename all header-related things to "toolbar" +function Qa(b,c){function d(){var b=c.header;return n=c.theme?"ui":"fc",b?o=a("
").append(f("left")).append(f("right")).append(f("center")).append('
'):void 0}function e(){o.remove(),o=a()}function f(d){var e=a('
'),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;// the element +"title"==e?(g=g.add(a("

 

")),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?aa(k):m&&c.theme?"":o&&!c.theme?"":aa(l),r=["fc-"+e+"-button",n+"-button",n+"-state-default"],s=a('").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("
"),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; +// exports +m.render=d,m.removeElement=e,m.updateTitle=g,m.activateButton=h,m.deactivateButton=i,m.disableButton=j,m.enableButton=k,m.getViewsWithButtons=l; +// locals +var n,o=a(),p=[]}function Ra(c){/* Fetching + -----------------------------------------------------------------------------*/ +// start and end are assumed to be unzoned +function d(a,b){// nothing has been fetched yet? +return!I||I>a||b>M}function e(a,b){I=a,M=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=c&&b.end<=d} +// Does the event's date range intersect with the given range? +// start/end already assumed to have stripped zones :( +function G(a,b){var c=a.start.clone().stripZone(),d=H.getEventEnd(a).stripZone();return b.startc}// assumed to be a calendar +var H=this; +// exports +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; +// imports +var I,M,N=H.reportEvents,O={events:[]},P=[O],Q=0,R=0,S=[];// holds events that have already been expanded +a.each((c.events?[c.events]:[]).concat(c.eventSources||[]),function(a,b){var c=i(b);c&&P.push(c)}),/* Business Hours + -----------------------------------------------------------------------------------------*/ +H.getBusinessHoursEvents=z,/* Overlapping / Constraining + -----------------------------------------------------------------------------------------*/ +H.isEventSpanAllowed=A,H.isExternalSpanAllowed=B,H.isSelectionSpanAllowed=C,H.getEventCache=function(){return S}} +// updates the "backup" properties, which are preserved in order to compute diffs later on. +function Sa(a){a._allDay=a.allDay,a._start=a.start.clone(),a._end=a.end?a.end.clone():null}var Ta=a.fullCalendar={version:"2.7.1",internalApiVersion:3},Ua=Ta.views={};Ta.isTouch="ontouchstart"in document,a.fn.fullCalendar=function(b){var c=Array.prototype.slice.call(arguments,1),d=this;// what this function will return (this jQuery object by default) +return this.each(function(e,f){// loop each DOM element involved +var g,h=a(f),i=h.data("fullCalendar");// the returned value of this single method call +// a method call +"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 vb(h,b),h.data("fullCalendar",i),i.render())}),d};var Va=[// names of options that are objects whose properties should be combined +"header","buttonText","buttonIcons","themeButtonIcons"]; +// exports +Ta.intersectRanges=I,Ta.applyAll=$,Ta.debounce=ha,Ta.isInt=fa,Ta.htmlEscape=aa,Ta.cssToStr=ca,Ta.proxy=ga,Ta.capitaliseFirstLetter=da,/* Element Geom Utilities +----------------------------------------------------------------------------------------------------------------------*/ +Ta.getOuterRect=n,Ta.getClientRect=o,Ta.getContentRect=p,Ta.getScrollbarWidths=q; +// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side +var Wa=null;/* Mouse / Touch Utilities +----------------------------------------------------------------------------------------------------------------------*/ +Ta.preventDefault=z,/* General Geometry Utils +----------------------------------------------------------------------------------------------------------------------*/ +Ta.intersectRects=A,/* Object Ordering by Field +----------------------------------------------------------------------------------------------------------------------*/ +Ta.parseFieldSpecs=E,Ta.compareByFieldSpecs=F,Ta.compareByFieldSpec=G,Ta.flexibleCompare=H,/* Date Utilities +----------------------------------------------------------------------------------------------------------------------*/ +Ta.computeIntervalUnit=M,Ta.divideRangeByDuration=O,Ta.divideDurationByDuration=P,Ta.multiplyDuration=Q,Ta.durationHasTime=R;var Xa=["sun","mon","tue","wed","thu","fri","sat"],Ya=["year","month","week","day","hour","minute","second","millisecond"];/* Logging and Debug +----------------------------------------------------------------------------------------------------------------------*/ +Ta.log=function(){var a=window.console;return a&&a.log?a.log.apply(a,arguments):void 0},Ta.warn=function(){var a=window.console;return a&&a.warn?a.warn.apply(a,arguments):Ta.log.apply(Ta,arguments)};/* General Utilities +----------------------------------------------------------------------------------------------------------------------*/ +var Za,$a,_a,ab={}.hasOwnProperty,bb=/^\s*\d{4}-\d\d$/,cb=/^\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+)?)?)?)?)?$/,db=b.fn,eb=a.extend({},db);// function defined below +// Creating +// ------------------------------------------------------------------------------------------------- +// Creates a new moment, similar to the vanilla moment(...) constructor, but with +// extra features (ambiguous time, enhanced formatting). When given an existing moment, +// it will function as a clone (and retain the zone of the moment). Anything else will +// result in a moment in the local zone. +Ta.moment=function(){return ia(arguments)}, +// Sames as FC.moment, but forces the resulting moment to be in the UTC timezone. +Ta.moment.utc=function(){var a=ia(arguments,!0); +// Force it into UTC because makeMoment doesn't guarantee it +// (if given a pre-existing moment for example) +// don't give ambiguously-timed moments a UTC zone +return a.hasTime()&&a.utc(),a}, +// Same as FC.moment, but when given an ISO8601 string, the timezone offset is preserved. +// ISO8601 strings with no timezone offset will become ambiguously zoned. +Ta.moment.parseZone=function(){return ia(arguments,!0,!0)}, +// A clone method that works with the flags related to our enhanced functionality. +// In the future, use moment.momentProperties +db.clone=function(){var a=eb.clone.apply(this,arguments); +// these flags weren't transfered with the clone +return ka(this,a),this._fullCalendar&&(a._fullCalendar=!0),a}, +// Week Number +// ------------------------------------------------------------------------------------------------- +// Returns the week number, considering the locale's custom week number calcuation +// `weeks` is an alias for `week` +db.week=db.weeks=function(a){var b=(this._locale||this._lang)._fullCalendar_weekCalc;return null==a&&"function"==typeof b?b(this):"ISO"===b?eb.isoWeek.apply(this,arguments):eb.week.apply(this,arguments)}, +// Time-of-day +// ------------------------------------------------------------------------------------------------- +// GETTER +// Returns a Duration with the hours/minutes/seconds/ms values of the moment. +// If the moment has an ambiguous time, a duration of 00:00 will be returned. +// +// SETTER +// You can supply a Duration, a Moment, or a Duration-like argument. +// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous. +db.time=function(a){ +// Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar. +// `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins. +if(!this._fullCalendar)return eb.time.apply(this,arguments);if(null==a)// getter +return b.duration({hours:this.hours(),minutes:this.minutes(),seconds:this.seconds(),milliseconds:this.milliseconds()});// setter +this._ambigTime=!1,// mark that the moment now has a time +b.isDuration(a)||b.isMoment(a)||(a=b.duration(a)); +// The day value should cause overflow (so 24 hours becomes 00:00:00 of next day). +// Only for Duration times, not Moment times. +var c=0; +// We need to set the individual fields. +// Can't use startOf('day') then add duration. In case of DST at start of day. +return b.isDuration(a)&&(c=24*Math.floor(a.asDays())),this.hours(c+a.hours()).minutes(a.minutes()).seconds(a.seconds()).milliseconds(a.milliseconds())}, +// Converts the moment to UTC, stripping out its time-of-day and timezone offset, +// but preserving its YMD. A moment with a stripped time will display no time +// nor timezone offset when .format() is called. +db.stripTime=function(){var a; +// get the values before any conversion happens +// array of y/m/d/h/m/s/ms +// TODO: use keepLocalTime in the future +// set the internal UTC flag (will clear the ambig flags) +// set the year/month/date. time will be zero +// Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), +// which clears all ambig flags. Same with setUTCValues with moment-timezone. +return this._ambigTime||(a=this.toArray(),this.utc(),$a(this,a.slice(0,3)),this._ambigTime=!0,this._ambigZone=!0),this}, +// Returns if the moment has a non-ambiguous time (boolean) +db.hasTime=function(){return!this._ambigTime}, +// Timezone +// ------------------------------------------------------------------------------------------------- +// Converts the moment to UTC, stripping out its timezone offset, but preserving its +// YMD and time-of-day. A moment with a stripped timezone offset will display no +// timezone offset when .format() is called. +// TODO: look into Moment's keepLocalTime functionality +db.stripZone=function(){var a,b; +// get the values before any conversion happens +// array of y/m/d/h/m/s/ms +// set the internal UTC flag (might clear the ambig flags, depending on Moment internals) +// will set the year/month/date/hours/minutes/seconds/ms +// the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore +// Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(), +// which clears the ambig flags. Same with setUTCValues with moment-timezone. +return this._ambigZone||(a=this.toArray(),b=this._ambigTime,this.utc(),$a(this,a),this._ambigTime=b||!1,this._ambigZone=!0),this}, +// Returns of the moment has a non-ambiguous timezone offset (boolean) +db.hasZone=function(){return!this._ambigZone}, +// this method implicitly marks a zone +db.local=function(){var a=this.toArray(),b=this._ambigZone; +// ensure non-ambiguous +// this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals +// If the moment was ambiguously zoned, the date fields were stored as UTC. +// We want to preserve these, but in local time. +// TODO: look into Moment's keepLocalTime functionality +return eb.local.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,b&&_a(this,a),this}, +// implicitly marks a zone +db.utc=function(){ +// ensure non-ambiguous +// this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals +return eb.utc.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,this}, +// methods for arbitrarily manipulating timezone offset. +// should clear time/zone ambiguity when called. +a.each(["zone",// only in moment-pre-2.9. deprecated afterwards +"utcOffset"],function(a,b){eb[b]&&(// original method exists? +// this method implicitly marks a zone (will probably get called upon .utc() and .local()) +db[b]=function(a){// setter +// these assignments needs to happen before the original zone method is called. +// I forget why, something to do with a browser crash. +return null!=a&&(this._ambigTime=!1,this._ambigZone=!1),eb[b].apply(this,arguments)})}), +// Formatting +// ------------------------------------------------------------------------------------------------- +db.format=function(){return this._fullCalendar&&arguments[0]?na(this,arguments[0]):this._ambigTime?ma(this,"YYYY-MM-DD"):this._ambigZone?ma(this,"YYYY-MM-DD[T]HH:mm:ss"):eb.format.apply(this,arguments)},db.toISOString=function(){return this._ambigTime?ma(this,"YYYY-MM-DD"):this._ambigZone?ma(this,"YYYY-MM-DD[T]HH:mm:ss"):eb.toISOString.apply(this,arguments)}, +// Querying +// ------------------------------------------------------------------------------------------------- +// Is the moment within the specified range? `end` is exclusive. +// FYI, this method is not a standard Moment method, so always do our enhanced logic. +db.isWithin=function(a,b){var c=ja([this,a,b]);return c[0]>=c[1]&&c[0]a;a++)b=arguments[a],c-1>a&&xa(this,b);return wa(this,b||{})}, +// Adds new member variables/methods to the class's prototype. +// Can be called with another class, or a plain object hash containing new members. +va.mixin=function(a){xa(this,a)};var ib=Ta.EmitterMixin={callbackHash:null,on:function(a,b){return this.loopCallbacks(a,"add",[b]),this},off:function(a,b){return this.loopCallbacks(a,"remove",[b]),this},trigger:function(a){// args... +var b=Array.prototype.slice.call(arguments,1);return this.triggerWith(a,this,b),this},triggerWith:function(a,b,c){return this.loopCallbacks(a,"fireWith",[b,c]),this},/* + Given an event name string with possible namespaces, + call the given methodName on all the internal Callback object with the given arguments. + */ +loopCallbacks:function(a,b,c){var d,e,f,g=a.split(".");for(d=0;d').addClass(c.className||"").css({ +// position initially to the top left to avoid creating scrollbars +top:0,left:0}).append(c.content).appendTo(c.parentEl), +// when a click happens on anything inside with a 'fc-close' className, hide the popover +this.el.on("click",".fc-close",function(){b.hide()}),c.autoHide&&this.listenTo(a(document),"mousedown",this.documentMousedown)}, +// Triggered when the user clicks *anywhere* in the document, for the autoHide feature +documentMousedown:function(b){ +// only hide the popover if the click happened outside the popover +this.el&&!a(b.target).closest(this.el).length&&this.hide()}, +// Hides and unregisters any handlers +removeElement:function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(a(document),"mousedown")}, +// Positions the popover optimally, using the top/left/right options +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})}, +// Triggers a callback. Calls a function in the option hash of the same name. +// Arguments beyond the first `name` are forwarded on. +// TODO: better code reuse for this. Repeat code +trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1))}}),lb=Ta.CoordCache=va.extend({els:null,// jQuery set (assumed to be siblings) +forcedOffsetParentEl:null,// options can override the natural offsetParent +origin:null,// {left,top} position of offsetParent of els +boundingRect:null,// constrain cordinates to this rectangle. {left,right,top,bottom} or null +isHorizontal:!1,// whether to query for left/right/width +isVertical:!1,// whether to query for top/bottom/height +// arrays of coordinates (offsets from topleft of document) +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}, +// Queries the els for coordinates and stores them. +// Call this method before using and of the get* methods below. +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()}, +// Destroys all internal data about coordinates, freeing memory +clear:function(){this.origin=null,this.boundingRect=null,this.lefts=null,this.rights=null,this.tops=null,this.bottoms=null}, +// When called, if coord caches aren't built, builds them +ensureBuilt:function(){this.origin||this.build()}, +// Compute and return what the elements' bounding rectangle is, from the user's perspective. +// Right now, only returns a rectangle if constrained by an overflow:scroll element. +queryBoundingRect:function(){var a=m(this.els.eq(0));return a.is(document)?void 0:o(a)}, +// Populates the left/right internal coordinate arrays +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}, +// Populates the top/bottom internal coordinate arrays +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}, +// Given a left offset (from document left), returns the index of the el that it horizontally intersects. +// If no intersection is made, or outside of the boundingRect, returns undefined. +getHorizontalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.lefts,e=this.rights,f=d.length;if(!c||a>=c.left&&ab;b++)if(a>=d[b]&&a=c.top&&ab;b++)if(a>=d[b]&&a=e*e&&this.handleDistanceSurpassed(a)),this.isDragging&&this.handleDrag(c,d,a)}, +// Called while the mouse is being moved and when we know a legitimate drag is taking place +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()}, +// Delay +// ----------------------------------------------------------------------------------------------------------------- +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)}, +// Distance +// ----------------------------------------------------------------------------------------------------------------- +handleDistanceSurpassed:function(a){this.isDistanceSurpassed=!0,this.isDelayEnded&&this.startDrag(a)}, +// Mouse / Touch +// ----------------------------------------------------------------------------------------------------------------- +handleTouchMove:function(a){ +// prevent inertia and touchmove-scrolling while dragging +this.isDragging&&a.preventDefault(),this.handleMove(a)},handleMouseMove:function(a){this.handleMove(a)}, +// Scrolling (unrelated to auto-scroll) +// ----------------------------------------------------------------------------------------------------------------- +handleTouchScroll:function(a){ +// if the drag is being initiated by touch, but a scroll happens before +// the drag-initiating delay is over, cancel the drag +this.isDragging||this.endInteraction(a)}, +// HREF Hack +// ----------------------------------------------------------------------------------------------------------------- +initHrefHack:function(){var a=this.subjectEl; +// remove a mousedown'd 's href so it is not visited (IE8 bug) +(this.subjectHref=a?a.attr("href"):null)&&a.removeAttr("href")},destroyHrefHack:function(){var a=this.subjectEl,b=this.subjectHref; +// restore a mousedown'd 's href (for IE8 bug) +setTimeout(function(){// must be outside of the click's execution +b&&a.attr("href",b)},0)}, +// Utils +// ----------------------------------------------------------------------------------------------------------------- +// Triggers a callback. Calls a function in the option hash of the same name. +// Arguments beyond the first `name` are forwarded on. +trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1)), +// makes _methods callable by event name. TODO: kill this +this["_"+a]&&this["_"+a].apply(this,Array.prototype.slice.call(arguments,1))}});/* +this.scrollEl is set in DragListener +*/ +mb.mixin({isAutoScroll:!1,scrollBounds:null,// { top, bottom, left, right } +scrollTopVel:null,// pixels per second +scrollLeftVel:null,// pixels per second +scrollIntervalId:null,// ID of setTimeout for scrolling animation loop +// defaults +scrollSensitivity:30,// pixels from edge for scrolling to start +scrollSpeed:200,// pixels per second, at maximum speed +scrollIntervalMs:50,// millisecond wait between scroll increment +initAutoScroll:function(){var a=this.scrollEl;this.isAutoScroll=this.options.scroll&&a&&!a.is(window)&&!a.is(document),this.isAutoScroll&& +// debounce makes sure rapid calls don't happen +this.listenTo(a,"scroll",ha(this.handleDebouncedScroll,100))},destroyAutoScroll:function(){this.endAutoScroll(),// kill any animation loop +// remove the scroll handler if there is a scrollEl +this.isAutoScroll&&this.stopListeningTo(this.scrollEl,"scroll")}, +// Computes and stores the bounding rectangle of scrollEl +computeScrollBounds:function(){this.isAutoScroll&&(this.scrollBounds=n(this.scrollEl))}, +// Called when the dragging is in progress and scrolling should be updated +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)}, +// Sets the speed-of-scrolling for the scrollEl +setScrollVel:function(a,b){this.scrollTopVel=a,this.scrollLeftVel=b,this.constrainScrollVel(),// massages into realistic values +// if there is non-zero velocity, and an animation loop hasn't already started, then START +!this.scrollTopVel&&!this.scrollLeftVel||this.scrollIntervalId||(this.scrollIntervalId=setInterval(ga(this,"scrollIntervalFunc"),// scope to `this` +this.scrollIntervalMs))}, +// Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way +constrainScrollVel:function(){var a=this.scrollEl;this.scrollTopVel<0?// scrolling up? +a.scrollTop()<=0&&(// already scrolled all the way up? +this.scrollTopVel=0):this.scrollTopVel>0&&a.scrollTop()+a[0].clientHeight>=a[0].scrollHeight&&(// already scrolled all the way down? +this.scrollTopVel=0),this.scrollLeftVel<0?// scrolling left? +a.scrollLeft()<=0&&(// already scrolled all the left? +this.scrollLeftVel=0):this.scrollLeftVel>0&&a.scrollLeft()+a[0].clientWidth>=a[0].scrollWidth&&(// already scrolled all the way right? +this.scrollLeftVel=0)}, +// This function gets called during every iteration of the scrolling animation loop +scrollIntervalFunc:function(){var a=this.scrollEl,b=this.scrollIntervalMs/1e3;// considering animation frequency, what the vel should be mult'd by +// change the value of scrollEl's scroll +this.scrollTopVel&&a.scrollTop(a.scrollTop()+this.scrollTopVel*b),this.scrollLeftVel&&a.scrollLeft(a.scrollLeft()+this.scrollLeftVel*b),this.constrainScrollVel(),// since the scroll values changed, recompute the velocities +// if scrolled all the way, which causes the vels to be zero, stop the animation loop +this.scrollTopVel||this.scrollLeftVel||this.endAutoScroll()}, +// Kills any existing scrolling animation loop +endAutoScroll:function(){this.scrollIntervalId&&(clearInterval(this.scrollIntervalId),this.scrollIntervalId=null,this.handleScrollEnd())}, +// Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce) +handleDebouncedScroll:function(){ +// recompute all coordinates, but *only* if this is *not* part of our scrolling animation +this.scrollIntervalId||this.handleScrollEnd()}, +// Called when scrolling has stopped, whether through auto scroll, or the user scrolling +handleScrollEnd:function(){}});/* Tracks mouse movements over a component and raises events about which hit the mouse is over. +------------------------------------------------------------------------------------------------------------------------ +options: +- subjectEl +- subjectCenter +*/ +var nb=mb.extend({component:null,// converts coordinates to hits +// methods: prepareHits, releaseHits, queryHit +origHit:null,// the hit the mouse was over when listening started +hit:null,// the hit the mouse is over +coordAdjust:null,// delta that will be added to the mouse coordinates when computing collisions +constructor:function(a,b){mb.call(this,b),// call the super-constructor +this.component=a}, +// Called when drag listening starts (but a real drag has not necessarily began). +// ev might be undefined if dragging was started manually. +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=B(d,b)),this.origHit=this.queryHit(d.left,d.top),e&&this.options.subjectCenter&&(this.origHit&&(b=A(this.origHit,b)||b),d=C(b)),this.coordAdjust=D(d,c)):(this.origHit=null,this.coordAdjust=null), +// call the super-method. do it after origHit has been computed +mb.prototype.handleInteractionStart.apply(this,arguments)}, +// Recomputes the drag-critical positions of elements +computeCoords:function(){this.component.prepareHits(),this.computeScrollBounds()}, +// Called when the actual drag has started +handleDragStart:function(a){var b;mb.prototype.handleDragStart.apply(this,arguments),b=this.queryHit(v(a),w(a)),b&&this.handleHitOver(b)}, +// Called when the drag moves +handleDrag:function(a,b,c){var d;mb.prototype.handleDrag.apply(this,arguments),d=this.queryHit(v(c),w(c)),ya(d,this.hit)||(this.hit&&this.handleHitOut(),d&&this.handleHitOver(d))}, +// Called when dragging has been stopped +handleDragEnd:function(){this.handleHitDone(),mb.prototype.handleDragEnd.apply(this,arguments)}, +// Called when a the mouse has just moved over a new hit +handleHitOver:function(a){var b=ya(a,this.origHit);this.hit=a,this.trigger("hitOver",this.hit,b,this.origHit)}, +// Called when the mouse has just moved out of a hit +handleHitOut:function(){this.hit&&(this.trigger("hitOut",this.hit),this.handleHitDone(),this.hit=null)}, +// Called after a hitOut. Also called before a dragStop +handleHitDone:function(){this.hit&&this.trigger("hitDone",this.hit)}, +// Called when the interaction ends, whether there was a real drag or not +handleInteractionEnd:function(){mb.prototype.handleInteractionEnd.apply(this,arguments),// call the super-method +this.origHit=null,this.hit=null,this.component.releaseHits()}, +// Called when scrolling has stopped, whether through auto scroll, or the user scrolling +handleScrollEnd:function(){mb.prototype.handleScrollEnd.apply(this,arguments),// call the super-method +this.computeCoords()}, +// Gets the hit underneath the coordinates for the given mouse event +queryHit:function(a,b){return this.coordAdjust&&(a+=this.coordAdjust.left,b+=this.coordAdjust.top),this.component.queryHit(a,b)}}),ob=va.extend(jb,{options:null,sourceEl:null,// the element that will be cloned and made to look like it is dragging +el:null,// the clone of `sourceEl` that will track the mouse +parentEl:null,// the element that `el` (the clone) will be attached to +// the initial position of el, relative to the offset parent. made to match the initial offset of sourceEl +top0:null,left0:null, +// the absolute coordinates of the initiating touch/mouse action +y0:null,x0:null, +// the number of pixels the mouse has moved from its initial position +topDelta:null,leftDelta:null,isFollowing:!1,isHidden:!1,isAnimating:!1,// doing the revert animation? +constructor:function(b,c){this.options=c=c||{},this.sourceEl=b,this.parentEl=c.parentEl?a(c.parentEl):b.parent()}, +// Causes the element to start following the mouse +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))}, +// Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position. +// `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately. +stop:function(b,c){function d(){this.isAnimating=!1,e.removeElement(),this.top0=this.left0=null,// reset state for future updatePosition calls +c&&c()}var e=this,f=this.options.revertDuration;this.isFollowing&&!this.isAnimating&&(// disallow more than one stop animation at a time +this.isFollowing=!1,this.stopListeningTo(a(document)),b&&f&&!this.isHidden?(// do a revert animation? +this.isAnimating=!0,this.el.animate({top:this.top0,left:this.left0},{duration:f,complete:d})):d())}, +// Gets the tracking element. Create it if necessary +getEl:function(){var a=this.el;// hack to force IE8 to compute correct bounding box +// we don't want long taps or any mouse interaction causing selection/menus. +// would use preventSelection(), but that prevents selectstart, causing problems. +return a||(this.sourceEl.width(),a=this.el=this.sourceEl.clone().addClass(this.options.additionalClass||"").css({position:"absolute",visibility:"",// in case original element was hidden (commonly through hideEvents()) +display:this.isHidden?"none":"",// for when initially hidden +margin:0,right:"auto",// erase and set width instead +bottom:"auto",// erase and set height instead +width:this.sourceEl.width(),// explicit height in case there was a 'right' value +height:this.sourceEl.height(),// explicit width in case there was a 'bottom' value +opacity:this.options.opacity||"",zIndex:this.options.zIndex}),a.addClass("fc-unselectable"),a.appendTo(this.parentEl)),a}, +// Removes the tracking element if it has already been created +removeElement:function(){this.el&&(this.el.remove(),this.el=null)}, +// Update the CSS position of the tracking element +updatePosition:function(){var a,b;this.getEl(),// ensure this.el +// make sure origin info was computed +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})}, +// Gets called when the user moves the mouse +handleMove:function(a){this.topDelta=w(a)-this.y0,this.leftDelta=v(a)-this.x0,this.isHidden||this.updatePosition()}, +// Temporarily makes the tracking element invisible. Can be called before following starts +hide:function(){this.isHidden||(this.isHidden=!0,this.el&&this.el.hide())}, +// Show the tracking element after it has been temporarily hidden +show:function(){this.isHidden&&(this.isHidden=!1,this.updatePosition(),this.getEl().show())}}),pb=Ta.Grid=va.extend(jb,{view:null,// a View object +isRTL:null,// shortcut to the view's isRTL option +start:null,end:null,el:null,// the containing element +elsByFill:null,// a hash of jQuery element sets used for rendering each fill. Keyed by fill name. +// derived from options +eventTimeFormat:null,displayEventTime:null,displayEventEnd:null,minResizeDuration:null,// TODO: hack. set by subclasses. minumum event resize duration +// if defined, holds the unit identified (ex: "year" or "month") that determines the level of granularity +// of the date areas. if not defined, assumes to be day and time granularity. +// TODO: port isTimeScale into same system? +largeUnit:null,dayDragListener:null,segDragListener:null,segResizeListener:null,externalDragListener:null,constructor:function(a){this.view=a,this.isRTL=a.opt("isRTL"),this.elsByFill={}},/* Options + ------------------------------------------------------------------------------------------------------------------*/ +// Generates the format string used for event time text, if not explicitly defined by 'timeFormat' +computeEventTimeFormat:function(){return this.view.opt("smallTimeFormat")}, +// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventTime'. +// Only applies to non-all-day events. +computeDisplayEventTime:function(){return!0}, +// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventEnd' +computeDisplayEventEnd:function(){return!0},/* Dates + ------------------------------------------------------------------------------------------------------------------*/ +// Tells the grid about what period of time to display. +// Any date-related internal data should be generated. +setRange:function(a){this.start=a.start.clone(),this.end=a.end.clone(),this.rangeUpdated(),this.processRangeOptions()}, +// Called when internal variables that rely on the range should be updated +rangeUpdated:function(){}, +// Updates values that rely on options and also relate to range +processRangeOptions:function(){var a,b,c=this.view;this.eventTimeFormat=c.opt("eventTimeFormat")||c.opt("timeFormat")||// deprecated +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}, +// Converts a span (has unzoned start/end and any other grid-specific location information) +// into an array of segments (pieces of events whose format is decided by the grid). +spanToSegs:function(a){}, +// Diffs the two dates, returning a duration, based on granularity of the grid +// TODO: port isTimeScale into this system? +diffDates:function(a,b){return this.largeUnit?L(a,b,this.largeUnit):J(a,b)},/* Hit Area + ------------------------------------------------------------------------------------------------------------------*/ +// Called before one or more queryHit calls might happen. Should prepare any cached coordinates for queryHit +prepareHits:function(){}, +// Called when queryHit calls have subsided. Good place to clear any coordinate caches. +releaseHits:function(){}, +// Given coordinates from the topleft of the document, return data about the date-related area underneath. +// Can return an object with arbitrary properties (although top/right/left/bottom are encouraged). +// Must have a `grid` property, a reference to this current grid. TODO: avoid this +// The returned object will be processed by getHitSpan and getHitEl. +queryHit:function(a,b){}, +// Given position-level information about a date-related area within the grid, +// should return an object with at least a start/end date. Can provide other information as well. +getHitSpan:function(a){}, +// Given position-level information about a date-related area within the grid, +// should return a jQuery element that best represents it. passed to dayClick callback. +getHitEl:function(a){},/* Rendering + ------------------------------------------------------------------------------------------------------------------*/ +// Sets the container element that the grid should render inside of. +// Does other DOM-related initializations. +setElement:function(a){this.el=a,y(a),this.view.calendar.isTouch?this.bindDayHandler("touchstart",this.dayTouchStart):this.bindDayHandler("mousedown",this.dayMousedown), +// attach event-element-related handlers. in Grid.events +// same garbage collection note as above. +this.bindSegHandlers(),this.bindGlobalHandlers()},bindDayHandler:function(b,c){var d=this; +// attach a handler to the grid's root element. +// jQuery will take care of unregistering them when removeElement gets called. +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)})}, +// Removes the grid's container element from the DOM. Undoes any other DOM-related attachments. +// DOES NOT remove any content beforehand (doesn't clear events or call unrenderDates), unlike View +removeElement:function(){this.unbindGlobalHandlers(),this.clearDragListeners(),this.el.remove()}, +// Renders the basic structure of grid view before any content is rendered +renderSkeleton:function(){}, +// Renders the grid's date-related content (like areas that represent days/times). +// Assumes setRange has already been called and the skeleton has already been rendered. +renderDates:function(){}, +// Unrenders the grid's date-related content +unrenderDates:function(){},/* Handlers + ------------------------------------------------------------------------------------------------------------------*/ +// Binds DOM handlers to elements that reside outside the grid, such as the document +bindGlobalHandlers:function(){this.listenTo(a(document),{dragstart:this.externalDragStart,// jqui +sortstart:this.externalDragStart})}, +// Unbinds DOM handlers from elements that reside outside the grid +unbindGlobalHandlers:function(){this.stopListeningTo(a(document))}, +// Process a mousedown on an element that represents a day. For day clicking and selecting. +dayMousedown:function(a){this.clearDragListeners(),this.buildDayDragListener().startInteraction(a,{})},dayTouchStart:function(a){this.clearDragListeners(),this.buildDayDragListener().startInteraction(a,{delay:this.view.opt("longPressDelay")})}, +// Creates a listener that tracks the user's drag across day elements. +// For day clicking and selecting. +buildDayDragListener:function(){var a,b,c=this,d=this.view,e=d.opt("selectable"),f=this.dayDragListener=new nb(this,{scroll:d.opt("dragScroll"),interactionStart:function(){a=f.origHit},dragStart:function(){d.unselect()},hitOver:function(d,f,h){h&&(// click needs to have started on a hit +// if user dragged to another cell at any point, it can no longer be a dayClick +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){a&&d.triggerDayClick(c.getHitSpan(a),c.getHitEl(a),e),b&& +// the selection will already have been rendered. just report it +d.reportSelection(b,e),h(),c.dayDragListener=null}});return f}, +// Kills all in-progress dragging. +// Useful for when public API methods that result in re-rendering are invoked during a drag. +// Also useful for when touch devices misbehave and don't fire their touchend. +clearDragListeners:function(){this.dayDragListener&&this.dayDragListener.endInteraction(),this.segDragListener&&this.segDragListener.endInteraction(),this.segResizeListener&&this.segResizeListener.endInteraction(),this.externalDragListener&&this.externalDragListener.endInteraction()},/* Event Helper + ------------------------------------------------------------------------------------------------------------------*/ +// TODO: should probably move this to Grid.events, like we did event dragging / resizing +// Renders a mock event at the given event location, which contains zoned start/end properties. +// Returns all mock event elements. +renderEventLocationHelper:function(a,b){var c=this.fabricateHelperEvent(a,b);return this.renderHelper(c,b)}, +// Builds a fake event given zoned event date properties and a segment is should be inspired from. +// The range's end can be null, in which case the mock event that is rendered will have a null end time. +// `sourceSeg` is the internal segment object involved in the drag. If null, something external is dragging. +fabricateHelperEvent:function(a,b){var c=b?V(b.event):{};// mask the original event object if possible +// force it to be freshly computed by normalizeEventDates +// this extra className will be useful for differentiating real events from mock events in CSS +// if something external is being dragged in, don't render a resizer +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}, +// Renders a mock event. Given zoned event date properties. +// Must return all mock event elements. +renderHelper:function(a,b){}, +// Unrenders a mock event +unrenderHelper:function(){},/* Selection + ------------------------------------------------------------------------------------------------------------------*/ +// Renders a visual indication of a selection. Will highlight by default but can be overridden by subclasses. +// Given a span (unzoned start/end and other misc data) +renderSelection:function(a){this.renderHighlight(a)}, +// Unrenders any visual indications of a selection. Will unrender a highlight by default. +unrenderSelection:function(){this.unrenderHighlight()}, +// Given the first and last date-spans of a selection, returns another date-span object. +// Subclasses can override and provide additional data in the span object. Will be passed to renderSelection(). +// Will return false if the selection is invalid and this should be indicated to the user. +// Will return null/undefined if a selection invalid but no error should be reported. +computeSelection:function(a,b){var c=this.computeSelectionSpan(a,b);return c&&!this.view.calendar.isSelectionSpanAllowed(c)?!1:c}, +// Given two spans, must return the combination of the two. +// TODO: do this separation of concerns (combining VS validation) for event dnd/resize too. +computeSelectionSpan:function(a,b){var c=[a.start,a.end,b.start,b.end];// sorts chronologically. works with Moments +return c.sort(ea),{start:c[0].clone(),end:c[3].clone()}},/* Highlight + ------------------------------------------------------------------------------------------------------------------*/ +// Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data) +renderHighlight:function(a){this.renderFill("highlight",this.spanToSegs(a))}, +// Unrenders the emphasis on a date range +unrenderHighlight:function(){this.unrenderFill("highlight")}, +// Generates an array of classNames for rendering the highlight. Used by the fill system. +highlightSegClasses:function(){return["fc-highlight"]},/* Business Hours + ------------------------------------------------------------------------------------------------------------------*/ +renderBusinessHours:function(){},unrenderBusinessHours:function(){},/* Now Indicator + ------------------------------------------------------------------------------------------------------------------*/ +getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},/* Fill System (highlight, background events, business hours) + -------------------------------------------------------------------------------------------------------------------- + TODO: remove this system. like we did in TimeGrid + */ +// Renders a set of rectangles over the given segments of time. +// MUST RETURN a subset of segs, the segs that were actually rendered. +// Responsible for populating this.elsByFill. TODO: better API for expressing this requirement +renderFill:function(a,b){}, +// Unrenders a specific type of fill that is currently rendered on the grid +unrenderFill:function(a){var b=this.elsByFill[a];b&&(b.remove(),delete this.elsByFill[a])}, +// Renders and assigns an `el` property for each fill segment. Generic enough to work with different types. +// Only returns segments that successfully rendered. +// To be harnessed by renderFill (implemented by subclasses). +// Analagous to renderFgSegEls. +renderFillSegEls:function(b,c){var d,e=this,f=this[b+"SegEl"],g="",h=[];if(c.length){ +// build a large concatenation of segment HTML +for(d=0;d"},/* Generic rendering utilities for subclasses + ------------------------------------------------------------------------------------------------------------------*/ +// Computes HTML classNames for a single-day element +getDayClasses:function(a){var b=this.view,c=b.calendar.getNow(),d=["fc-"+Xa[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}});/* Event-rendering and event-interaction methods for the abstract Grid class +----------------------------------------------------------------------------------------------------------------------*/ +pb.mixin({mousedOverSeg:null,// the segment object the user's mouse is over. null if over nothing +isDraggingSeg:!1,// is a segment being dragged? boolean +isResizingSeg:!1,// is a segment being resized? boolean +isDraggingExternal:!1,// jqui-dragging an external element? boolean +segs:null,// the *event* segments currently rendered in the grid. TODO: rename to `eventSegs` +// Renders the given events onto the grid +renderEvents:function(a){var b,c=[],d=[];for(b=0;b *",function(b){var e=a(this).data("fc-seg");// grab segment data. put there by View::renderEvents +// only call the handlers if there is not a drag/resize in progress +// grab segment data. put there by View::renderEvents +// only call the handlers if there is not a drag/resize in progress +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)}, +// Updates internal state and triggers handlers for when an event element is moused over +handleSegMouseover:function(a,b){this.mousedOverSeg||(this.mousedOverSeg=a,this.view.trigger("eventMouseover",a.el[0],a.event,b))}, +// Updates internal state and triggers handlers for when an event element is moused out. +// Can be given no arguments, in which case it will mouseout the segment that was previously moused over. +handleSegMouseout:function(a,b){b=b||{},this.mousedOverSeg&&(a=a||this.mousedOverSeg,this.mousedOverSeg=null,this.view.trigger("eventMouseout",a.el[0],a.event,b))},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&&( +// only allow resizing of the event is selected +i=this.startSegResize(a,b)),i||!g&&!h||(// allowed to be selected? +this.clearDragListeners(),c=g?this.buildSegDragListener(a):new mb,c._dragStart=function(){f||d.selectEvent(e)},c.startInteraction(b,{delay:f?0:this.view.opt("longPressDelay")}))},handleSegMousedown:function(a,b){var c=this.startSegResize(a,b,{distance:5});!c&&this.view.isEventDraggable(a.event)&&(this.clearDragListeners(),this.buildSegDragListener(a).startInteraction(b,{distance:5}))}, +// returns boolean whether resizing actually started or not. +// assumes the seg allows resizing. +// `dragOptions` are optional. +startSegResize:function(b,c,d){return a(c.target).is(".fc-resizer")?(this.clearDragListeners(),this.buildSegResizeListener(b,a(c.target).is(".fc-start-resizer")).startInteraction(c,d),!0):!1},/* Event Dragging + ------------------------------------------------------------------------------------------------------------------*/ +// Builds a listener that will track user-dragging on an event segment. +// Generic enough to work with any type of Grid. +buildSegDragListener:function(a){var b,c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event,l=this.segDragListener=new nb(f,{scroll:f.opt("dragScroll"),subjectEl:j,subjectCenter:!0,interactionStart:function(d){b=!1,c=new ob(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){b=!0,e.handleSegMouseout(a,c),e.segDragStart(a,c),f.hideEvent(k)},hitOver:function(b,h,j){var m; +// starting hit could be forced (DayGrid.limit) +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(){// called before mouse moves to a different hit OR moved out of all hits +f.unrenderDrag(),// unrender whatever was done in renderDrag +c.show(),// show in case we are moving out of all hits +d=null},hitDone:function(){// Called after a hitOut OR before a dragEnd +h()},interactionEnd:function(g){ +// do revert animation if hasn't changed. calls a callback when finished (whether animation or not) +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}, +// Called before event segment dragging starts +segDragStart:function(a,b){this.isDraggingSeg=!0,this.view.trigger("eventDragStart",a.el[0],a.event,b,{})}, +// Called after event segment dragging stops +segDragStop:function(a,b){this.isDraggingSeg=!1,this.view.trigger("eventDragStop",a.el[0],a.event,b,{})}, +// Given the spans an event drag began, and the span event was dropped, calculates the new zoned start/end/allDay +// values for the event. Subclasses may override and set additional properties to be used by renderDrag. +// A falsy returned value indicates an invalid drop. +// DOES NOT consider overlap/constraint. +computeEventDrop:function(a,b,c){var d,e,f=this.view.calendar,g=a.start,h=b.start;// zoned event date properties +// if an all-day event was in a timed area and it was dragged to a different time, +// guarantee an end and adjust start/end to have times +// if switching from day <-> timed, start should be reset to the dropped date, and the end cleared +return g.hasTime()===h.hasTime()?(d=this.diffDates(h,g),c.allDay&&R(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,// end should be cleared +allDay:!h.hasTime()},e}, +// Utility for apply dragOpacity to a jQuery set +applyDragOpacity:function(a){var b=this.view.opt("dragOpacity");null!=b&&a.each(function(a,c){ +// Don't use jQuery (will set an IE filter), do it the old fashioned way. +// In IE8, a helper element will disappears if there's a filter. +c.style.opacity=b})},/* External Element Dragging + ------------------------------------------------------------------------------------------------------------------*/ +// Called when a jQuery UI drag is initiated anywhere in the DOM +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)))}, +// Called when a jQuery UI drag starts and it needs to be monitored for dropping +listenToExternalDrag:function(a,b,c){var d,e=this,f=this.view.calendar,i=Fa(a),j=e.externalDragListener=new nb(this,{interactionStart:function(){e.isDraggingExternal=!0},hitOver:function(a){d=e.computeExternalDrop(a.component.getHitSpan(a),// since we are querying the parent view, might not belong to this grid +i),d&&!f.isExternalSpanAllowed(e.eventToSpan(d),d,i.eventProps)&&(g(),d=null),d&&e.renderDrag(d)},hitOut:function(){d=null},hitDone:function(){// Called after a hitOut OR before a dragEnd +h(),e.unrenderDrag()},interactionEnd:function(b){d&&// element was dropped on a valid hit +e.view.reportExternalDrop(i,d,a,b,c),e.isDraggingExternal=!1,e.externalDragListener=null}});j.startDrag(b)}, +// Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object), +// returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null. +// Returning a null value signals an invalid drop hit. +// DOES NOT consider overlap/constraint. +computeExternalDrop:function(a,b){var c=this.view.calendar,d={start:c.applyTimezone(a.start),// simulate a zoned event start date +end:null}; +// if dropped on an all-day span, and element's metadata specified a time, set it +return b.startTime&&!d.start.hasTime()&&d.start.time(b.startTime),b.duration&&(d.end=d.start.clone().add(b.duration)),d},/* Drag Rendering (for both events and an external elements) + ------------------------------------------------------------------------------------------------------------------*/ +// Renders a visual indication of an event or external element being dragged. +// `dropLocation` contains hypothetical start/end/allDay values the event would have if dropped. end can be null. +// `seg` is the internal segment object that is being dragged. If dragging an external element, `seg` is null. +// A truthy returned value indicates this method has rendered a helper element. +// Must return elements used for any mock events. +renderDrag:function(a,b){}, +// Unrenders a visual indication of an event or external element being dragged +unrenderDrag:function(){},/* Resizing + ------------------------------------------------------------------------------------------------------------------*/ +// Creates a listener that tracks the user as they resize an event segment. +// Generic enough to work with any type of Grid. +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 nb(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(){// called before mouse moves to a different hit OR moved out of all hits +d=null},hitDone:function(){// resets the rendering to show the original event +e.unrenderEventResize(),f.showEvent(k),h()},interactionEnd:function(b){c&&e.segResizeStop(a,b),d&&// valid date to resize to? +f.reportEventResize(k,d,this.largeUnit,j,b),e.segResizeListener=null}});return m}, +// Called before event segment resizing starts +segResizeStart:function(a,b){this.isResizingSeg=!0,this.view.trigger("eventResizeStart",a.el[0],a.event,b,{})}, +// Called after event segment resizing stops +segResizeStop:function(a,b){this.isResizingSeg=!1,this.view.trigger("eventResizeStop",a.el[0],a.event,b,{})}, +// Returns new date-information for an event segment being resized from its start +computeEventStartResize:function(a,b,c){return this.computeEventResize("start",a,b,c)}, +// Returns new date-information for an event segment being resized from its end +computeEventEndResize:function(a,b,c){return this.computeEventResize("end",a,b,c)}, +// Returns new zoned date information for an event segment being resized from its start OR end +// `type` is either 'start' or 'end'. +// DOES NOT consider overlap/constraint. +computeEventResize:function(a,b,c,d){var e,f,g=this.view.calendar,h=this.diffDates(c[a],b[a]); +// build original values to work from, guaranteeing a start and end +// if an all-day event was in a timed area and was resized to a time, adjust start/end to have times +// apply delta to start or end +// if the event was compressed too small, find a new reasonable duration for it +// TODO: hack +// resizing the start? +// resizing the end? +return e={start:d.start.clone(),end:g.getEventEnd(d),allDay:d.allDay},e.allDay&&R(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}, +// Renders a visual indication of an event being resized. +// `range` has the updated dates of the event. `seg` is the original segment object involved in the drag. +// Must return elements used for any mock events. +renderEventResize:function(a,b){}, +// Unrenders a visual indication of an event being resized. +unrenderEventResize:function(){},/* Rendering Utils + ------------------------------------------------------------------------------------------------------------------*/ +// Compute the text that should be displayed on an event's element. +// `range` can be the Event object itself, or something range-like, with at least a `start`. +// If event times are disabled, or the event has no time, will return a blank string. +// If not specified, formatStr will default to the eventTimeFormat setting, +// and displayEnd will default to the displayEventEnd setting. +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):""}, +// Generic utility for generating the HTML classNames for an event segment's element +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:[]); +// event is currently selected? attach a className. +return b&&f.push("fc-draggable"),c&&f.push("fc-resizable"),d.isEventSelected(e)&&f.push("fc-selected"),f}, +// Utility for generating event skin-related CSS properties +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")}},/* Converting events -> eventRange -> eventSpan -> eventSegs + ------------------------------------------------------------------------------------------------------------------*/ +// Generates an array of segments for the given single event +// Can accept an event "location" as well (which only has start/end and no allDay) +eventToSegs:function(a){return this.eventsToSegs([a])},eventToSpan:function(a){return this.eventToSpans(a)[0]}, +// Generates spans (always unzoned) for the given event. +// Does not do any inverting for inverse-background events. +// Can accept an event "location" as well (which only has start/end and no allDay) +eventToSpans:function(a){var b=this.eventToRange(a);return this.eventRangeToSpans(b,a)}, +// Converts an array of event objects into an array of event segment objects. +// A custom `segSliceFunc` may be given for arbitrarily slicing up events. +// Doesn't guarantee an order for the resulting array. +eventsToSegs:function(b,c){var d=this,e=Da(b),f=[];return a.each(e,function(a,b){var e,g=[];for(e=0;eh&&g.push({start:h,end:c.start}),h=c.end; +// add the span of time after the last event (if there is any) +// compare millisecond time (skip any ambig logic) +return f>h&&g.push({start:h,end:f}),g},sortEventSegs:function(a){a.sort(ga(this,"compareEventSegs"))}, +// A cmp function for determining which segments should take visual priority +compareEventSegs:function(a,b){// earlier events go first +// tie? longer events go first +// tie? put all-day events first (booleans cast to 0/1) +return a.eventStartMS-b.eventStartMS||b.eventDurationMS-a.eventDurationMS||b.event.allDay-a.event.allDay||F(a.event,b.event,this.view.eventOrderSpecs)}}),Ta.isBgEvent=Aa,/* External-Dragging-Element Data +----------------------------------------------------------------------------------------------------------------------*/ +// Require all HTML5 data-* attributes used by FullCalendar to have this prefix. +// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event. +Ta.dataAttrPrefix="";/* +A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns. +Prerequisite: the object being mixed into needs to be a *Grid* +*/ +var qb=Ta.DayTableMixin={breakOnWeeks:!1,// should create a new row for each week? +dayDates:null,// whole-day dates for each column. left to right +dayIndices:null,// for each day from start, the offset +daysPerRow:null,rowCnt:null,colCnt:null,colHeadFormat:null, +// Populates internal variables used for date calculation and rendering +updateDayTable:function(){for(var a,b,c,d=this.view,e=this.start.clone(),f=-1,g=[],h=[];e.isBefore(this.end);)// loop each day from start to 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;ac?b[0]-1:c>=b.length?b[b.length-1]+1:b[c]},/* Options + ------------------------------------------------------------------------------------------------------------------*/ +// Computes a default column header formatting string if `colFormat` is not explicitly defined +computeColHeadFormat:function(){ +// if more than one week row, or if there are a lot of columns with not much space, +// put just the day numbers will be in each cell +// if more than one week row, or if there are a lot of columns with not much space, +// put just the day numbers will be in each cell +return this.rowCnt>1||this.colCnt>10?"ddd":this.colCnt>1?this.view.opt("dayOfMonthFormat"):"dddd"},/* Slicing + ------------------------------------------------------------------------------------------------------------------*/ +// Slices up a date range into a segment for every week-row it intersects with +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=[];// inclusive day-index range for segment +for(b=0;b=e&&k.push({row:b,firstRowDayIndex:e-c,lastRowDayIndex:f-c,isStart:e===i,isEnd:f===j});return k}, +// Slices up a date range into a segment for every day-cell it intersects with. +// TODO: make more DRY with sliceRangeByRow somehow. +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=[];// inclusive day-index range for segment +for(b=0;b=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},/* Header Rendering + ------------------------------------------------------------------------------------------------------------------*/ +renderHeadHtml:function(){var a=this.view;return'
'+this.renderHeadTrHtml()+"
"},renderHeadIntroHtml:function(){return this.renderIntroHtml()},renderHeadTrHtml:function(){return""+(this.isRTL?"":this.renderHeadIntroHtml())+this.renderHeadDateCellsHtml()+(this.isRTL?this.renderHeadIntroHtml():"")+""},renderHeadDateCellsHtml:function(){var a,b,c=[];for(a=0;a1?' colspan="'+b+'"':"")+(c?" "+c:"")+">"+aa(a.format(this.colHeadFormat))+""},/* Background Rendering + ------------------------------------------------------------------------------------------------------------------*/ +renderBgTrHtml:function(a){return""+(this.isRTL?"":this.renderBgIntroHtml(a))+this.renderBgCellsHtml(a)+(this.isRTL?this.renderBgIntroHtml(a):"")+""},renderBgIntroHtml:function(a){return this.renderIntroHtml()},renderBgCellsHtml:function(a){var b,c,d=[];for(b=0;b"},/* Generic + ------------------------------------------------------------------------------------------------------------------*/ +// Generates the default HTML intro for any row. User classes should override +renderIntroHtml:function(){}, +// TODO: a generic method for dealing with , RTL, intro +// when increment internalApiVersion +// wrapTr (scheduler) +/* Utils + ------------------------------------------------------------------------------------------------------------------*/ +// Applies the generic "intro" and "outro" HTML to the given cells. +// Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro. +bookendCells:function(a){var b=this.renderIntroHtml();b&&(this.isRTL?a.append(b):a.prepend(b))}},rb=Ta.DayGrid=pb.extend(qb,{numbersVisible:!1,// should render a row for day/week numbers? set by outside view. TODO: make internal +bottomCoordPadding:0,// hack for extending the hit area for the last row of the coordinate grid +rowEls:null,// set of fake row elements +cellEls:null,// set of whole-day elements comprising the row's background +helperEls:null,// set of cell skeleton elements for rendering the mock event "helper" +rowCoordCache:null,colCoordCache:null, +// Renders the rows and columns into the component's `this.el`, which should already be assigned. +// isRigid determins whether the individual rows should ignore the contents and be a constant height. +// Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient. +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); +// trigger dayRender with each cell's element +for(this.el.html(g),this.rowEls=this.el.find(".fc-row"),this.cellEls=this.el.find(".fc-day"),this.rowCoordCache=new lb({els:this.rowEls,isVertical:!0}),this.colCoordCache=new lb({els:this.cellEls.slice(0,this.colCnt),// only the first row +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")}, +// Generates the HTML for a single row, which is a div that wraps a table. +// `row` is the row number. +renderDayRowHtml:function(a,b){var c=this.view,d=["fc-row","fc-week",c.widgetContentClass];return b&&d.push("fc-rigid"),'
'+this.renderBgTrHtml(a)+'
'+(this.numbersVisible?""+this.renderNumberTrHtml(a)+"":"")+"
"},/* Grid Number Rendering + ------------------------------------------------------------------------------------------------------------------*/ +renderNumberTrHtml:function(a){return""+(this.isRTL?"":this.renderNumberIntroHtml(a))+this.renderNumberCellsHtml(a)+(this.isRTL?this.renderNumberIntroHtml(a):"")+""},renderNumberIntroHtml:function(a){return this.renderIntroHtml()},renderNumberCellsHtml:function(a){var b,c,d=[];for(b=0;bs of the "number" row in the DayGrid's content skeleton. +// The number row will only exist if either day numbers or week numbers are turned on. +renderNumberCellHtml:function(a){var b;return this.view.dayNumbersVisible?(b=this.getDayClasses(a),b.unshift("fc-day-number"),''+a.date()+""):""},/* Options + ------------------------------------------------------------------------------------------------------------------*/ +// Computes a default event time formatting string if `timeFormat` is not explicitly defined +computeEventTimeFormat:function(){return this.view.opt("extraSmallTimeFormat")}, +// Computes a default `displayEventEnd` value if one is not expliclty defined +computeDisplayEventEnd:function(){return 1==this.colCnt},/* Dates + ------------------------------------------------------------------------------------------------------------------*/ +rangeUpdated:function(){this.updateDayTable()}, +// Slices up the given span (unzoned start/end with other misc data) into an array of segments +spanToSegs:function(a){var b,c,d=this.sliceRangeByRow(a);for(b=0;b');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)}, +// Unrenders any visual indication of a mock helper event +unrenderHelper:function(){this.helperEls&&(this.helperEls.remove(),this.helperEls=null)},/* Fill System (highlight, background events, business hours) + ------------------------------------------------------------------------------------------------------------------*/ +fillSegTag:"td",// override the default tag name +// Renders a set of rectangles over the given segments of days. +// Only returns segments that successfully rendered. +renderFill:function(b,c,d){var e,f,g,h=[];// assignes `.el` to each seg. returns successfully rendered segs +for(c=this.renderFillSegEls(b,c),e=0;e
'),f=e.find("tr"),h>0&&f.append(''),f.append(c.el.attr("colspan",i-h)),g>i&&f.append(''),this.bookendCells(f),e}});/* Event-rendering methods for the DayGrid class +----------------------------------------------------------------------------------------------------------------------*/ +rb.mixin({rowStructs:null,// an array of objects, each holding information about a row's foreground event-rendering +// Unrenders all events currently rendered on the grid +unrenderEvents:function(){this.removeSegPopover(),// removes the "more.." events popover +pb.prototype.unrenderEvents.apply(this,arguments)}, +// Retrieves all rendered segment objects currently rendered on the grid +getEventSegs:function(){return pb.prototype.getEventSegs.call(this).concat(this.popoverSegs||[])}, +// Renders the given background event segments onto the grid +renderBgSegs:function(b){ +// don't render timed background events +var c=a.grep(b,function(a){return a.event.allDay});return pb.prototype.renderBgSegs.call(this,c)}, +// Renders the given foreground event segments onto the grid +renderFgSegs:function(b){var c; +// render an `.el` on each seg +// returns a subset of the segs. segs that were actually rendered +// append to each row's content skeleton +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}, +// Unrenders all currently rendered foreground event segments +unrenderFgSegs:function(){for(var a,b=this.rowStructs||[];a=b.pop();)a.tbodyEl.remove();this.rowStructs=null}, +// Uses the given events array to generate elements that should be appended to each row's content skeleton. +// Returns an array of rowStruct objects (see the bottom of `renderSegRow`). +// PRECONDITION: each segment shoud already have a rendered and assigned `.el` +renderSegRows:function(a){var b,c,d=[];// group into nested arrays +// iterate each row of segment groupings +for(b=this.groupSegRows(a),c=0;c'+aa(c)+"")),d=''+(aa(f.title||"")||" ")+"",'
'+(this.isRTL?d+" "+l:l+" "+d)+"
"+(h?'
':"")+(i?'
':"")+""}, +// Given a row # and an array of segments all in the same row, render a element, a skeleton that contains +// the segments. Returns object with a bunch of internal data about how the render was calculated. +// NOTE: modifies rowSegs +renderSegRow:function(b,c){ +// populates empty cells from the current column (`col`) to `endCol` +function d(b){for(;b>g;)k=(r[e-1]||[])[g],k?k.attr("rowspan",parseInt(k.attr("rowspan")||1,10)+1):(k=a(""),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(""),p=[],q=[],r=[];for(e=0;n>e;e++){ +// levelCnt might be 1 even though there are no actual levels. protect against this. +// this single empty row is useful for styling. +if(f=m[e],g=0,h=a(""),p.push([]),q.push([]),r.push([]),f)for(i=0;i').append(j.el),j.leftCol!=j.rightCol?k.attr("colspan",j.rightCol-j.leftCol+1):// a single-column segment +r[e][g]=k;g<=j.rightCol;)q[e][g]=k,p[e][g]=j,g++;h.append(k)}d(l),// finish off the row +this.bookendCells(h),o.append(h)}return{// a "rowStruct" +row:b,// the row number +tbodyEl:o,cellMatrix:q,segMatrix:p,segLevels:m,segs:c}}, +// Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels. +// NOTE: modifies segs +buildSegLevels:function(a){var b,c,d,e=[];for( +// Give preference to elements with certain criteria, so they have +// a chance to be closer to the top. +this.sortEventSegs(a),b=0;b at a time and stop when we find one out of bounds +for(d=0;d td > :first-child").each(c),e.position().top+f>h)return d;return!1}, +// Limits the given grid row to the maximum number of levels and injects "more" links if necessary. +// `row` is the row number. +// `levelLimit` is a number for the maximum (inclusive) number of levels allowed. +limitRow:function(b,c){ +// Iterates through empty level cells and places "more" links inside if need be +function d(d){// goes from current `col` to `endCol` +for(;d>w;)j=t.getCellSegs(b,w,c),j.length&&(m=f[c-1][w],s=t.renderMoreLink(b,w,j),r=a("
").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 for each column the segment occupies. will be one for each colspan +for(m=f[c-1][i.leftCol],n=m.attr("rowspan")||1,o=[],p=0;p').attr("rowspan",n),j=l[p],s=this.renderMoreLink(b,i.leftCol+p,[i].concat(j)),r=a("
").append(s),q.append(r),o.push(q[0]),v.push(q[0]);m.addClass("fc-limited").after(a(o)),// hide original and inject replacements +g.push(m[0])}}d(this.colCnt),// finish off the level +u.moreEls=a(v),// for easy undoing later +u.limitedEls=a(g)}}, +// Reveals all levels and removes all "more"-related elements for a grid's row. +// `row` is a row number. +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)}, +// Renders an element that represents hidden event element for a cell. +// Responsible for attaching click handler as well. +renderMoreLink:function(b,c,d){var e=this,f=this.view;return a('').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&&( +// the returned value can be an atomic option +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&&// a view name +f.calendar.zoomTo(i,h)})}, +// Reveals the popover that displays all events within a cell +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 kb(f),this.segPopover.show()}, +// Builds the inner DOM contents of the segment popover +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('
'+aa(h)+'
'),j=i.find(".fc-event-container");for(d=this.renderFgSegEls(d,!0),this.popoverSegs=d,e=0;e'+this.renderBgTrHtml(0)+'
'+this.renderSlatRowHtml()+"
"}, +// Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. +renderSlatRowHtml:function(){ +// Calculate the time for each slot +for(var a,c,d,e=this.view,f=this.isRTL,g="",h=b.duration(+this.minTime);h"+(c?""+aa(a.format(this.labelFormat))+"":"")+"",g+='"+(f?"":d)+''+(f?d:"")+"",h.add(this.slotDuration);return g},/* Options + ------------------------------------------------------------------------------------------------------------------*/ +// Parses various options into properties of this object +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)}, +// Computes an automatic value for slotLabelInterval +computeLabelInterval:function(a){var c,d,e; +// find the smallest stock label interval that results in more than one slots-per-label +for(c=Jb.length-1;c>=0;c--)if(d=b.duration(Jb[c]),e=P(d,a),fa(e)&&e>1)return d;return b.duration(a)}, +// Computes a default event time formatting string if `timeFormat` is not explicitly defined +computeEventTimeFormat:function(){return this.view.opt("noMeridiemTimeFormat")}, +// Computes a default `displayEventEnd` value if one is not expliclty defined +computeDisplayEventEnd:function(){return!0},/* Hit System + ------------------------------------------------------------------------------------------------------------------*/ +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,// needed unfortunately :( +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)},/* Dates + ------------------------------------------------------------------------------------------------------------------*/ +rangeUpdated:function(){this.updateDayTable()}, +// Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day +computeSnapTime:function(a){return b.duration(this.minTime+this.snapDuration*a)}, +// Slices up the given span (unzoned start/end with other misc data) into an array of segments +spanToSegs:function(a){var b,c=this.sliceRangeByTimes(a);for(b=0;b
').css("top",e).appendTo(this.colContainerEls.eq(d[c].col))[0]); +// render an arrow over the axis +d.length>0&&// is the current time in view? +f.push(a('
').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)},/* Selection + ------------------------------------------------------------------------------------------------------------------*/ +// Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight. +renderSelection:function(a){this.view.opt("selectHelper")?// this setting signals that a mock helper event should be rendered +// normally acceps an eventLocation, span has a start/end, which is good enough +this.renderEventLocationHelper(a):this.renderHighlight(a)}, +// Unrenders any visual indication of a selection +unrenderSelection:function(){this.unrenderHelper(),this.unrenderHighlight()},/* Highlight + ------------------------------------------------------------------------------------------------------------------*/ +renderHighlight:function(a){this.renderHighlightSegs(this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderHighlightSegs()}});/* Methods for rendering SEGMENTS, pieces of content that live on the view + ( this file is no longer just for events ) +----------------------------------------------------------------------------------------------------------------------*/ +sb.mixin({colContainerEls:null,// containers for each column +// inner-containers for each column where different types of segs live +fgContainerEls:null,bgContainerEls:null,helperContainerEls:null,highlightContainerEls:null,businessContainerEls:null, +// arrays of different types of displayed segments +fgSegs:null,bgSegs:null,helperSegs:null,highlightSegs:null,businessSegs:null, +// Renders the DOM that the view's content will live in +renderContentSkeleton:function(){var b,c,d="";for(b=0;b
';c=a('
'+d+"
"),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)},/* Foreground Events + ------------------------------------------------------------------------------------------------------------------*/ +renderFgSegs:function(a){return a=this.renderFgSegsIntoContainers(a,this.fgContainerEls),this.fgSegs=a,a},unrenderFgSegs:function(){this.unrenderNamedSegs("fgSegs")},/* Foreground Helper Events + ------------------------------------------------------------------------------------------------------------------*/ +renderHelperSegs:function(b,c){var d,e,f,g=[]; +// Try to make the segment that is in the same row as sourceSeg look the same +for(b=this.renderFgSegsIntoContainers(b,this.helperContainerEls),d=0;d' : + '' + ) + + */ +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)),'
'+(c?'
'+aa(c)+"
":"")+(g.title?'
'+aa(g.title)+"
":"")+'
'+(j?'
':"")+""},/* Seg Position Utils + ------------------------------------------------------------------------------------------------------------------*/ +// Refreshes the CSS top/bottom coordinates for each segment element. +// Works when called after initial render, after a window resize/zoom for example. +updateSegVerticals:function(a){this.computeSegVerticals(a),this.assignSegVerticals(a)}, +// For each segment in an array, computes and assigns its top and bottom properties +computeSegVerticals:function(a){var b,c;for(b=0;b1?"ll":"LL"}, +// Utility for formatting a range. Accepts a range object, formatting string, and optional separator. +// Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account. +// The timezones of the dates within `range` will be respected. +formatRange:function(a,b,c){var d=a.end;// all-day? +return d.hasTime()||(d=d.clone().subtract(1)),qa(a.start,d,b,c,this.opt("isRTL"))},/* Rendering + ------------------------------------------------------------------------------------------------------------------*/ +// Sets the container element that the view should render inside of. +// Does other DOM-related initializations. +setElement:function(a){this.el=a,this.bindGlobalHandlers()}, +// Removes the view's container element from the DOM, clearing any content beforehand. +// Undoes any other DOM-related attachments. +removeElement:function(){this.clear(),// clears all content +// clean up the skeleton +this.isSkeletonRendered&&(this.unrenderSkeleton(),this.isSkeletonRendered=!1),this.unbindGlobalHandlers(),this.el.remove()}, +// Does everything necessary to display the view centered around the given unzoned date. +// Does every type of rendering EXCEPT rendering events. +// Is asychronous and returns a promise. +display:function(b){var c=this,d=null;return this.displaying&&(d=this.queryScroll()),this.calendar.freezeContentHeight(),this.clear().then(function(){// clear the content first (async) +return c.displaying=a.when(c.displayView(b)).then(function(){c.forceScroll(c.computeInitialScroll(d)),c.calendar.unfreezeContentHeight(),c.triggerRender()})})}, +// Does everything necessary to clear the content of the view. +// Clears dates and events. Does not clear the skeleton. +// Is asychronous and returns a promise. +clear:function(){var b=this,c=this.displaying;return c?c.then(function(){// wait for the display to finish +return b.displaying=null,b.clearEvents(),b.clearView()}):a.when()}, +// Displays the view's non-event content, such as date-related content or anything required by events. +// Renders the view's non-content skeleton if necessary. +// Can be asynchronous and return a promise. +displayView:function(a){this.isSkeletonRendered||(this.renderSkeleton(),this.isSkeletonRendered=!0),a&&this.setDate(a),this.render&&this.render(),this.renderDates(),this.updateSize(),this.renderBusinessHours(),// might need coordinates, so should go after updateSize() +this.startNowIndicator()}, +// Unrenders the view content that was rendered in displayView. +// Can be asynchronous and return a promise. +clearView:function(){this.unselect(),this.stopNowIndicator(),this.triggerUnrender(),this.unrenderBusinessHours(),this.unrenderDates(),this.destroy&&this.destroy()}, +// Renders the basic structure of the view before any content is rendered +renderSkeleton:function(){}, +// Unrenders the basic structure of the view +unrenderSkeleton:function(){}, +// Renders the view's date-related content. +// Assumes setRange has already been called and the skeleton has already been rendered. +renderDates:function(){}, +// Unrenders the view's date-related content +unrenderDates:function(){}, +// Signals that the view's content has been rendered +triggerRender:function(){this.trigger("viewRender",this,this,this.el)}, +// Signals that the view's content is about to be unrendered +triggerUnrender:function(){this.trigger("viewDestroy",this,this,this.el)}, +// Binds DOM handlers to elements that reside outside the view container, such as the document +bindGlobalHandlers:function(){this.listenTo(a(document),"mousedown",this.handleDocumentMousedown),this.listenTo(a(document),"touchstart",this.handleDocumentTouchStart),this.listenTo(a(document),"touchend",this.handleDocumentTouchEnd)}, +// Unbinds DOM handlers from elements that reside outside the view container +unbindGlobalHandlers:function(){this.stopListeningTo(a(document))}, +// Initializes internal variables related to theming +initThemingProps:function(){var a=this.opt("theme")?"ui":"fc";this.widgetHeaderClass=a+"-widget-header",this.widgetContentClass=a+"-widget-content",this.highlightStateClass=a+"-state-highlight"},/* Business Hours + ------------------------------------------------------------------------------------------------------------------*/ +// Renders business-hours onto the view. Assumes updateSize has already been called. +renderBusinessHours:function(){}, +// Unrenders previously-rendered business-hours +unrenderBusinessHours:function(){},/* Now Indicator + ------------------------------------------------------------------------------------------------------------------*/ +// Immediately render the current time indicator and begins re-rendering it at an interval, +// which is defined by this.getNowIndicatorUnit(). +// TODO: somehow do this for the current whole day's background too +startNowIndicator:function(){var a,c,d,e=this;// ms wait value +this.opt("nowIndicator")&&(a=this.getNowIndicatorUnit(),a&&(c=ga(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)))}, +// rerenders the now indicator, computing the new current time from the amount of time that has passed +// since the initial getNow call. +updateNowIndicator:function(){this.isNowIndicatorRendered&&(this.unrenderNowIndicator(),this.renderNowIndicator(this.initialNowDate.clone().add(new Date-this.initialNowQueriedMs)))}, +// Immediately unrenders the view's current time indicator and stops any re-rendering timers. +// Won't cause side effects if indicator isn't rendered. +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)}, +// Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator +// should be refreshed. If something falsy is returned, no time indicator is rendered at all. +getNowIndicatorUnit:function(){}, +// Renders a current time indicator at the given datetime +renderNowIndicator:function(a){}, +// Undoes the rendering actions from renderNowIndicator +unrenderNowIndicator:function(){},/* Dimensions + ------------------------------------------------------------------------------------------------------------------*/ +// Refreshes anything dependant upon sizing of the container element of the grid +updateSize:function(a){var b;a&&(b=this.queryScroll()),this.updateHeight(a),this.updateWidth(a),this.updateNowIndicator(),a&&this.setScroll(b)}, +// Refreshes the horizontal dimensions of the calendar +updateWidth:function(a){}, +// Refreshes the vertical dimensions of the calendar +updateHeight:function(a){var b=this.calendar;// we poll the calendar for height information +this.setHeight(b.getSuggestedViewHeight(),b.isHeightAuto())}, +// Updates the vertical dimensions of the calendar to the specified height. +// if `isAuto` is set to true, height becomes merely a suggestion and the view should use its "natural" height. +setHeight:function(a,b){},/* Scroller + ------------------------------------------------------------------------------------------------------------------*/ +// Computes the initial pre-configured scroll state prior to allowing the user to change it. +// Given the scroll state from the previous rendering. If first time rendering, given null. +computeInitialScroll:function(a){return 0}, +// Retrieves the view's current natural scroll state. Can return an arbitrary format. +queryScroll:function(){}, +// Sets the view's scroll state. Will accept the same format computeInitialScroll and queryScroll produce. +setScroll:function(a){}, +// Sets the scroll state, making sure to overcome any predefined scroll value the browser has in mind +forceScroll:function(a){var b=this;this.setScroll(a),setTimeout(function(){b.setScroll(a)},0)},/* Event Elements / Segments + ------------------------------------------------------------------------------------------------------------------*/ +// Does everything necessary to display the given events onto the current view +displayEvents:function(a){var b=this.queryScroll();this.clearEvents(),this.renderEvents(a),this.isEventsRendered=!0,this.setScroll(b),this.triggerEventRender()}, +// Does everything necessary to clear the view's currently-rendered events +clearEvents:function(){var a;this.isEventsRendered&&(a=this.queryScroll(),this.triggerEventUnrender(),this.destroyEvents&&this.destroyEvents(),this.unrenderEvents(),this.setScroll(a),this.isEventsRendered=!1)}, +// Renders the events onto the view. +renderEvents:function(a){}, +// Removes event elements from the view. +unrenderEvents:function(){}, +// Signals that all events have been rendered +triggerEventRender:function(){this.renderedEventSegEach(function(a){this.trigger("eventAfterRender",a.event,a.event,a.el)}),this.trigger("eventAfterAllRender")}, +// Signals that all event elements are about to be removed +triggerEventUnrender:function(){this.renderedEventSegEach(function(a){this.trigger("eventDestroy",a.event,a.event,a.el)})}, +// Given an event and the default element used for rendering, returns the element that should actually be used. +// Basically runs events and elements through the eventRender hook. +resolveEventEl:function(b,c){var d=this.trigger("eventRender",b,b,c);// means don't render at all +return d===!1?c=null:d&&d!==!0&&(c=a(d)),c}, +// Hides all rendered event segments linked to the given event +showEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","")},a)}, +// Shows all rendered event segments linked to the given event +hideEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","hidden")},a)}, +// Iterates through event segments that have been rendered (have an el). Goes through all by default. +// If the optional `event` argument is specified, only iterates through segments linked to that event. +// The `this` value of the callback function will be the view. +renderedEventSegEach:function(a,b){var c,d=this.getEventSegs();for(c=0;c