hoodcms 5.0.15 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/css/login.css +1 -1
  2. package/dist/js/admin/ContentController.d.ts +30 -0
  3. package/dist/js/admin/ContentController.js +188 -0
  4. package/dist/js/admin/ContentTypeController.d.ts +15 -0
  5. package/dist/js/admin/ContentTypeController.js +140 -0
  6. package/dist/js/admin/HomeController.d.ts +17 -0
  7. package/dist/js/admin/HomeController.js +111 -0
  8. package/dist/js/admin/LogsController.d.ts +6 -0
  9. package/dist/js/admin/LogsController.js +14 -0
  10. package/dist/js/admin/MediaController.d.ts +7 -0
  11. package/dist/js/admin/MediaController.js +29 -0
  12. package/dist/js/admin/PropertyController.d.ts +18 -0
  13. package/dist/js/admin/PropertyController.js +118 -0
  14. package/dist/js/admin/PropertyImporter.d.ts +31 -0
  15. package/dist/js/admin/PropertyImporter.js +95 -0
  16. package/dist/js/admin/ThemesController.d.ts +8 -0
  17. package/dist/js/admin/ThemesController.js +37 -0
  18. package/dist/js/admin/UsersController.d.ts +17 -0
  19. package/dist/js/admin/UsersController.js +176 -0
  20. package/dist/js/admin.js +7 -7
  21. package/dist/js/app/PropertyService.d.ts +46 -0
  22. package/{src/ts/app/PropertyController.ts → dist/js/app/PropertyService.js} +44 -76
  23. package/dist/js/app.js +16 -4
  24. package/dist/js/app.property.js +5 -5
  25. package/dist/js/core/DataList.js +25 -3
  26. package/dist/js/index.d.ts +10 -0
  27. package/dist/js/index.js +12 -0
  28. package/dist/js/login.js +1 -1
  29. package/images/hood-small.png +0 -0
  30. package/images/hood.png +0 -0
  31. package/package.json +108 -108
  32. package/src/css/admin.css +0 -3
  33. package/src/css/admin.css.map +1 -1
  34. package/src/css/app.css +0 -3
  35. package/src/css/app.css.map +1 -1
  36. package/src/css/login.css +165 -0
  37. package/src/css/login.css.map +1 -1
  38. package/src/html/auth0/login.html +100 -0
  39. package/src/html/auth0/passwordless-email.html +184 -0
  40. package/src/js/admin.js +835 -664
  41. package/src/js/admin.js.map +1 -1
  42. package/src/js/app.js +11546 -5
  43. package/src/js/app.js.map +1 -1
  44. package/src/js/app.property.js +175 -129
  45. package/src/js/app.property.js.map +1 -1
  46. package/src/js/login.js +1 -1
  47. package/src/scss/core/_images.scss +48 -48
  48. package/src/scss/login.scss +1 -0
  49. package/src/ts/app/PropertyService.ts +202 -0
  50. package/src/ts/app.property.ts +4 -5
  51. package/src/ts/core/DataList.ts +27 -4
  52. package/src/ts/index.ts +14 -0
package/src/js/admin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * hoodcms v5.0.15
2
+ * hoodcms v6.0.2
3
3
  * A fully customisable content management system built in ASP.NET Core 5 & Bootstrap 5.
4
4
  * Written by George Whysall, 2022
5
5
  * Released under the GPL-3.0 License.
@@ -424,9 +424,31 @@
424
424
  }
425
425
  this.options = __assign(__assign({}, this.options), options);
426
426
  if ($(this.element).hasClass('query')) {
427
- var pageUrl = $(this.element).data('url') + window.location.search;
428
- $(this.element).attr('data-url', pageUrl);
429
- $(this.element).data('url', pageUrl);
427
+ var r = new RegExp('^(?:[a-z]+:)?//', 'i');
428
+ var pageUrl = null;
429
+ if (r.test(this.element.dataset.url)) {
430
+ pageUrl = new URL(this.element.dataset.url);
431
+ }
432
+ else {
433
+ pageUrl = new URL(window.location.origin + this.element.dataset.url);
434
+ }
435
+ if ('URLSearchParams' in window) {
436
+ var searchParams = new URLSearchParams(window.location.search);
437
+ var urlParams = new URLSearchParams(pageUrl.search);
438
+ searchParams.forEach(function (value, key, parent) {
439
+ urlParams.set(key, value);
440
+ });
441
+ if (urlParams.get("page") == "0") {
442
+ urlParams.set("page", "1");
443
+ }
444
+ pageUrl.search = urlParams.toString();
445
+ }
446
+ else {
447
+ pageUrl.search = window.location.search;
448
+ }
449
+ var url = pageUrl.pathname + pageUrl.search;
450
+ $(this.element).attr('data-url', url);
451
+ $(this.element).data('url', url);
430
452
  }
431
453
  if (!$(this.element).hasClass('refresh-only')) {
432
454
  var listUrl = document.createElement('a');
@@ -31713,8 +31735,328 @@
31713
31735
  return output;
31714
31736
  };
31715
31737
 
31738
+ var ContentController = /** @class */ (function () {
31739
+ function ContentController() {
31740
+ this.manage();
31741
+ $('body').on('click', '.content-create', this.create.bind(this));
31742
+ $('body').on('click', '.content-delete', this.delete.bind(this));
31743
+ $('body').on('click', '.content-set-status', this.setStatus.bind(this));
31744
+ $('body').on('click', '.content-categories-delete', this.deleteCategory.bind(this));
31745
+ $('body').on('click', '.content-categories-create,.content-categories-edit', this.createOrEditCategory.bind(this));
31746
+ $('body').on('change', '.content-categories-check', this.toggleCategory.bind(this));
31747
+ $('body').on('click', '.content-media-delete', this.removeMedia.bind(this));
31748
+ $('body').on('keyup', '#Slug', function () {
31749
+ var slugValue = $(this).val();
31750
+ $('.slug-display').html(slugValue);
31751
+ });
31752
+ }
31753
+ ContentController.prototype.manage = function () {
31754
+ this.element = document.getElementById('content-list');
31755
+ if (this.element) {
31756
+ this.list = new DataList(this.element, {
31757
+ onComplete: function (data, sender) {
31758
+ Alerts.log('Finished loading content list.', 'info');
31759
+ }.bind(this)
31760
+ });
31761
+ }
31762
+ this.categoryElement = document.getElementById('content-categories-list');
31763
+ if (this.categoryElement) {
31764
+ this.categoryList = new DataList(this.categoryElement, {
31765
+ onComplete: function (data, sender) {
31766
+ Alerts.log('Finished loading category list.', 'info');
31767
+ }.bind(this)
31768
+ });
31769
+ }
31770
+ };
31771
+ ContentController.prototype.create = function (e) {
31772
+ e.preventDefault();
31773
+ e.stopPropagation();
31774
+ var createContentModal = new ModalController({
31775
+ onComplete: function () {
31776
+ var form = document.getElementById('content-create-form');
31777
+ new Validator(form, {
31778
+ onComplete: function (response) {
31779
+ Response.process(response, 5000);
31780
+ if (this.list) {
31781
+ this.list.reload();
31782
+ }
31783
+ if (response.success) {
31784
+ createContentModal.close();
31785
+ }
31786
+ }.bind(this)
31787
+ });
31788
+ }.bind(this)
31789
+ });
31790
+ createContentModal.show($(e.currentTarget).attr('href'), this.element);
31791
+ };
31792
+ ContentController.prototype.delete = function (e) {
31793
+ e.preventDefault();
31794
+ e.stopPropagation();
31795
+ Alerts.confirm({
31796
+ // Confirm options...
31797
+ title: "Are you sure?",
31798
+ html: "The content will be permanently removed."
31799
+ }, function (result) {
31800
+ if (result.isConfirmed) {
31801
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
31802
+ Response.process(data, 5000);
31803
+ if (this.list) {
31804
+ this.list.reload();
31805
+ }
31806
+ if (e.currentTarget.dataset.redirect) {
31807
+ Alerts.message('Just taking you back to the content list.', 'Redirecting...');
31808
+ setTimeout(function () {
31809
+ window.location = e.currentTarget.dataset.redirect;
31810
+ }, 1500);
31811
+ }
31812
+ }.bind(this));
31813
+ }
31814
+ }.bind(this));
31815
+ };
31816
+ ContentController.prototype.setStatus = function (e) {
31817
+ e.preventDefault();
31818
+ e.stopPropagation();
31819
+ Alerts.confirm({
31820
+ // Confirm options...
31821
+ title: "Are you sure?",
31822
+ html: "The change will happen immediately."
31823
+ }, function (result) {
31824
+ if (result.isConfirmed) {
31825
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
31826
+ Response.process(data, 5000);
31827
+ if (this.list) {
31828
+ this.list.reload();
31829
+ }
31830
+ }.bind(this));
31831
+ }
31832
+ }.bind(this));
31833
+ };
31834
+ ContentController.prototype.clone = function (e) {
31835
+ e.preventDefault();
31836
+ e.stopPropagation();
31837
+ Alerts.confirm({
31838
+ // Confirm options...
31839
+ title: "Are you sure?",
31840
+ html: "This will duplicate the content and everything inside it."
31841
+ }, function (result) {
31842
+ if (result.isConfirmed) {
31843
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
31844
+ Response.process(data, 5000);
31845
+ if (this.list) {
31846
+ this.list.reload();
31847
+ }
31848
+ }.bind(this));
31849
+ }
31850
+ }.bind(this));
31851
+ };
31852
+ ContentController.prototype.createOrEditCategory = function (e) {
31853
+ e.preventDefault();
31854
+ e.stopPropagation();
31855
+ var createCategoryModal = new ModalController({
31856
+ onComplete: function () {
31857
+ var form = document.getElementById('content-categories-edit-form');
31858
+ new Validator(form, {
31859
+ onComplete: function (response) {
31860
+ Response.process(response, 5000);
31861
+ if (this.list) {
31862
+ this.list.reload();
31863
+ }
31864
+ if (response.success) {
31865
+ this.categoryList.reload();
31866
+ createCategoryModal.close();
31867
+ }
31868
+ }.bind(this)
31869
+ });
31870
+ }.bind(this)
31871
+ });
31872
+ createCategoryModal.show($(e.currentTarget).attr('href'), this.element);
31873
+ };
31874
+ ContentController.prototype.deleteCategory = function (e) {
31875
+ e.preventDefault();
31876
+ e.stopPropagation();
31877
+ Alerts.confirm({
31878
+ // Confirm options...
31879
+ }, function (result) {
31880
+ if (result.isConfirmed) {
31881
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
31882
+ // category deleted...
31883
+ Response.process(data, 5000);
31884
+ this.categoryList.reload();
31885
+ }.bind(this));
31886
+ }
31887
+ }.bind(this));
31888
+ };
31889
+ ContentController.prototype.toggleCategory = function (e) {
31890
+ e.preventDefault();
31891
+ e.stopPropagation();
31892
+ $.post($(e.currentTarget).data('url'), { categoryId: $(e.currentTarget).val(), add: $(e.currentTarget).is(':checked') }, function (response) {
31893
+ Response.process(response, 5000);
31894
+ if (this.categoryList) {
31895
+ this.categoryList.reload();
31896
+ }
31897
+ }.bind(this));
31898
+ };
31899
+ ContentController.prototype.removeMedia = function (e) {
31900
+ e.preventDefault();
31901
+ e.stopPropagation();
31902
+ Alerts.confirm({
31903
+ // Confirm options...
31904
+ title: "Are you sure?",
31905
+ html: "The media will be removed from the property, but will still be in the media collection."
31906
+ }, function (result) {
31907
+ if (result.isConfirmed) {
31908
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
31909
+ Response.process(data, 5000);
31910
+ // reload the property media gallery, should be attached to #property-gallery-list
31911
+ var mediaGalleryEl = document.getElementById('content-gallery-list');
31912
+ if (mediaGalleryEl.hoodDataList) {
31913
+ mediaGalleryEl.hoodDataList.reload();
31914
+ }
31915
+ }.bind(this));
31916
+ }
31917
+ }.bind(this));
31918
+ };
31919
+ return ContentController;
31920
+ }());
31921
+
31922
+ var ContentTypeController = /** @class */ (function () {
31923
+ function ContentTypeController() {
31924
+ this.manage();
31925
+ $('body').on('click', '.content-type-create', this.create.bind(this));
31926
+ $('body').on('click', '.content-type-delete', this.delete.bind(this));
31927
+ $('body').on('click', '.content-type-set-status', this.setStatus.bind(this));
31928
+ $('body').on('click', '.content-custom-field-create', this.createField.bind(this));
31929
+ $('body').on('click', '.content-custom-field-delete', this.deleteField.bind(this));
31930
+ $('body').on('keyup', '#Slug', function () {
31931
+ var slugValue = $(this).val();
31932
+ $('.slug-display').html(slugValue);
31933
+ });
31934
+ }
31935
+ ContentTypeController.prototype.manage = function () {
31936
+ this.element = document.getElementById('content-type-list');
31937
+ if (this.element) {
31938
+ this.list = new DataList(this.element, {
31939
+ onComplete: function (data, sender) {
31940
+ Alerts.log('Finished loading content type list.', 'info');
31941
+ }.bind(this)
31942
+ });
31943
+ }
31944
+ this.fieldsElement = document.getElementById('content-custom-field-list');
31945
+ if (this.fieldsElement) {
31946
+ this.fieldsList = new DataList(this.fieldsElement, {
31947
+ onComplete: function (data, sender) {
31948
+ Alerts.log('Finished loading content type list.', 'info');
31949
+ }.bind(this)
31950
+ });
31951
+ }
31952
+ };
31953
+ ContentTypeController.prototype.create = function (e) {
31954
+ e.preventDefault();
31955
+ e.stopPropagation();
31956
+ var createContentModal = new ModalController({
31957
+ onComplete: function () {
31958
+ var form = document.getElementById('content-type-create-form');
31959
+ new Validator(form, {
31960
+ onComplete: function (response) {
31961
+ Response.process(response, 5000);
31962
+ if (this.list) {
31963
+ this.list.reload();
31964
+ }
31965
+ if (response.success) {
31966
+ createContentModal.close();
31967
+ }
31968
+ }.bind(this)
31969
+ });
31970
+ }.bind(this)
31971
+ });
31972
+ createContentModal.show($(e.currentTarget).attr('href'), this.element);
31973
+ };
31974
+ ContentTypeController.prototype.delete = function (e) {
31975
+ e.preventDefault();
31976
+ e.stopPropagation();
31977
+ Alerts.confirm({
31978
+ // Confirm options...
31979
+ title: "Are you sure?",
31980
+ html: "The content type will be permanently removed. Content will remain, but will be unusable and marked as the old content type."
31981
+ }, function (result) {
31982
+ if (result.isConfirmed) {
31983
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
31984
+ Response.process(data, 5000);
31985
+ if (this.list) {
31986
+ this.list.reload();
31987
+ }
31988
+ if (e.currentTarget.dataset.redirect) {
31989
+ Alerts.message('Just taking you back to the content list.', 'Redirecting...');
31990
+ setTimeout(function () {
31991
+ window.location = e.currentTarget.dataset.redirect;
31992
+ }, 1500);
31993
+ }
31994
+ }.bind(this));
31995
+ }
31996
+ }.bind(this));
31997
+ };
31998
+ ContentTypeController.prototype.setStatus = function (e) {
31999
+ e.preventDefault();
32000
+ e.stopPropagation();
32001
+ Alerts.confirm({
32002
+ // Confirm options...
32003
+ title: "Are you sure?",
32004
+ html: "The change will happen immediately."
32005
+ }, function (result) {
32006
+ if (result.isConfirmed) {
32007
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
32008
+ Response.process(data, 5000);
32009
+ if (this.list) {
32010
+ this.list.reload();
32011
+ }
32012
+ }.bind(this));
32013
+ }
32014
+ }.bind(this));
32015
+ };
32016
+ ContentTypeController.prototype.createField = function (e) {
32017
+ e.preventDefault();
32018
+ e.stopPropagation();
32019
+ var createContentModal = new ModalController({
32020
+ onComplete: function () {
32021
+ var form = document.getElementById('content-custom-field-create-form');
32022
+ new Validator(form, {
32023
+ onComplete: function (response) {
32024
+ Response.process(response, 5000);
32025
+ if (this.fieldsList) {
32026
+ this.fieldsList.reload();
32027
+ }
32028
+ if (response.success) {
32029
+ createContentModal.close();
32030
+ }
32031
+ }.bind(this)
32032
+ });
32033
+ }.bind(this)
32034
+ });
32035
+ createContentModal.show($(e.currentTarget).attr('href'), this.element);
32036
+ };
32037
+ ContentTypeController.prototype.deleteField = function (e) {
32038
+ e.preventDefault();
32039
+ e.stopPropagation();
32040
+ Alerts.confirm({
32041
+ // Confirm options...
32042
+ title: "Are you sure?",
32043
+ html: "The field will be permanently removed. However fields will still be attached to content."
32044
+ }, function (result) {
32045
+ if (result.isConfirmed) {
32046
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
32047
+ Response.process(data, 5000);
32048
+ if (this.fieldsList) {
32049
+ this.fieldsList.reload();
32050
+ }
32051
+ }.bind(this));
32052
+ }
32053
+ }.bind(this));
32054
+ };
32055
+ return ContentTypeController;
32056
+ }());
32057
+
31716
32058
  /*!
31717
- * Chart.js v3.6.0
32059
+ * Chart.js v3.7.0
31718
32060
  * https://www.chartjs.org
31719
32061
  * (c) 2021 Chart.js Contributors
31720
32062
  * Released under the MIT License
@@ -31934,6 +32276,9 @@
31934
32276
  }
31935
32277
  return true;
31936
32278
  };
32279
+ function _isClickEvent(e) {
32280
+ return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';
32281
+ }
31937
32282
 
31938
32283
  const PI = Math.PI;
31939
32284
  const TAU = 2 * PI;
@@ -32046,6 +32391,9 @@
32046
32391
  function _int16Range(value) {
32047
32392
  return _limitValue(value, -32768, 32767);
32048
32393
  }
32394
+ function _isBetween(value, start, end, epsilon = 1e-6) {
32395
+ return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
32396
+ }
32049
32397
 
32050
32398
  const atEdge = (t) => t === 0 || t === 1;
32051
32399
  const elasticIn = (t, s, p) => -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * TAU / p));
@@ -32755,6 +33103,7 @@
32755
33103
  this.scale = undefined;
32756
33104
  this.scales = {};
32757
33105
  this.showLine = true;
33106
+ this.drawActiveElementsOnTop = true;
32758
33107
  this.describe(_descriptors);
32759
33108
  }
32760
33109
  set(scope, values) {
@@ -33105,7 +33454,7 @@
33105
33454
  }
33106
33455
  return size * value;
33107
33456
  }
33108
- const numberOrZero$1 = v => +v || 0;
33457
+ const numberOrZero = v => +v || 0;
33109
33458
  function _readValueToProps(value, props) {
33110
33459
  const ret = {};
33111
33460
  const objProps = isObject(props);
@@ -33116,7 +33465,7 @@
33116
33465
  : prop => value[prop]
33117
33466
  : () => value;
33118
33467
  for (const prop of keys) {
33119
- ret[prop] = numberOrZero$1(read(prop));
33468
+ ret[prop] = numberOrZero(read(prop));
33120
33469
  }
33121
33470
  return ret;
33122
33471
  }
@@ -33323,8 +33672,7 @@
33323
33672
  },
33324
33673
  set(target, prop, value) {
33325
33674
  const storage = target._storage || (target._storage = getTarget());
33326
- storage[prop] = value;
33327
- delete target[prop];
33675
+ target[prop] = storage[prop] = value;
33328
33676
  delete target._keys;
33329
33677
  return true;
33330
33678
  }
@@ -33383,7 +33731,8 @@
33383
33731
  };
33384
33732
  }
33385
33733
  const readKey = (prefix, name) => prefix ? prefix + _capitalize(name) : name;
33386
- const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters';
33734
+ const needsSubResolver = (prop, value) => isObject(value) && prop !== 'adapters' &&
33735
+ (Object.getPrototypeOf(value) === null || value.constructor === Object);
33387
33736
  function _cached(target, prop, resolve) {
33388
33737
  if (Object.prototype.hasOwnProperty.call(target, prop)) {
33389
33738
  return target[prop];
@@ -33414,7 +33763,7 @@
33414
33763
  _stack.add(prop);
33415
33764
  value = value(_context, _subProxy || receiver);
33416
33765
  _stack.delete(prop);
33417
- if (isObject(value)) {
33766
+ if (needsSubResolver(prop, value)) {
33418
33767
  value = createSubResolver(_proxy._scopes, _proxy, prop, value);
33419
33768
  }
33420
33769
  return value;
@@ -33439,12 +33788,12 @@
33439
33788
  }
33440
33789
  const getScope = (key, parent) => key === true ? parent
33441
33790
  : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
33442
- function addScopes(set, parentScopes, key, parentFallback) {
33791
+ function addScopes(set, parentScopes, key, parentFallback, value) {
33443
33792
  for (const parent of parentScopes) {
33444
33793
  const scope = getScope(key, parent);
33445
33794
  if (scope) {
33446
33795
  set.add(scope);
33447
- const fallback = resolveFallback(scope._fallback, key, scope);
33796
+ const fallback = resolveFallback(scope._fallback, key, value);
33448
33797
  if (defined(fallback) && fallback !== key && fallback !== parentFallback) {
33449
33798
  return fallback;
33450
33799
  }
@@ -33460,12 +33809,12 @@
33460
33809
  const allScopes = [...parentScopes, ...rootScopes];
33461
33810
  const set = new Set();
33462
33811
  set.add(value);
33463
- let key = addScopesFromKey(set, allScopes, prop, fallback || prop);
33812
+ let key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);
33464
33813
  if (key === null) {
33465
33814
  return false;
33466
33815
  }
33467
33816
  if (defined(fallback) && fallback !== prop) {
33468
- key = addScopesFromKey(set, allScopes, fallback, key);
33817
+ key = addScopesFromKey(set, allScopes, fallback, key, value);
33469
33818
  if (key === null) {
33470
33819
  return false;
33471
33820
  }
@@ -33473,9 +33822,9 @@
33473
33822
  return _createResolver(Array.from(set), [''], rootScopes, fallback,
33474
33823
  () => subGetTarget(resolver, prop, value));
33475
33824
  }
33476
- function addScopesFromKey(set, allScopes, key, fallback) {
33825
+ function addScopesFromKey(set, allScopes, key, fallback, item) {
33477
33826
  while (key) {
33478
- key = addScopes(set, allScopes, key, fallback);
33827
+ key = addScopes(set, allScopes, key, fallback, item);
33479
33828
  }
33480
33829
  return key;
33481
33830
  }
@@ -33966,7 +34315,7 @@
33966
34315
  };
33967
34316
  }
33968
34317
  return {
33969
- between: (n, s, e) => n >= Math.min(s, e) && n <= Math.max(e, s),
34318
+ between: _isBetween,
33970
34319
  compare: (a, b) => a - b,
33971
34320
  normalize: x => x
33972
34321
  };
@@ -34194,7 +34543,7 @@
34194
34543
  }
34195
34544
 
34196
34545
  /*!
34197
- * Chart.js v3.6.0
34546
+ * Chart.js v3.7.0
34198
34547
  * https://www.chartjs.org
34199
34548
  * (c) 2021 Chart.js Contributors
34200
34549
  * Released under the MIT License
@@ -34919,6 +35268,7 @@
34919
35268
  const scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true);
34920
35269
  this.options = config.createResolver(scopes, this.getContext());
34921
35270
  this._parsing = this.options.parsing;
35271
+ this._cachedDataOpts = {};
34922
35272
  }
34923
35273
  parse(start, count) {
34924
35274
  const {_cachedMeta: meta, _data: data} = this;
@@ -35090,8 +35440,6 @@
35090
35440
  }
35091
35441
  _update(mode) {
35092
35442
  const meta = this._cachedMeta;
35093
- this.configure();
35094
- this._cachedDataOpts = {};
35095
35443
  this.update(mode || 'default');
35096
35444
  meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow())));
35097
35445
  }
@@ -35105,6 +35453,7 @@
35105
35453
  const active = [];
35106
35454
  const start = this._drawStart || 0;
35107
35455
  const count = this._drawCount || (elements.length - start);
35456
+ const drawActiveElementsOnTop = this.options.drawActiveElementsOnTop;
35108
35457
  let i;
35109
35458
  if (meta.dataset) {
35110
35459
  meta.dataset.draw(ctx, area, start, count);
@@ -35114,7 +35463,7 @@
35114
35463
  if (element.hidden) {
35115
35464
  continue;
35116
35465
  }
35117
- if (element.active) {
35466
+ if (element.active && drawActiveElementsOnTop) {
35118
35467
  active.push(element);
35119
35468
  } else {
35120
35469
  element.draw(ctx, area);
@@ -35305,6 +35654,7 @@
35305
35654
  const [method, arg1, arg2] = args;
35306
35655
  this[method](arg1, arg2);
35307
35656
  }
35657
+ this.chart._dataChanges.push([this.index, ...args]);
35308
35658
  }
35309
35659
  _onDataPush() {
35310
35660
  const count = arguments.length;
@@ -35317,8 +35667,13 @@
35317
35667
  this._sync(['_removeElements', 0, 1]);
35318
35668
  }
35319
35669
  _onDataSplice(start, count) {
35320
- this._sync(['_removeElements', start, count]);
35321
- this._sync(['_insertElements', start, arguments.length - 2]);
35670
+ if (count) {
35671
+ this._sync(['_removeElements', start, count]);
35672
+ }
35673
+ const newCount = arguments.length - 2;
35674
+ if (newCount) {
35675
+ this._sync(['_insertElements', start, newCount]);
35676
+ }
35322
35677
  }
35323
35678
  _onDataUnshift() {
35324
35679
  this._sync(['_insertElements', 0, arguments.length]);
@@ -36098,9 +36453,6 @@
36098
36453
  meta = chart.getDatasetMeta(i);
36099
36454
  arcs = meta.data;
36100
36455
  controller = meta.controller;
36101
- if (controller !== this) {
36102
- controller.configure();
36103
- }
36104
36456
  break;
36105
36457
  }
36106
36458
  }
@@ -36705,7 +37057,7 @@
36705
37057
  function binarySearch(metaset, axis, value, intersect) {
36706
37058
  const {controller, data, _sorted} = metaset;
36707
37059
  const iScale = controller._cachedMeta.iScale;
36708
- if (iScale && axis === iScale.axis && _sorted && data.length) {
37060
+ if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {
36709
37061
  const lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;
36710
37062
  if (!intersect) {
36711
37063
  return lookupMethod(data, axis, value);
@@ -36757,19 +37109,30 @@
36757
37109
  optimizedEvaluateItems(chart, axis, position, evaluationFunc, true);
36758
37110
  return items;
36759
37111
  }
36760
- function getNearestItems(chart, position, axis, intersect, useFinalPosition) {
36761
- const distanceMetric = getDistanceMetricForAxis(axis);
36762
- let minDistance = Number.POSITIVE_INFINITY;
37112
+ function getNearestRadialItems(chart, position, axis, useFinalPosition) {
36763
37113
  let items = [];
36764
- if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
36765
- return items;
37114
+ function evaluationFunc(element, datasetIndex, index) {
37115
+ const {startAngle, endAngle} = element.getProps(['startAngle', 'endAngle'], useFinalPosition);
37116
+ const {angle} = getAngleFromPoint(element, {x: position.x, y: position.y});
37117
+ if (_angleBetween(angle, startAngle, endAngle)) {
37118
+ items.push({element, datasetIndex, index});
37119
+ }
36766
37120
  }
36767
- const evaluationFunc = function(element, datasetIndex, index) {
36768
- if (intersect && !element.inRange(position.x, position.y, useFinalPosition)) {
37121
+ optimizedEvaluateItems(chart, axis, position, evaluationFunc);
37122
+ return items;
37123
+ }
37124
+ function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition) {
37125
+ let items = [];
37126
+ const distanceMetric = getDistanceMetricForAxis(axis);
37127
+ let minDistance = Number.POSITIVE_INFINITY;
37128
+ function evaluationFunc(element, datasetIndex, index) {
37129
+ const inRange = element.inRange(position.x, position.y, useFinalPosition);
37130
+ if (intersect && !inRange) {
36769
37131
  return;
36770
37132
  }
36771
37133
  const center = element.getCenterPoint(useFinalPosition);
36772
- if (!_isPointInArea(center, chart.chartArea, chart._minPadding) && !element.inRange(position.x, position.y, useFinalPosition)) {
37134
+ const pointInArea = _isPointInArea(center, chart.chartArea, chart._minPadding);
37135
+ if (!pointInArea && !inRange) {
36773
37136
  return;
36774
37137
  }
36775
37138
  const distance = distanceMetric(position, center);
@@ -36779,10 +37142,18 @@
36779
37142
  } else if (distance === minDistance) {
36780
37143
  items.push({element, datasetIndex, index});
36781
37144
  }
36782
- };
37145
+ }
36783
37146
  optimizedEvaluateItems(chart, axis, position, evaluationFunc);
36784
37147
  return items;
36785
37148
  }
37149
+ function getNearestItems(chart, position, axis, intersect, useFinalPosition) {
37150
+ if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
37151
+ return [];
37152
+ }
37153
+ return axis === 'r' && !intersect
37154
+ ? getNearestRadialItems(chart, position, axis, useFinalPosition)
37155
+ : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition);
37156
+ }
36786
37157
  function getAxisItems(chart, e, options, useFinalPosition) {
36787
37158
  const position = getRelativePosition(e, chart);
36788
37159
  const items = [];
@@ -36850,12 +37221,10 @@
36850
37221
  return getNearestItems(chart, position, axis, options.intersect, useFinalPosition);
36851
37222
  },
36852
37223
  x(chart, e, options, useFinalPosition) {
36853
- options.axis = 'x';
36854
- return getAxisItems(chart, e, options, useFinalPosition);
37224
+ return getAxisItems(chart, e, {axis: 'x', intersect: options.intersect}, useFinalPosition);
36855
37225
  },
36856
37226
  y(chart, e, options, useFinalPosition) {
36857
- options.axis = 'y';
36858
- return getAxisItems(chart, e, options, useFinalPosition);
37227
+ return getAxisItems(chart, e, {axis: 'y', intersect: options.intersect}, useFinalPosition);
36859
37228
  }
36860
37229
  }
36861
37230
  };
@@ -37166,7 +37535,7 @@
37166
37535
  each(boxes.chartArea, (layout) => {
37167
37536
  const box = layout.box;
37168
37537
  Object.assign(box, chart.chartArea);
37169
- box.update(chartArea.w, chartArea.h);
37538
+ box.update(chartArea.w, chartArea.h, {left: 0, top: 0, right: 0, bottom: 0});
37170
37539
  });
37171
37540
  }
37172
37541
  };
@@ -37271,15 +37640,23 @@
37271
37640
  y: y !== undefined ? y : null,
37272
37641
  };
37273
37642
  }
37643
+ function nodeListContains(nodeList, canvas) {
37644
+ for (const node of nodeList) {
37645
+ if (node === canvas || node.contains(canvas)) {
37646
+ return true;
37647
+ }
37648
+ }
37649
+ }
37274
37650
  function createAttachObserver(chart, type, listener) {
37275
37651
  const canvas = chart.canvas;
37276
37652
  const observer = new MutationObserver(entries => {
37653
+ let trigger = false;
37277
37654
  for (const entry of entries) {
37278
- for (const node of entry.addedNodes) {
37279
- if (node === canvas || node.contains(canvas)) {
37280
- return listener();
37281
- }
37282
- }
37655
+ trigger = trigger || nodeListContains(entry.addedNodes, canvas);
37656
+ trigger = trigger && !nodeListContains(entry.removedNodes, canvas);
37657
+ }
37658
+ if (trigger) {
37659
+ listener();
37283
37660
  }
37284
37661
  });
37285
37662
  observer.observe(document, {childList: true, subtree: true});
@@ -37288,12 +37665,13 @@
37288
37665
  function createDetachObserver(chart, type, listener) {
37289
37666
  const canvas = chart.canvas;
37290
37667
  const observer = new MutationObserver(entries => {
37668
+ let trigger = false;
37291
37669
  for (const entry of entries) {
37292
- for (const node of entry.removedNodes) {
37293
- if (node === canvas || node.contains(canvas)) {
37294
- return listener();
37295
- }
37296
- }
37670
+ trigger = trigger || nodeListContains(entry.removedNodes, canvas);
37671
+ trigger = trigger && !nodeListContains(entry.addedNodes, canvas);
37672
+ }
37673
+ if (trigger) {
37674
+ listener();
37297
37675
  }
37298
37676
  });
37299
37677
  observer.observe(document, {childList: true, subtree: true});
@@ -39059,7 +39437,7 @@
39059
39437
  }
39060
39438
  const descriptors = filter ? this._descriptors(chart).filter(filter) : this._descriptors(chart);
39061
39439
  const result = this._notify(descriptors, chart, hook, args);
39062
- if (hook === 'destroy') {
39440
+ if (hook === 'afterDestroy') {
39063
39441
  this._notify(descriptors, chart, 'stop');
39064
39442
  this._notify(this._init, chart, 'uninstall');
39065
39443
  }
@@ -39435,7 +39813,7 @@
39435
39813
  return false;
39436
39814
  }
39437
39815
 
39438
- var version = "3.6.0";
39816
+ var version = "3.7.0";
39439
39817
 
39440
39818
  const KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
39441
39819
  function positionIsHorizontal(position, axis) {
@@ -39475,6 +39853,28 @@
39475
39853
  const canvas = getCanvas(key);
39476
39854
  return Object.values(instances).filter((c) => c.canvas === canvas).pop();
39477
39855
  };
39856
+ function moveNumericKeys(obj, start, move) {
39857
+ const keys = Object.keys(obj);
39858
+ for (const key of keys) {
39859
+ const intKey = +key;
39860
+ if (intKey >= start) {
39861
+ const value = obj[key];
39862
+ delete obj[key];
39863
+ if (move > 0 || intKey > start) {
39864
+ obj[intKey + move] = value;
39865
+ }
39866
+ }
39867
+ }
39868
+ }
39869
+ function determineLastEvent(e, lastEvent, inChartArea, isClick) {
39870
+ if (!inChartArea || e.type === 'mouseout') {
39871
+ return null;
39872
+ }
39873
+ if (isClick) {
39874
+ return lastEvent;
39875
+ }
39876
+ return e;
39877
+ }
39478
39878
  class Chart {
39479
39879
  constructor(item, userConfig) {
39480
39880
  const config = this.config = new Config(userConfig);
@@ -39519,6 +39919,7 @@
39519
39919
  this._animationsDisabled = undefined;
39520
39920
  this.$context = undefined;
39521
39921
  this._doResize = debounce(mode => this.update(mode), options.resizeDelay || 0);
39922
+ this._dataChanges = [];
39522
39923
  instances[this.id] = this;
39523
39924
  if (!context || !canvas) {
39524
39925
  console.error("Failed to create chart: can't acquire context from the given item");
@@ -39738,18 +40139,10 @@
39738
40139
  const config = this.config;
39739
40140
  config.update();
39740
40141
  const options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext());
39741
- each(this.scales, (scale) => {
39742
- layouts.removeBox(this, scale);
39743
- });
39744
40142
  const animsDisabled = this._animationsDisabled = !options.animation;
39745
- this.ensureScalesHaveIDs();
39746
- this.buildOrUpdateScales();
39747
- const existingEvents = new Set(Object.keys(this._listeners));
39748
- const newEvents = new Set(options.events);
39749
- if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
39750
- this.unbindEvents();
39751
- this.bindEvents();
39752
- }
40143
+ this._updateScales();
40144
+ this._checkEventBindings();
40145
+ this._updateHiddenIndices();
39753
40146
  this._plugins.invalidate();
39754
40147
  if (this.notifyPlugins('beforeUpdate', {mode, cancelable: true}) === false) {
39755
40148
  return;
@@ -39773,11 +40166,60 @@
39773
40166
  this._updateDatasets(mode);
39774
40167
  this.notifyPlugins('afterUpdate', {mode});
39775
40168
  this._layers.sort(compare2Level('z', '_idx'));
39776
- if (this._lastEvent) {
39777
- this._eventHandler(this._lastEvent, true);
40169
+ const {_active, _lastEvent} = this;
40170
+ if (_lastEvent) {
40171
+ this._eventHandler(_lastEvent, true);
40172
+ } else if (_active.length) {
40173
+ this._updateHoverStyles(_active, _active, true);
39778
40174
  }
39779
40175
  this.render();
39780
40176
  }
40177
+ _updateScales() {
40178
+ each(this.scales, (scale) => {
40179
+ layouts.removeBox(this, scale);
40180
+ });
40181
+ this.ensureScalesHaveIDs();
40182
+ this.buildOrUpdateScales();
40183
+ }
40184
+ _checkEventBindings() {
40185
+ const options = this.options;
40186
+ const existingEvents = new Set(Object.keys(this._listeners));
40187
+ const newEvents = new Set(options.events);
40188
+ if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
40189
+ this.unbindEvents();
40190
+ this.bindEvents();
40191
+ }
40192
+ }
40193
+ _updateHiddenIndices() {
40194
+ const {_hiddenIndices} = this;
40195
+ const changes = this._getUniformDataChanges() || [];
40196
+ for (const {method, start, count} of changes) {
40197
+ const move = method === '_removeElements' ? -count : count;
40198
+ moveNumericKeys(_hiddenIndices, start, move);
40199
+ }
40200
+ }
40201
+ _getUniformDataChanges() {
40202
+ const _dataChanges = this._dataChanges;
40203
+ if (!_dataChanges || !_dataChanges.length) {
40204
+ return;
40205
+ }
40206
+ this._dataChanges = [];
40207
+ const datasetCount = this.data.datasets.length;
40208
+ const makeSet = (idx) => new Set(
40209
+ _dataChanges
40210
+ .filter(c => c[0] === idx)
40211
+ .map((c, i) => i + ',' + c.splice(1).join(','))
40212
+ );
40213
+ const changeSet = makeSet(0);
40214
+ for (let i = 1; i < datasetCount; i++) {
40215
+ if (!setsEqual(changeSet, makeSet(i))) {
40216
+ return;
40217
+ }
40218
+ }
40219
+ return Array.from(changeSet)
40220
+ .map(c => c.split(','))
40221
+ .map(a => ({method: a[1], start: +a[2], count: +a[3]}));
40222
+ }
39781
40223
  _updateLayout(minPadding) {
39782
40224
  if (this.notifyPlugins('beforeLayout', {cancelable: true}) === false) {
39783
40225
  return;
@@ -39804,6 +40246,9 @@
39804
40246
  if (this.notifyPlugins('beforeDatasetsUpdate', {mode, cancelable: true}) === false) {
39805
40247
  return;
39806
40248
  }
40249
+ for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
40250
+ this.getDatasetMeta(i).controller.configure();
40251
+ }
39807
40252
  for (let i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
39808
40253
  this._updateDataset(i, isFunction(mode) ? mode({datasetIndex: i}) : mode);
39809
40254
  }
@@ -39998,6 +40443,7 @@
39998
40443
  }
39999
40444
  }
40000
40445
  destroy() {
40446
+ this.notifyPlugins('beforeDestroy');
40001
40447
  const {canvas, ctx} = this;
40002
40448
  this._stop();
40003
40449
  this.config.clearCache();
@@ -40010,6 +40456,7 @@
40010
40456
  }
40011
40457
  this.notifyPlugins('destroy');
40012
40458
  delete instances[this.id];
40459
+ this.notifyPlugins('afterDestroy');
40013
40460
  }
40014
40461
  toBase64Image(...args) {
40015
40462
  return this.canvas.toDataURL(...args);
@@ -40122,6 +40569,7 @@
40122
40569
  const changed = !_elementsEqual(active, lastActive);
40123
40570
  if (changed) {
40124
40571
  this._active = active;
40572
+ this._lastEvent = null;
40125
40573
  this._updateHoverStyles(active, lastActive);
40126
40574
  }
40127
40575
  }
@@ -40141,12 +40589,17 @@
40141
40589
  }
40142
40590
  }
40143
40591
  _eventHandler(e, replay) {
40144
- const args = {event: e, replay, cancelable: true};
40592
+ const args = {
40593
+ event: e,
40594
+ replay,
40595
+ cancelable: true,
40596
+ inChartArea: _isPointInArea(e, this.chartArea, this._minPadding)
40597
+ };
40145
40598
  const eventFilter = (plugin) => (plugin.options.events || this.options.events).includes(e.native.type);
40146
40599
  if (this.notifyPlugins('beforeEvent', args, eventFilter) === false) {
40147
40600
  return;
40148
40601
  }
40149
- const changed = this._handleEvent(e, replay);
40602
+ const changed = this._handleEvent(e, replay, args.inChartArea);
40150
40603
  args.cancelable = false;
40151
40604
  this.notifyPlugins('afterEvent', args, eventFilter);
40152
40605
  if (changed || args.changed) {
@@ -40154,25 +40607,20 @@
40154
40607
  }
40155
40608
  return this;
40156
40609
  }
40157
- _handleEvent(e, replay) {
40610
+ _handleEvent(e, replay, inChartArea) {
40158
40611
  const {_active: lastActive = [], options} = this;
40159
- const hoverOptions = options.hover;
40160
40612
  const useFinalPosition = replay;
40161
- let active = [];
40162
- let changed = false;
40163
- let lastEvent = null;
40164
- if (e.type !== 'mouseout') {
40165
- active = this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
40166
- lastEvent = e.type === 'click' ? this._lastEvent : e;
40167
- }
40168
- this._lastEvent = null;
40169
- if (_isPointInArea(e, this.chartArea, this._minPadding)) {
40613
+ const active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition);
40614
+ const isClick = _isClickEvent(e);
40615
+ const lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick);
40616
+ if (inChartArea) {
40617
+ this._lastEvent = null;
40170
40618
  callback(options.onHover, [e, active, this], this);
40171
- if (e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu') {
40619
+ if (isClick) {
40172
40620
  callback(options.onClick, [e, active, this], this);
40173
40621
  }
40174
40622
  }
40175
- changed = !_elementsEqual(active, lastActive);
40623
+ const changed = !_elementsEqual(active, lastActive);
40176
40624
  if (changed || replay) {
40177
40625
  this._active = active;
40178
40626
  this._updateHoverStyles(active, lastActive, replay);
@@ -40180,6 +40628,16 @@
40180
40628
  this._lastEvent = lastEvent;
40181
40629
  return changed;
40182
40630
  }
40631
+ _getActiveElements(e, lastActive, inChartArea, useFinalPosition) {
40632
+ if (e.type === 'mouseout') {
40633
+ return [];
40634
+ }
40635
+ if (!inChartArea) {
40636
+ return lastActive;
40637
+ }
40638
+ const hoverOptions = this.options.hover;
40639
+ return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
40640
+ }
40183
40641
  }
40184
40642
  const invalidatePlugins = () => each(Chart.instances, (chart) => chart._plugins.invalidate());
40185
40643
  const enumerable = true;
@@ -40353,16 +40811,17 @@
40353
40811
  }
40354
40812
  function drawBorder(ctx, element, offset, spacing, endAngle) {
40355
40813
  const {options} = element;
40814
+ const {borderWidth, borderJoinStyle} = options;
40356
40815
  const inner = options.borderAlign === 'inner';
40357
- if (!options.borderWidth) {
40816
+ if (!borderWidth) {
40358
40817
  return;
40359
40818
  }
40360
40819
  if (inner) {
40361
- ctx.lineWidth = options.borderWidth * 2;
40362
- ctx.lineJoin = 'round';
40820
+ ctx.lineWidth = borderWidth * 2;
40821
+ ctx.lineJoin = borderJoinStyle || 'round';
40363
40822
  } else {
40364
- ctx.lineWidth = options.borderWidth;
40365
- ctx.lineJoin = 'bevel';
40823
+ ctx.lineWidth = borderWidth;
40824
+ ctx.lineJoin = borderJoinStyle || 'bevel';
40366
40825
  }
40367
40826
  if (element.fullCircles) {
40368
40827
  drawFullCircleBorders(ctx, element, inner);
@@ -40399,8 +40858,9 @@
40399
40858
  'circumference'
40400
40859
  ], useFinalPosition);
40401
40860
  const rAdjust = this.options.spacing / 2;
40402
- const betweenAngles = circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
40403
- const withinRadius = (distance >= innerRadius + rAdjust && distance <= outerRadius + rAdjust);
40861
+ const _circumference = valueOrDefault(circumference, endAngle - startAngle);
40862
+ const betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
40863
+ const withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust);
40404
40864
  return (betweenAngles && withinRadius);
40405
40865
  }
40406
40866
  getCenterPoint(useFinalPosition) {
@@ -40454,6 +40914,7 @@
40454
40914
  ArcElement.defaults = {
40455
40915
  borderAlign: 'center',
40456
40916
  borderColor: '#fff',
40917
+ borderJoinStyle: undefined,
40457
40918
  borderRadius: 0,
40458
40919
  borderWidth: 2,
40459
40920
  offset: 0,
@@ -40888,8 +41349,8 @@
40888
41349
  const skipBoth = skipX && skipY;
40889
41350
  const bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition);
40890
41351
  return bounds
40891
- && (skipX || x >= bounds.left && x <= bounds.right)
40892
- && (skipY || y >= bounds.top && y <= bounds.bottom);
41352
+ && (skipX || _isBetween(x, bounds.left, bounds.right))
41353
+ && (skipY || _isBetween(y, bounds.top, bounds.bottom));
40893
41354
  }
40894
41355
  function hasRadius(radius) {
40895
41356
  return radius.topLeft || radius.topRight || radius.bottomLeft || radius.bottomRight;
@@ -41061,7 +41522,7 @@
41061
41522
  };
41062
41523
  }
41063
41524
  function getTooltipSize(tooltip, options) {
41064
- const ctx = tooltip._chart.ctx;
41525
+ const ctx = tooltip.chart.ctx;
41065
41526
  const {body, footer, title} = tooltip;
41066
41527
  const {boxWidth, boxHeight} = options;
41067
41528
  const bodyFont = toFont(options.bodyFont);
@@ -41149,9 +41610,9 @@
41149
41610
  return xAlign;
41150
41611
  }
41151
41612
  function determineAlignment(chart, options, size) {
41152
- const yAlign = options.yAlign || determineYAlign(chart, size);
41613
+ const yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size);
41153
41614
  return {
41154
- xAlign: options.xAlign || determineXAlign(chart, options, size, yAlign),
41615
+ xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign),
41155
41616
  yAlign
41156
41617
  };
41157
41618
  }
@@ -41189,9 +41650,9 @@
41189
41650
  x -= paddingAndSize;
41190
41651
  }
41191
41652
  } else if (xAlign === 'left') {
41192
- x -= Math.max(topLeft, bottomLeft) + caretPadding;
41653
+ x -= Math.max(topLeft, bottomLeft) + caretSize;
41193
41654
  } else if (xAlign === 'right') {
41194
- x += Math.max(topRight, bottomRight) + caretPadding;
41655
+ x += Math.max(topRight, bottomRight) + caretSize;
41195
41656
  }
41196
41657
  return {
41197
41658
  x: _limitValue(x, 0, chart.width - size.width),
@@ -41225,13 +41686,14 @@
41225
41686
  super();
41226
41687
  this.opacity = 0;
41227
41688
  this._active = [];
41228
- this._chart = config._chart;
41229
41689
  this._eventPosition = undefined;
41230
41690
  this._size = undefined;
41231
41691
  this._cachedAnimations = undefined;
41232
41692
  this._tooltipItems = [];
41233
41693
  this.$animations = undefined;
41234
41694
  this.$context = undefined;
41695
+ this.chart = config.chart || config._chart;
41696
+ this._chart = this.chart;
41235
41697
  this.options = config.options;
41236
41698
  this.dataPoints = undefined;
41237
41699
  this.title = undefined;
@@ -41261,10 +41723,10 @@
41261
41723
  if (cached) {
41262
41724
  return cached;
41263
41725
  }
41264
- const chart = this._chart;
41726
+ const chart = this.chart;
41265
41727
  const options = this.options.setContext(this.getContext());
41266
41728
  const opts = options.enabled && chart.options.animation && options.animations;
41267
- const animations = new Animations(this._chart, opts);
41729
+ const animations = new Animations(this.chart, opts);
41268
41730
  if (opts._cacheable) {
41269
41731
  this._cachedAnimations = Object.freeze(animations);
41270
41732
  }
@@ -41272,7 +41734,7 @@
41272
41734
  }
41273
41735
  getContext() {
41274
41736
  return this.$context ||
41275
- (this.$context = createTooltipContext(this._chart.getContext(), this, this._tooltipItems));
41737
+ (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems));
41276
41738
  }
41277
41739
  getTitle(context, options) {
41278
41740
  const {callbacks} = options;
@@ -41321,14 +41783,14 @@
41321
41783
  }
41322
41784
  _createItems(options) {
41323
41785
  const active = this._active;
41324
- const data = this._chart.data;
41786
+ const data = this.chart.data;
41325
41787
  const labelColors = [];
41326
41788
  const labelPointStyles = [];
41327
41789
  const labelTextColors = [];
41328
41790
  let tooltipItems = [];
41329
41791
  let i, len;
41330
41792
  for (i = 0, len = active.length; i < len; ++i) {
41331
- tooltipItems.push(createTooltipItem(this._chart, active[i]));
41793
+ tooltipItems.push(createTooltipItem(this.chart, active[i]));
41332
41794
  }
41333
41795
  if (options.filter) {
41334
41796
  tooltipItems = tooltipItems.filter((element, index, array) => options.filter(element, index, array, data));
@@ -41369,8 +41831,8 @@
41369
41831
  this.footer = this.getFooter(tooltipItems, options);
41370
41832
  const size = this._size = getTooltipSize(this, options);
41371
41833
  const positionAndSize = Object.assign({}, position, size);
41372
- const alignment = determineAlignment(this._chart, options, positionAndSize);
41373
- const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this._chart);
41834
+ const alignment = determineAlignment(this.chart, options, positionAndSize);
41835
+ const backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart);
41374
41836
  this.xAlign = alignment.xAlign;
41375
41837
  this.yAlign = alignment.yAlign;
41376
41838
  properties = {
@@ -41389,7 +41851,7 @@
41389
41851
  this._resolveAnimations().update(this, properties);
41390
41852
  }
41391
41853
  if (changed && options.external) {
41392
- options.external.call(this, {chart: this._chart, tooltip: this, replay});
41854
+ options.external.call(this, {chart: this.chart, tooltip: this, replay});
41393
41855
  }
41394
41856
  }
41395
41857
  drawCaret(tooltipPoint, ctx, size, options) {
@@ -41627,7 +42089,7 @@
41627
42089
  }
41628
42090
  }
41629
42091
  _updateAnimationTarget(options) {
41630
- const chart = this._chart;
42092
+ const chart = this.chart;
41631
42093
  const anims = this.$animations;
41632
42094
  const animX = anims && anims.x;
41633
42095
  const animY = anims && anims.y;
@@ -41688,7 +42150,7 @@
41688
42150
  setActiveElements(activeElements, eventPosition) {
41689
42151
  const lastActive = this._active;
41690
42152
  const active = activeElements.map(({datasetIndex, index}) => {
41691
- const meta = this._chart.getDatasetMeta(datasetIndex);
42153
+ const meta = this.chart.getDatasetMeta(datasetIndex);
41692
42154
  if (!meta) {
41693
42155
  throw new Error('Cannot find a dataset at index ' + datasetIndex);
41694
42156
  }
@@ -41703,22 +42165,20 @@
41703
42165
  if (changed || positionChanged) {
41704
42166
  this._active = active;
41705
42167
  this._eventPosition = eventPosition;
42168
+ this._ignoreReplayEvents = true;
41706
42169
  this.update(true);
41707
42170
  }
41708
42171
  }
41709
- handleEvent(e, replay) {
42172
+ handleEvent(e, replay, inChartArea = true) {
42173
+ if (replay && this._ignoreReplayEvents) {
42174
+ return false;
42175
+ }
42176
+ this._ignoreReplayEvents = false;
41710
42177
  const options = this.options;
41711
42178
  const lastActive = this._active || [];
41712
- let changed = false;
41713
- let active = [];
41714
- if (e.type !== 'mouseout') {
41715
- active = this._chart.getElementsAtEventForMode(e, options.mode, options, replay);
41716
- if (options.reverse) {
41717
- active.reverse();
41718
- }
41719
- }
42179
+ const active = this._getActiveElements(e, lastActive, replay, inChartArea);
41720
42180
  const positionChanged = this._positionChanged(active, e);
41721
- changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
42181
+ const changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
41722
42182
  if (changed) {
41723
42183
  this._active = active;
41724
42184
  if (options.enabled || options.external) {
@@ -41731,6 +42191,20 @@
41731
42191
  }
41732
42192
  return changed;
41733
42193
  }
42194
+ _getActiveElements(e, lastActive, replay, inChartArea) {
42195
+ const options = this.options;
42196
+ if (e.type === 'mouseout') {
42197
+ return [];
42198
+ }
42199
+ if (!inChartArea) {
42200
+ return lastActive;
42201
+ }
42202
+ const active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay);
42203
+ if (options.reverse) {
42204
+ active.reverse();
42205
+ }
42206
+ return active;
42207
+ }
41734
42208
  _positionChanged(active, e) {
41735
42209
  const {caretX, caretY, options} = this;
41736
42210
  const position = positioners[options.position].call(this, active, e);
@@ -41739,13 +42213,19 @@
41739
42213
  }
41740
42214
  Tooltip.positioners = positioners;
41741
42215
 
41742
- const addIfString = (labels, raw, index) => typeof raw === 'string'
41743
- ? labels.push(raw) - 1
41744
- : isNaN(raw) ? null : index;
41745
- function findOrAddLabel(labels, raw, index) {
42216
+ const addIfString = (labels, raw, index, addedLabels) => {
42217
+ if (typeof raw === 'string') {
42218
+ index = labels.push(raw) - 1;
42219
+ addedLabels.unshift({index, label: raw});
42220
+ } else if (isNaN(raw)) {
42221
+ index = null;
42222
+ }
42223
+ return index;
42224
+ };
42225
+ function findOrAddLabel(labels, raw, index, addedLabels) {
41746
42226
  const first = labels.indexOf(raw);
41747
42227
  if (first === -1) {
41748
- return addIfString(labels, raw, index);
42228
+ return addIfString(labels, raw, index, addedLabels);
41749
42229
  }
41750
42230
  const last = labels.lastIndexOf(raw);
41751
42231
  return first !== last ? index : first;
@@ -41756,6 +42236,20 @@
41756
42236
  super(cfg);
41757
42237
  this._startValue = undefined;
41758
42238
  this._valueRange = 0;
42239
+ this._addedLabels = [];
42240
+ }
42241
+ init(scaleOptions) {
42242
+ const added = this._addedLabels;
42243
+ if (added.length) {
42244
+ const labels = this.getLabels();
42245
+ for (const {index, label} of added) {
42246
+ if (labels[index] === label) {
42247
+ labels.splice(index, 1);
42248
+ }
42249
+ }
42250
+ this._addedLabels = [];
42251
+ }
42252
+ super.init(scaleOptions);
41759
42253
  }
41760
42254
  parse(raw, index) {
41761
42255
  if (isNullOrUndef(raw)) {
@@ -41763,7 +42257,7 @@
41763
42257
  }
41764
42258
  const labels = this.getLabels();
41765
42259
  index = isFinite(index) && labels[index] === raw ? index
41766
- : findOrAddLabel(labels, raw, valueOrDefault(index, raw));
42260
+ : findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);
41767
42261
  return validIndex(index, labels.length - 1);
41768
42262
  }
41769
42263
  determineDataLimits() {
@@ -42040,7 +42534,7 @@
42040
42534
  this._valueRange = end - start;
42041
42535
  }
42042
42536
  getLabelForValue(value) {
42043
- return formatNumber(value, this.chart.options.locale);
42537
+ return formatNumber(value, this.chart.options.locale, this.options.ticks.format);
42044
42538
  }
42045
42539
  }
42046
42540
 
@@ -42173,7 +42667,9 @@
42173
42667
  return ticks;
42174
42668
  }
42175
42669
  getLabelForValue(value) {
42176
- return value === undefined ? '0' : formatNumber(value, this.chart.options.locale);
42670
+ return value === undefined
42671
+ ? '0'
42672
+ : formatNumber(value, this.chart.options.locale, this.options.ticks.format);
42177
42673
  }
42178
42674
  configure() {
42179
42675
  const start = this.min;
@@ -42240,57 +42736,69 @@
42240
42736
  };
42241
42737
  }
42242
42738
  function fitWithPointLabels(scale) {
42243
- const furthestLimits = {
42244
- l: 0,
42245
- r: scale.width,
42246
- t: 0,
42247
- b: scale.height - scale.paddingTop
42739
+ const orig = {
42740
+ l: scale.left + scale._padding.left,
42741
+ r: scale.right - scale._padding.right,
42742
+ t: scale.top + scale._padding.top,
42743
+ b: scale.bottom - scale._padding.bottom
42248
42744
  };
42249
- const furthestAngles = {};
42745
+ const limits = Object.assign({}, orig);
42250
42746
  const labelSizes = [];
42251
42747
  const padding = [];
42252
- const valueCount = scale.getLabels().length;
42748
+ const valueCount = scale._pointLabels.length;
42749
+ const pointLabelOpts = scale.options.pointLabels;
42750
+ const additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0;
42253
42751
  for (let i = 0; i < valueCount; i++) {
42254
- const opts = scale.options.pointLabels.setContext(scale.getPointLabelContext(i));
42752
+ const opts = pointLabelOpts.setContext(scale.getPointLabelContext(i));
42255
42753
  padding[i] = opts.padding;
42256
- const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i]);
42754
+ const pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle);
42257
42755
  const plFont = toFont(opts.font);
42258
42756
  const textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);
42259
42757
  labelSizes[i] = textSize;
42260
- const angleRadians = scale.getIndexAngle(i);
42261
- const angle = toDegrees(angleRadians);
42758
+ const angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle);
42759
+ const angle = Math.round(toDegrees(angleRadians));
42262
42760
  const hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
42263
42761
  const vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
42264
- if (hLimits.start < furthestLimits.l) {
42265
- furthestLimits.l = hLimits.start;
42266
- furthestAngles.l = angleRadians;
42267
- }
42268
- if (hLimits.end > furthestLimits.r) {
42269
- furthestLimits.r = hLimits.end;
42270
- furthestAngles.r = angleRadians;
42271
- }
42272
- if (vLimits.start < furthestLimits.t) {
42273
- furthestLimits.t = vLimits.start;
42274
- furthestAngles.t = angleRadians;
42275
- }
42276
- if (vLimits.end > furthestLimits.b) {
42277
- furthestLimits.b = vLimits.end;
42278
- furthestAngles.b = angleRadians;
42279
- }
42762
+ updateLimits(limits, orig, angleRadians, hLimits, vLimits);
42280
42763
  }
42281
- scale._setReductions(scale.drawingArea, furthestLimits, furthestAngles);
42764
+ scale.setCenterPoint(
42765
+ orig.l - limits.l,
42766
+ limits.r - orig.r,
42767
+ orig.t - limits.t,
42768
+ limits.b - orig.b
42769
+ );
42282
42770
  scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
42283
42771
  }
42772
+ function updateLimits(limits, orig, angle, hLimits, vLimits) {
42773
+ const sin = Math.abs(Math.sin(angle));
42774
+ const cos = Math.abs(Math.cos(angle));
42775
+ let x = 0;
42776
+ let y = 0;
42777
+ if (hLimits.start < orig.l) {
42778
+ x = (orig.l - hLimits.start) / sin;
42779
+ limits.l = Math.min(limits.l, orig.l - x);
42780
+ } else if (hLimits.end > orig.r) {
42781
+ x = (hLimits.end - orig.r) / sin;
42782
+ limits.r = Math.max(limits.r, orig.r + x);
42783
+ }
42784
+ if (vLimits.start < orig.t) {
42785
+ y = (orig.t - vLimits.start) / cos;
42786
+ limits.t = Math.min(limits.t, orig.t - y);
42787
+ } else if (vLimits.end > orig.b) {
42788
+ y = (vLimits.end - orig.b) / cos;
42789
+ limits.b = Math.max(limits.b, orig.b + y);
42790
+ }
42791
+ }
42284
42792
  function buildPointLabelItems(scale, labelSizes, padding) {
42285
42793
  const items = [];
42286
- const valueCount = scale.getLabels().length;
42794
+ const valueCount = scale._pointLabels.length;
42287
42795
  const opts = scale.options;
42288
- const tickBackdropHeight = getTickBackdropHeight(opts);
42289
- const outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
42796
+ const extra = getTickBackdropHeight(opts) / 2;
42797
+ const outerDistance = scale.drawingArea;
42798
+ const additionalAngle = opts.pointLabels.centerPointLabels ? PI / valueCount : 0;
42290
42799
  for (let i = 0; i < valueCount; i++) {
42291
- const extra = (i === 0 ? tickBackdropHeight / 2 : 0);
42292
- const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i]);
42293
- const angle = toDegrees(scale.getIndexAngle(i));
42800
+ const pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i], additionalAngle);
42801
+ const angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI)));
42294
42802
  const size = labelSizes[i];
42295
42803
  const y = yForAngle(pointLabelPosition.y, size.h, angle);
42296
42804
  const textAlign = getTextAlignForAngle(angle);
@@ -42388,9 +42896,6 @@
42388
42896
  ctx.stroke();
42389
42897
  ctx.restore();
42390
42898
  }
42391
- function numberOrZero(param) {
42392
- return isNumber(param) ? param : 0;
42393
- }
42394
42899
  function createPointLabelContext(parent, index, label) {
42395
42900
  return createContext(parent, {
42396
42901
  label,
@@ -42408,12 +42913,12 @@
42408
42913
  this._pointLabelItems = [];
42409
42914
  }
42410
42915
  setDimensions() {
42411
- this.width = this.maxWidth;
42412
- this.height = this.maxHeight;
42413
- this.paddingTop = getTickBackdropHeight(this.options) / 2;
42414
- this.xCenter = Math.floor(this.width / 2);
42415
- this.yCenter = Math.floor((this.height - this.paddingTop) / 2);
42416
- this.drawingArea = Math.min(this.height - this.paddingTop, this.width) / 2;
42916
+ const padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2);
42917
+ const w = this.width = this.maxWidth - padding.width;
42918
+ const h = this.height = this.maxHeight - padding.height;
42919
+ this.xCenter = Math.floor(this.left + w / 2 + padding.left);
42920
+ this.yCenter = Math.floor(this.top + h / 2 + padding.top);
42921
+ this.drawingArea = Math.floor(Math.min(w, h) / 2);
42417
42922
  }
42418
42923
  determineDataLimits() {
42419
42924
  const {min, max} = this.getMinMax(false);
@@ -42426,10 +42931,12 @@
42426
42931
  }
42427
42932
  generateTickLabels(ticks) {
42428
42933
  LinearScaleBase.prototype.generateTickLabels.call(this, ticks);
42429
- this._pointLabels = this.getLabels().map((value, index) => {
42430
- const label = callback(this.options.pointLabels.callback, [value, index], this);
42431
- return label || label === 0 ? label : '';
42432
- });
42934
+ this._pointLabels = this.getLabels()
42935
+ .map((value, index) => {
42936
+ const label = callback(this.options.pointLabels.callback, [value, index], this);
42937
+ return label || label === 0 ? label : '';
42938
+ })
42939
+ .filter((v, i) => this.chart.getDataVisibility(i));
42433
42940
  }
42434
42941
  fit() {
42435
42942
  const opts = this.options;
@@ -42439,30 +42946,13 @@
42439
42946
  this.setCenterPoint(0, 0, 0, 0);
42440
42947
  }
42441
42948
  }
42442
- _setReductions(largestPossibleRadius, furthestLimits, furthestAngles) {
42443
- let radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
42444
- let radiusReductionRight = Math.max(furthestLimits.r - this.width, 0) / Math.sin(furthestAngles.r);
42445
- let radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
42446
- let radiusReductionBottom = -Math.max(furthestLimits.b - (this.height - this.paddingTop), 0) / Math.cos(furthestAngles.b);
42447
- radiusReductionLeft = numberOrZero(radiusReductionLeft);
42448
- radiusReductionRight = numberOrZero(radiusReductionRight);
42449
- radiusReductionTop = numberOrZero(radiusReductionTop);
42450
- radiusReductionBottom = numberOrZero(radiusReductionBottom);
42451
- this.drawingArea = Math.max(largestPossibleRadius / 2, Math.min(
42452
- Math.floor(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),
42453
- Math.floor(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2)));
42454
- this.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
42455
- }
42456
42949
  setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) {
42457
- const maxRight = this.width - rightMovement - this.drawingArea;
42458
- const maxLeft = leftMovement + this.drawingArea;
42459
- const maxTop = topMovement + this.drawingArea;
42460
- const maxBottom = (this.height - this.paddingTop) - bottomMovement - this.drawingArea;
42461
- this.xCenter = Math.floor(((maxLeft + maxRight) / 2) + this.left);
42462
- this.yCenter = Math.floor(((maxTop + maxBottom) / 2) + this.top + this.paddingTop);
42950
+ this.xCenter += Math.floor((leftMovement - rightMovement) / 2);
42951
+ this.yCenter += Math.floor((topMovement - bottomMovement) / 2);
42952
+ this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement));
42463
42953
  }
42464
42954
  getIndexAngle(index) {
42465
- const angleMultiplier = TAU / this.getLabels().length;
42955
+ const angleMultiplier = TAU / (this._pointLabels.length || 1);
42466
42956
  const startAngle = this.options.startAngle || 0;
42467
42957
  return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));
42468
42958
  }
@@ -42490,8 +42980,8 @@
42490
42980
  return createPointLabelContext(this.getContext(), index, pointLabel);
42491
42981
  }
42492
42982
  }
42493
- getPointPosition(index, distanceFromCenter) {
42494
- const angle = this.getIndexAngle(index) - HALF_PI;
42983
+ getPointPosition(index, distanceFromCenter, additionalAngle = 0) {
42984
+ const angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;
42495
42985
  return {
42496
42986
  x: Math.cos(angle) * distanceFromCenter + this.xCenter,
42497
42987
  y: Math.sin(angle) * distanceFromCenter + this.yCenter,
@@ -42519,7 +43009,7 @@
42519
43009
  const ctx = this.ctx;
42520
43010
  ctx.save();
42521
43011
  ctx.beginPath();
42522
- pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this.getLabels().length);
43012
+ pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length);
42523
43013
  ctx.closePath();
42524
43014
  ctx.fillStyle = backgroundColor;
42525
43015
  ctx.fill();
@@ -42530,7 +43020,7 @@
42530
43020
  const ctx = this.ctx;
42531
43021
  const opts = this.options;
42532
43022
  const {angleLines, grid} = opts;
42533
- const labelCount = this.getLabels().length;
43023
+ const labelCount = this._pointLabels.length;
42534
43024
  let i, offset, position;
42535
43025
  if (opts.pointLabels.display) {
42536
43026
  drawPointLabels(this, labelCount);
@@ -42546,7 +43036,7 @@
42546
43036
  }
42547
43037
  if (angleLines.display) {
42548
43038
  ctx.save();
42549
- for (i = this.getLabels().length - 1; i >= 0; i--) {
43039
+ for (i = labelCount - 1; i >= 0; i--) {
42550
43040
  const optsAtIndex = angleLines.setContext(this.getPointLabelContext(i));
42551
43041
  const {color, lineWidth} = optsAtIndex;
42552
43042
  if (!lineWidth || !color) {
@@ -42637,7 +43127,8 @@
42637
43127
  callback(label) {
42638
43128
  return label;
42639
43129
  },
42640
- padding: 5
43130
+ padding: 5,
43131
+ centerPointLabels: false
42641
43132
  }
42642
43133
  };
42643
43134
  RadialLinearScale.defaultRoutes = {
@@ -43214,6 +43705,20 @@
43214
43705
  return HomeController;
43215
43706
  }());
43216
43707
 
43708
+ var LogsController = /** @class */ (function () {
43709
+ function LogsController() {
43710
+ this.element = document.getElementById('log-list');
43711
+ if (this.element) {
43712
+ this.list = new DataList(this.element, {
43713
+ onComplete: function (data, sender) {
43714
+ Alerts.log('Finished loading logs list.', 'info');
43715
+ }.bind(this)
43716
+ });
43717
+ }
43718
+ }
43719
+ return LogsController;
43720
+ }());
43721
+
43217
43722
  var MediaController = /** @class */ (function () {
43218
43723
  function MediaController() {
43219
43724
  this.manage();
@@ -43243,190 +43748,6 @@
43243
43748
  return MediaController;
43244
43749
  }());
43245
43750
 
43246
- var ContentController = /** @class */ (function () {
43247
- function ContentController() {
43248
- this.manage();
43249
- $('body').on('click', '.content-create', this.create.bind(this));
43250
- $('body').on('click', '.content-delete', this.delete.bind(this));
43251
- $('body').on('click', '.content-set-status', this.setStatus.bind(this));
43252
- $('body').on('click', '.content-categories-delete', this.deleteCategory.bind(this));
43253
- $('body').on('click', '.content-categories-create,.content-categories-edit', this.createOrEditCategory.bind(this));
43254
- $('body').on('change', '.content-categories-check', this.toggleCategory.bind(this));
43255
- $('body').on('click', '.content-media-delete', this.removeMedia.bind(this));
43256
- $('body').on('keyup', '#Slug', function () {
43257
- var slugValue = $(this).val();
43258
- $('.slug-display').html(slugValue);
43259
- });
43260
- }
43261
- ContentController.prototype.manage = function () {
43262
- this.element = document.getElementById('content-list');
43263
- if (this.element) {
43264
- this.list = new DataList(this.element, {
43265
- onComplete: function (data, sender) {
43266
- Alerts.log('Finished loading content list.', 'info');
43267
- }.bind(this)
43268
- });
43269
- }
43270
- this.categoryElement = document.getElementById('content-categories-list');
43271
- if (this.categoryElement) {
43272
- this.categoryList = new DataList(this.categoryElement, {
43273
- onComplete: function (data, sender) {
43274
- Alerts.log('Finished loading category list.', 'info');
43275
- }.bind(this)
43276
- });
43277
- }
43278
- };
43279
- ContentController.prototype.create = function (e) {
43280
- e.preventDefault();
43281
- e.stopPropagation();
43282
- var createContentModal = new ModalController({
43283
- onComplete: function () {
43284
- var form = document.getElementById('content-create-form');
43285
- new Validator(form, {
43286
- onComplete: function (response) {
43287
- Response.process(response, 5000);
43288
- if (this.list) {
43289
- this.list.reload();
43290
- }
43291
- if (response.success) {
43292
- createContentModal.close();
43293
- }
43294
- }.bind(this)
43295
- });
43296
- }.bind(this)
43297
- });
43298
- createContentModal.show($(e.currentTarget).attr('href'), this.element);
43299
- };
43300
- ContentController.prototype.delete = function (e) {
43301
- e.preventDefault();
43302
- e.stopPropagation();
43303
- Alerts.confirm({
43304
- // Confirm options...
43305
- title: "Are you sure?",
43306
- html: "The content will be permanently removed."
43307
- }, function (result) {
43308
- if (result.isConfirmed) {
43309
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43310
- Response.process(data, 5000);
43311
- if (this.list) {
43312
- this.list.reload();
43313
- }
43314
- if (e.currentTarget.dataset.redirect) {
43315
- Alerts.message('Just taking you back to the content list.', 'Redirecting...');
43316
- setTimeout(function () {
43317
- window.location = e.currentTarget.dataset.redirect;
43318
- }, 1500);
43319
- }
43320
- }.bind(this));
43321
- }
43322
- }.bind(this));
43323
- };
43324
- ContentController.prototype.setStatus = function (e) {
43325
- e.preventDefault();
43326
- e.stopPropagation();
43327
- Alerts.confirm({
43328
- // Confirm options...
43329
- title: "Are you sure?",
43330
- html: "The change will happen immediately."
43331
- }, function (result) {
43332
- if (result.isConfirmed) {
43333
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43334
- Response.process(data, 5000);
43335
- if (this.list) {
43336
- this.list.reload();
43337
- }
43338
- }.bind(this));
43339
- }
43340
- }.bind(this));
43341
- };
43342
- ContentController.prototype.clone = function (e) {
43343
- e.preventDefault();
43344
- e.stopPropagation();
43345
- Alerts.confirm({
43346
- // Confirm options...
43347
- title: "Are you sure?",
43348
- html: "This will duplicate the content and everything inside it."
43349
- }, function (result) {
43350
- if (result.isConfirmed) {
43351
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43352
- Response.process(data, 5000);
43353
- if (this.list) {
43354
- this.list.reload();
43355
- }
43356
- }.bind(this));
43357
- }
43358
- }.bind(this));
43359
- };
43360
- ContentController.prototype.createOrEditCategory = function (e) {
43361
- e.preventDefault();
43362
- e.stopPropagation();
43363
- var createCategoryModal = new ModalController({
43364
- onComplete: function () {
43365
- var form = document.getElementById('content-categories-edit-form');
43366
- new Validator(form, {
43367
- onComplete: function (response) {
43368
- Response.process(response, 5000);
43369
- if (this.list) {
43370
- this.list.reload();
43371
- }
43372
- if (response.success) {
43373
- this.categoryList.reload();
43374
- createCategoryModal.close();
43375
- }
43376
- }.bind(this)
43377
- });
43378
- }.bind(this)
43379
- });
43380
- createCategoryModal.show($(e.currentTarget).attr('href'), this.element);
43381
- };
43382
- ContentController.prototype.deleteCategory = function (e) {
43383
- e.preventDefault();
43384
- e.stopPropagation();
43385
- Alerts.confirm({
43386
- // Confirm options...
43387
- }, function (result) {
43388
- if (result.isConfirmed) {
43389
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43390
- // category deleted...
43391
- Response.process(data, 5000);
43392
- this.categoryList.reload();
43393
- }.bind(this));
43394
- }
43395
- }.bind(this));
43396
- };
43397
- ContentController.prototype.toggleCategory = function (e) {
43398
- e.preventDefault();
43399
- e.stopPropagation();
43400
- $.post($(e.currentTarget).data('url'), { categoryId: $(e.currentTarget).val(), add: $(e.currentTarget).is(':checked') }, function (response) {
43401
- Response.process(response, 5000);
43402
- if (this.categoryList) {
43403
- this.categoryList.reload();
43404
- }
43405
- }.bind(this));
43406
- };
43407
- ContentController.prototype.removeMedia = function (e) {
43408
- e.preventDefault();
43409
- e.stopPropagation();
43410
- Alerts.confirm({
43411
- // Confirm options...
43412
- title: "Are you sure?",
43413
- html: "The media will be removed from the property, but will still be in the media collection."
43414
- }, function (result) {
43415
- if (result.isConfirmed) {
43416
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43417
- Response.process(data, 5000);
43418
- // reload the property media gallery, should be attached to #property-gallery-list
43419
- var mediaGalleryEl = document.getElementById('content-gallery-list');
43420
- if (mediaGalleryEl.hoodDataList) {
43421
- mediaGalleryEl.hoodDataList.reload();
43422
- }
43423
- }.bind(this));
43424
- }
43425
- }.bind(this));
43426
- };
43427
- return ContentController;
43428
- }());
43429
-
43430
43751
  var PropertyController = /** @class */ (function () {
43431
43752
  function PropertyController() {
43432
43753
  this.manage();
@@ -43541,6 +43862,137 @@
43541
43862
  return PropertyController;
43542
43863
  }());
43543
43864
 
43865
+ var PropertyImporter = /** @class */ (function () {
43866
+ function PropertyImporter() {
43867
+ if ($('#import-property-start').length > 0) {
43868
+ this.update();
43869
+ $('#import-property-start').click(function () {
43870
+ $.ajax({
43871
+ url: $('#import-property-start').data('url'),
43872
+ type: "POST",
43873
+ error: Inline.handleError,
43874
+ success: function () {
43875
+ this.update();
43876
+ }.bind(this)
43877
+ });
43878
+ }.bind(this));
43879
+ $('#import-property-cancel').click(function () {
43880
+ $.ajax({
43881
+ url: $('#import-property-cancel').data('url'),
43882
+ type: "POST",
43883
+ error: Inline.handleError,
43884
+ success: function () {
43885
+ this.update();
43886
+ }.bind(this)
43887
+ });
43888
+ }.bind(this));
43889
+ }
43890
+ }
43891
+ PropertyImporter.prototype.update = function () {
43892
+ $.ajax({
43893
+ url: $('#import-property-status').data('url'),
43894
+ type: "POST",
43895
+ error: Inline.handleError,
43896
+ success: function (result) {
43897
+ if (result.importer.running) {
43898
+ this.showInfo();
43899
+ clearInterval(this.updateInterval);
43900
+ this.updateInterval = window.setTimeout(this.update, 250);
43901
+ }
43902
+ else {
43903
+ clearInterval(this.updateInterval);
43904
+ this.hideInfo();
43905
+ }
43906
+ $('.tp').html(result.importer.total.toString());
43907
+ $('#pu').html(result.importer.updated.toString());
43908
+ $('#pa').html(result.importer.added.toString());
43909
+ $('#pp').html(result.importer.processed.toString());
43910
+ $('#pd').html(result.importer.deleted.toString());
43911
+ $('#ToAdd').html(result.importer.toAdd.toString());
43912
+ $('#ToUpdate').html(result.importer.toUpdate.toString());
43913
+ $('#ToDelete').html(result.importer.toDelete.toString());
43914
+ $('#pt').html(result.importer.statusMessage.toString());
43915
+ var ftpPercentComplete = Math.round(result.ftp.complete * 100) / 100;
43916
+ $('#fp').html(ftpPercentComplete.toString());
43917
+ $('#ft').html(result.ftp.statusMessage);
43918
+ var percentComplete = Math.round(result.importer.complete * 100) / 100;
43919
+ $('.pc').html(percentComplete.toString());
43920
+ $('#progressbar').css({
43921
+ width: result.importer.complete + "%"
43922
+ });
43923
+ if (result.importer.errors.length) {
43924
+ var errorHtml = "";
43925
+ for (var i = result.importer.errors.length - 1; i >= 0; i--) {
43926
+ errorHtml += '<div class="text-danger">' + result.importer.errors[i] + '</div>';
43927
+ }
43928
+ $('#import-property-errors').html(errorHtml);
43929
+ }
43930
+ else {
43931
+ $('#import-property-errors').html("<div>No errors reported.</div>");
43932
+ }
43933
+ if (result.importer.warnings.length) {
43934
+ var warningHtml = "";
43935
+ for (var j = result.importer.warnings.length - 1; j >= 0; j--) {
43936
+ warningHtml += '<div class="text-warning">' + result.importer.warnings[j] + '</div>';
43937
+ }
43938
+ $('#import-property-warnings').html(warningHtml);
43939
+ }
43940
+ else {
43941
+ $('#import-property-warnings').html("<div>No warnings reported.</div>");
43942
+ }
43943
+ }.bind(this)
43944
+ });
43945
+ };
43946
+ PropertyImporter.prototype.hideInfo = function () {
43947
+ $('#import-property-start').removeAttr('disabled');
43948
+ $('#import-property-cancel').attr('disabled', 'disabled');
43949
+ $('#import-property-progress').removeClass('d-block');
43950
+ $('#import-property-progress').addClass('d-none');
43951
+ };
43952
+ PropertyImporter.prototype.showInfo = function () {
43953
+ $('#import-property-cancel').removeAttr('disabled');
43954
+ $('#import-property-start').attr('disabled', 'disabled');
43955
+ $('#import-property-progress').addClass('d-block');
43956
+ $('#import-property-progress').removeClass('d-none');
43957
+ };
43958
+ return PropertyImporter;
43959
+ }());
43960
+
43961
+ var ThemesController = /** @class */ (function () {
43962
+ function ThemesController() {
43963
+ $('body').on('click', '.activate-theme', this.activate.bind(this));
43964
+ this.element = document.getElementById('themes-list');
43965
+ if (this.element) {
43966
+ this.list = new DataList(this.element, {
43967
+ onComplete: function (data, sender) {
43968
+ Alerts.log('Finished loading users list.', 'info');
43969
+ }.bind(this)
43970
+ });
43971
+ }
43972
+ }
43973
+ ThemesController.prototype.activate = function (e) {
43974
+ e.preventDefault();
43975
+ e.stopPropagation();
43976
+ Alerts.confirm({
43977
+ // Confirm options...
43978
+ title: "Are you sure?",
43979
+ html: "The site will change themes, and the selected theme will be live right away."
43980
+ }, function (result) {
43981
+ if (result.isConfirmed) {
43982
+ Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43983
+ Response.process(data, 5000);
43984
+ setTimeout(function () {
43985
+ if (this.list) {
43986
+ this.list.reload();
43987
+ }
43988
+ }.bind(this), 2000);
43989
+ }.bind(this));
43990
+ }
43991
+ }.bind(this));
43992
+ };
43993
+ return ThemesController;
43994
+ }());
43995
+
43544
43996
  var UsersController = /** @class */ (function () {
43545
43997
  function UsersController() {
43546
43998
  this.initLists();
@@ -43711,287 +44163,6 @@
43711
44163
  return UsersController;
43712
44164
  }());
43713
44165
 
43714
- var ThemesController = /** @class */ (function () {
43715
- function ThemesController() {
43716
- $('body').on('click', '.activate-theme', this.activate.bind(this));
43717
- this.element = document.getElementById('themes-list');
43718
- if (this.element) {
43719
- this.list = new DataList(this.element, {
43720
- onComplete: function (data, sender) {
43721
- Alerts.log('Finished loading users list.', 'info');
43722
- }.bind(this)
43723
- });
43724
- }
43725
- }
43726
- ThemesController.prototype.activate = function (e) {
43727
- e.preventDefault();
43728
- e.stopPropagation();
43729
- Alerts.confirm({
43730
- // Confirm options...
43731
- title: "Are you sure?",
43732
- html: "The site will change themes, and the selected theme will be live right away."
43733
- }, function (result) {
43734
- if (result.isConfirmed) {
43735
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43736
- Response.process(data, 5000);
43737
- setTimeout(function () {
43738
- if (this.list) {
43739
- this.list.reload();
43740
- }
43741
- }.bind(this), 2000);
43742
- }.bind(this));
43743
- }
43744
- }.bind(this));
43745
- };
43746
- return ThemesController;
43747
- }());
43748
-
43749
- var ContentTypeController = /** @class */ (function () {
43750
- function ContentTypeController() {
43751
- this.manage();
43752
- $('body').on('click', '.content-type-create', this.create.bind(this));
43753
- $('body').on('click', '.content-type-delete', this.delete.bind(this));
43754
- $('body').on('click', '.content-type-set-status', this.setStatus.bind(this));
43755
- $('body').on('click', '.content-custom-field-create', this.createField.bind(this));
43756
- $('body').on('click', '.content-custom-field-delete', this.deleteField.bind(this));
43757
- $('body').on('keyup', '#Slug', function () {
43758
- var slugValue = $(this).val();
43759
- $('.slug-display').html(slugValue);
43760
- });
43761
- }
43762
- ContentTypeController.prototype.manage = function () {
43763
- this.element = document.getElementById('content-type-list');
43764
- if (this.element) {
43765
- this.list = new DataList(this.element, {
43766
- onComplete: function (data, sender) {
43767
- Alerts.log('Finished loading content type list.', 'info');
43768
- }.bind(this)
43769
- });
43770
- }
43771
- this.fieldsElement = document.getElementById('content-custom-field-list');
43772
- if (this.fieldsElement) {
43773
- this.fieldsList = new DataList(this.fieldsElement, {
43774
- onComplete: function (data, sender) {
43775
- Alerts.log('Finished loading content type list.', 'info');
43776
- }.bind(this)
43777
- });
43778
- }
43779
- };
43780
- ContentTypeController.prototype.create = function (e) {
43781
- e.preventDefault();
43782
- e.stopPropagation();
43783
- var createContentModal = new ModalController({
43784
- onComplete: function () {
43785
- var form = document.getElementById('content-type-create-form');
43786
- new Validator(form, {
43787
- onComplete: function (response) {
43788
- Response.process(response, 5000);
43789
- if (this.list) {
43790
- this.list.reload();
43791
- }
43792
- if (response.success) {
43793
- createContentModal.close();
43794
- }
43795
- }.bind(this)
43796
- });
43797
- }.bind(this)
43798
- });
43799
- createContentModal.show($(e.currentTarget).attr('href'), this.element);
43800
- };
43801
- ContentTypeController.prototype.delete = function (e) {
43802
- e.preventDefault();
43803
- e.stopPropagation();
43804
- Alerts.confirm({
43805
- // Confirm options...
43806
- title: "Are you sure?",
43807
- html: "The content type will be permanently removed. Content will remain, but will be unusable and marked as the old content type."
43808
- }, function (result) {
43809
- if (result.isConfirmed) {
43810
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43811
- Response.process(data, 5000);
43812
- if (this.list) {
43813
- this.list.reload();
43814
- }
43815
- if (e.currentTarget.dataset.redirect) {
43816
- Alerts.message('Just taking you back to the content list.', 'Redirecting...');
43817
- setTimeout(function () {
43818
- window.location = e.currentTarget.dataset.redirect;
43819
- }, 1500);
43820
- }
43821
- }.bind(this));
43822
- }
43823
- }.bind(this));
43824
- };
43825
- ContentTypeController.prototype.setStatus = function (e) {
43826
- e.preventDefault();
43827
- e.stopPropagation();
43828
- Alerts.confirm({
43829
- // Confirm options...
43830
- title: "Are you sure?",
43831
- html: "The change will happen immediately."
43832
- }, function (result) {
43833
- if (result.isConfirmed) {
43834
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43835
- Response.process(data, 5000);
43836
- if (this.list) {
43837
- this.list.reload();
43838
- }
43839
- }.bind(this));
43840
- }
43841
- }.bind(this));
43842
- };
43843
- ContentTypeController.prototype.createField = function (e) {
43844
- e.preventDefault();
43845
- e.stopPropagation();
43846
- var createContentModal = new ModalController({
43847
- onComplete: function () {
43848
- var form = document.getElementById('content-custom-field-create-form');
43849
- new Validator(form, {
43850
- onComplete: function (response) {
43851
- Response.process(response, 5000);
43852
- if (this.fieldsList) {
43853
- this.fieldsList.reload();
43854
- }
43855
- if (response.success) {
43856
- createContentModal.close();
43857
- }
43858
- }.bind(this)
43859
- });
43860
- }.bind(this)
43861
- });
43862
- createContentModal.show($(e.currentTarget).attr('href'), this.element);
43863
- };
43864
- ContentTypeController.prototype.deleteField = function (e) {
43865
- e.preventDefault();
43866
- e.stopPropagation();
43867
- Alerts.confirm({
43868
- // Confirm options...
43869
- title: "Are you sure?",
43870
- html: "The field will be permanently removed. However fields will still be attached to content."
43871
- }, function (result) {
43872
- if (result.isConfirmed) {
43873
- Inline.post(e.currentTarget.href, e.currentTarget, function (data) {
43874
- Response.process(data, 5000);
43875
- if (this.fieldsList) {
43876
- this.fieldsList.reload();
43877
- }
43878
- }.bind(this));
43879
- }
43880
- }.bind(this));
43881
- };
43882
- return ContentTypeController;
43883
- }());
43884
-
43885
- var LogsController = /** @class */ (function () {
43886
- function LogsController() {
43887
- this.element = document.getElementById('log-list');
43888
- if (this.element) {
43889
- this.list = new DataList(this.element, {
43890
- onComplete: function (data, sender) {
43891
- Alerts.log('Finished loading logs list.', 'info');
43892
- }.bind(this)
43893
- });
43894
- }
43895
- }
43896
- return LogsController;
43897
- }());
43898
-
43899
- var PropertyImporter = /** @class */ (function () {
43900
- function PropertyImporter() {
43901
- if ($('#import-property-start').length > 0) {
43902
- this.update();
43903
- $('#import-property-start').click(function () {
43904
- $.ajax({
43905
- url: $('#import-property-start').data('url'),
43906
- type: "POST",
43907
- error: Inline.handleError,
43908
- success: function () {
43909
- this.update();
43910
- }.bind(this)
43911
- });
43912
- }.bind(this));
43913
- $('#import-property-cancel').click(function () {
43914
- $.ajax({
43915
- url: $('#import-property-cancel').data('url'),
43916
- type: "POST",
43917
- error: Inline.handleError,
43918
- success: function () {
43919
- this.update();
43920
- }.bind(this)
43921
- });
43922
- }.bind(this));
43923
- }
43924
- }
43925
- PropertyImporter.prototype.update = function () {
43926
- $.ajax({
43927
- url: $('#import-property-status').data('url'),
43928
- type: "POST",
43929
- error: Inline.handleError,
43930
- success: function (result) {
43931
- if (result.importer.running) {
43932
- this.showInfo();
43933
- clearInterval(this.updateInterval);
43934
- this.updateInterval = window.setTimeout(this.update, 250);
43935
- }
43936
- else {
43937
- clearInterval(this.updateInterval);
43938
- this.hideInfo();
43939
- }
43940
- $('.tp').html(result.importer.total.toString());
43941
- $('#pu').html(result.importer.updated.toString());
43942
- $('#pa').html(result.importer.added.toString());
43943
- $('#pp').html(result.importer.processed.toString());
43944
- $('#pd').html(result.importer.deleted.toString());
43945
- $('#ToAdd').html(result.importer.toAdd.toString());
43946
- $('#ToUpdate').html(result.importer.toUpdate.toString());
43947
- $('#ToDelete').html(result.importer.toDelete.toString());
43948
- $('#pt').html(result.importer.statusMessage.toString());
43949
- var ftpPercentComplete = Math.round(result.ftp.complete * 100) / 100;
43950
- $('#fp').html(ftpPercentComplete.toString());
43951
- $('#ft').html(result.ftp.statusMessage);
43952
- var percentComplete = Math.round(result.importer.complete * 100) / 100;
43953
- $('.pc').html(percentComplete.toString());
43954
- $('#progressbar').css({
43955
- width: result.importer.complete + "%"
43956
- });
43957
- if (result.importer.errors.length) {
43958
- var errorHtml = "";
43959
- for (var i = result.importer.errors.length - 1; i >= 0; i--) {
43960
- errorHtml += '<div class="text-danger">' + result.importer.errors[i] + '</div>';
43961
- }
43962
- $('#import-property-errors').html(errorHtml);
43963
- }
43964
- else {
43965
- $('#import-property-errors').html("<div>No errors reported.</div>");
43966
- }
43967
- if (result.importer.warnings.length) {
43968
- var warningHtml = "";
43969
- for (var j = result.importer.warnings.length - 1; j >= 0; j--) {
43970
- warningHtml += '<div class="text-warning">' + result.importer.warnings[j] + '</div>';
43971
- }
43972
- $('#import-property-warnings').html(warningHtml);
43973
- }
43974
- else {
43975
- $('#import-property-warnings').html("<div>No warnings reported.</div>");
43976
- }
43977
- }.bind(this)
43978
- });
43979
- };
43980
- PropertyImporter.prototype.hideInfo = function () {
43981
- $('#import-property-start').removeAttr('disabled');
43982
- $('#import-property-cancel').attr('disabled', 'disabled');
43983
- $('#import-property-progress').removeClass('d-block');
43984
- $('#import-property-progress').addClass('d-none');
43985
- };
43986
- PropertyImporter.prototype.showInfo = function () {
43987
- $('#import-property-cancel').removeAttr('disabled');
43988
- $('#import-property-start').attr('disabled', 'disabled');
43989
- $('#import-property-progress').addClass('d-block');
43990
- $('#import-property-progress').removeClass('d-none');
43991
- };
43992
- return PropertyImporter;
43993
- }());
43994
-
43995
44166
  var Admin = /** @class */ (function (_super) {
43996
44167
  __extends(Admin, _super);
43997
44168
  function Admin() {