@jetbrains/ring-ui 5.0.99 → 5.0.101

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 (50) hide show
  1. package/components/analytics/analytics.d.ts +20 -6
  2. package/components/analytics/analytics.js +19 -24
  3. package/components/analytics/analytics__custom-plugin.d.ts +4 -15
  4. package/components/analytics/analytics__custom-plugin.js +11 -52
  5. package/components/analytics/analytics__fus-plugin.d.ts +15 -25
  6. package/components/analytics/analytics__fus-plugin.js +15 -73
  7. package/components/analytics/analytics__ga-plugin.d.ts +12 -2
  8. package/components/analytics/analytics__ga-plugin.js +35 -5
  9. package/components/analytics/analytics__plugin-utils.d.ts +16 -0
  10. package/components/analytics/analytics__plugin-utils.js +26 -1
  11. package/components/button-ng/button-ng.js +1 -1
  12. package/components/dialog-ng/dialog-ng.js +4 -5
  13. package/components/global/angular-component-factory.js +4 -3
  14. package/components/global/ring-angular-component.js +1 -3
  15. package/components/global/ring-angular-component.test.js +2 -1
  16. package/components/input-ng/input-ng.js +1 -1
  17. package/components/loader-ng/loader-ng.js +1 -1
  18. package/components/promised-click-ng/promised-click-ng.js +1 -1
  19. package/components/shortcuts-hint-ng/shortcuts-hint-ng.js +1 -2
  20. package/components/sidebar-ng/sidebar-ng.js +1 -2
  21. package/components/template-ng/template-ng.js +1 -2
  22. package/components/user-card/card.js +18 -16
  23. package/components/user-card/user-card.css +4 -0
  24. package/dist/_helpers/card.js +4 -2
  25. package/dist/analytics/analytics.d.ts +20 -6
  26. package/dist/analytics/analytics.js +21 -25
  27. package/dist/analytics/analytics__custom-plugin.d.ts +4 -15
  28. package/dist/analytics/analytics__custom-plugin.js +15 -51
  29. package/dist/analytics/analytics__fus-plugin.d.ts +15 -25
  30. package/dist/analytics/analytics__fus-plugin.js +15 -86
  31. package/dist/analytics/analytics__ga-plugin.d.ts +12 -2
  32. package/dist/analytics/analytics__ga-plugin.js +39 -5
  33. package/dist/analytics/analytics__plugin-utils.d.ts +16 -0
  34. package/dist/analytics/analytics__plugin-utils.js +26 -1
  35. package/dist/button-ng/button-ng.js +1 -1
  36. package/dist/dialog-ng/dialog-ng.js +3 -3
  37. package/dist/global/angular-component-factory.js +6 -3
  38. package/dist/global/ring-angular-component.js +2 -2
  39. package/dist/input-ng/input-ng.js +1 -1
  40. package/dist/loader-ng/loader-ng.js +1 -1
  41. package/dist/promised-click-ng/promised-click-ng.js +2 -2
  42. package/dist/shortcuts-hint-ng/shortcuts-hint-ng.js +2 -2
  43. package/dist/sidebar-ng/sidebar-ng.js +2 -2
  44. package/dist/style.css +1 -1
  45. package/dist/template-ng/template-ng.js +1 -1
  46. package/package.json +19 -18
  47. package/components/analytics-ng/analytics-ng.examples.js +0 -61
  48. package/components/analytics-ng/analytics-ng.js +0 -87
  49. package/components/analytics-ng/analytics-ng.test.js +0 -82
  50. package/dist/analytics-ng/analytics-ng.js +0 -89
@@ -1,96 +1,25 @@
1
- import { _ as _defineProperty } from '../_helpers/_rollupPluginBabelHelpers.js';
2
- import AnalyticsPluginUtils from './analytics__plugin-utils.js';
3
- import '../global/sniffer.js';
4
- import 'sniffr';
1
+ import deprecate from 'util-deprecate';
5
2
 
6
3
  /**
4
+ * @deprecated
7
5
  * @name AnalyticsFUSPlugin
8
- *
9
- * @param * @param {{
10
- * productId: string,
11
- * productBuild: string,
12
- * recorderVersion: string?,
13
- * isDevelopment: boolean?,
14
- * groups: object[]?
15
- * }} config
16
- * @constructor
17
6
  */
18
7
  class AnalyticsFUSPlugin {
19
- constructor(_ref) {
20
- let {
21
- productId,
22
- productBuild,
23
- recorderVersion = '1',
24
- isDevelopment = false,
25
- groups = []
26
- } = _ref;
27
- _defineProperty(this, "_recorderVersion", void 0);
28
- _defineProperty(this, "_lastPagePath", void 0);
29
- _defineProperty(this, "_groups", void 0);
30
- if (!productId && !isDevelopment) {
31
- return;
32
- }
33
- ((i, s, o, g, r) => {
34
- i[r] = i[r] || function addArgumentsToQueueForWaitingTheScriptLoading() {
35
- const fn = i[r];
36
- if (fn != null) {
37
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
38
- args[_key] = arguments[_key];
39
- }
40
- (fn.query = fn.query || []).push(args);
41
- }
42
- };
43
- const script = document.createElement(o);
44
- script.async = true;
45
- script.src = g;
46
- const firstScript = document.getElementsByTagName(o)[0];
47
- firstScript.parentNode?.insertBefore(script, firstScript);
48
- })(window, document, 'script', '//resources.jetbrains.com/storage/fus/api/fus-reporting-api.js', 'fusra');
49
- window.fusra?.('init', {
50
- recorderCode: productId,
51
- recorderVersion,
52
- productCode: productId,
53
- productBuild,
54
- internal: isDevelopment,
55
- groups,
56
- useForSubdomains: true
57
- });
58
- this._recorderVersion = recorderVersion;
59
- this._groups = groups;
60
- }
61
- trackEvent(category, action, additionalInfo) {
62
- this._processEvent(category, action, additionalInfo);
63
- }
64
- trackPageView(path) {
65
- if (this._lastPagePath === path) {
66
- return;
67
- }
68
- this._lastPagePath = path;
69
- this._processEvent('ring.page.view', 'open', {
70
- path,
71
- browser: AnalyticsPluginUtils.getUserAgentPresentation(),
72
- platform: AnalyticsPluginUtils.npeSaveLowerCase(navigator.platform),
73
- lang: AnalyticsPluginUtils.npeSaveLowerCase(navigator.language),
74
- ['page-view-duration']: AnalyticsPluginUtils.getPageViewDurationPresentation(),
75
- ['pixel-ratio']: AnalyticsPluginUtils.getDevicePixelRatioPresentation(),
76
- screen: AnalyticsPluginUtils.getScreenWidthPresentation()
77
- });
78
- }
8
+ /**
9
+ * @deprecated
10
+ */
11
+ trackEvent() {}
12
+ /**
13
+ * @deprecated
14
+ */
15
+ trackPageView() {}
16
+ /**
17
+ * @deprecated
18
+ */
79
19
  get serializeAdditionalInfo() {
80
20
  return false;
81
21
  }
82
- _processEvent(category, action, additionalInfo) {
83
- const groupId = category.replace(/[-]/g, '.');
84
- const group = (this._groups || []).filter(currentGroup => currentGroup.id === groupId)[0];
85
- if (group && window.fusra) {
86
- window.fusra('event', {
87
- groupId,
88
- groupVersion: group.version || this._recorderVersion,
89
- eventId: action,
90
- eventData: additionalInfo
91
- });
92
- }
93
- }
94
22
  }
23
+ var analytics__fusPlugin = deprecate(AnalyticsFUSPlugin, 'AnalyticsFUSPlugin is deprecated, use AnalyticsCustomPlugin instead');
95
24
 
96
- export { AnalyticsFUSPlugin as default };
25
+ export { analytics__fusPlugin as default };
@@ -5,13 +5,23 @@ declare global {
5
5
  }
6
6
  }
7
7
  /**
8
- *
8
+ * @deprecated
9
9
  * @param {string?} gaId Google Analytics ID (should be undefined in development)
10
10
  * @constructor
11
11
  */
12
12
  export default class AnalyticsGAPlugin implements AnalyticsPlugin {
13
13
  constructor(gaId?: string | undefined, isDevelopment?: boolean | undefined, domain?: string, cookielessUserIdentifier?: string | undefined);
14
- trackEvent(category: string, action: string): void;
14
+ /**
15
+ * @deprecated
16
+ */
17
+ trackEvent(rawCategory: string, rawAction: string, additionalData?: Record<string, string>): void;
18
+ /**
19
+ * @deprecated
20
+ */
15
21
  trackPageView(path: string): void;
22
+ /**
23
+ * @deprecated
24
+ */
16
25
  get serializeAdditionalInfo(): boolean;
26
+ private _buildSuffix;
17
27
  }
@@ -1,5 +1,10 @@
1
+ import AnalyticsPluginUtils from './analytics__plugin-utils.js';
2
+ import 'util-deprecate';
3
+ import '../global/sniffer.js';
4
+ import 'sniffr';
5
+
1
6
  /**
2
- *
7
+ * @deprecated
3
8
  * @param {string?} gaId Google Analytics ID (should be undefined in development)
4
9
  * @constructor
5
10
  */
@@ -45,23 +50,52 @@ class AnalyticsGAPlugin {
45
50
  ga('set', 'location', domain || '/');
46
51
  ga('set', 'allowAdFeatures', false);
47
52
  }
48
- trackEvent(category, action) {
53
+ /**
54
+ * @deprecated
55
+ */
56
+ trackEvent(rawCategory, rawAction, additionalData) {
49
57
  if (window.ga != null) {
50
- const eventOptions = {
58
+ const category = AnalyticsPluginUtils.reformatString(rawCategory, true);
59
+ const action = AnalyticsPluginUtils.reformatString(rawAction);
60
+ ga('send', 'event', {
51
61
  eventCategory: category,
52
62
  eventAction: action
53
- };
54
- ga('send', 'event', eventOptions);
63
+ });
64
+ if (additionalData) {
65
+ ga('send', 'event', {
66
+ eventCategory: category,
67
+ eventAction: action + this._buildSuffix(additionalData)
68
+ });
69
+ }
55
70
  }
56
71
  }
72
+ /**
73
+ * @deprecated
74
+ */
57
75
  trackPageView(path) {
58
76
  if (window.ga != null) {
59
77
  ga('send', 'pageview', path);
60
78
  }
61
79
  }
80
+ /**
81
+ * @deprecated
82
+ */
62
83
  get serializeAdditionalInfo() {
63
84
  return true;
64
85
  }
86
+ _buildSuffix(additionalData) {
87
+ if (!additionalData) {
88
+ return '';
89
+ }
90
+ let suffix = '';
91
+ let key;
92
+ for (key in additionalData) {
93
+ if (additionalData.hasOwnProperty(key)) {
94
+ suffix += `__${key}$${additionalData[key]}`;
95
+ }
96
+ }
97
+ return suffix;
98
+ }
65
99
  }
66
100
 
67
101
  export { AnalyticsGAPlugin as default };
@@ -1,15 +1,31 @@
1
1
  declare const AnalyticsPluginUtils: {
2
2
  /**
3
+ * @deprecated
3
4
  * Statistics server does not accept undefined values and strings containing certain symbols
4
5
  * @param value
5
6
  * @param isCategory
6
7
  * @returns string, where forbidden symbols are replaced with '_'
7
8
  */
8
9
  reformatString: (value: unknown, isCategory?: boolean) => string;
10
+ /**
11
+ * @deprecated
12
+ */
9
13
  getPageViewDurationPresentation: (durationMs?: number) => string;
14
+ /**
15
+ * @deprecated
16
+ */
10
17
  getScreenWidthPresentation: () => string;
18
+ /**
19
+ * @deprecated
20
+ */
11
21
  npeSaveLowerCase: (val: string | null | undefined) => string;
22
+ /**
23
+ * @deprecated
24
+ */
12
25
  getUserAgentPresentation: () => string;
26
+ /**
27
+ * @deprecated
28
+ */
13
29
  getDevicePixelRatioPresentation: () => string;
14
30
  };
15
31
  export default AnalyticsPluginUtils;
@@ -1,10 +1,13 @@
1
+ import deprecate from 'util-deprecate';
1
2
  import sniffr from '../global/sniffer.js';
2
3
  import 'sniffr';
3
4
 
5
+ const warnOnDeprecationOfAnalyticsUtilsMethod = methodName => deprecate(() => {}, `Method AnalyticsPluginUtils::${methodName} is deprecated and will be removed soon`)();
4
6
  const SECOND = 1000;
5
7
  const HOUR = 3600;
6
8
  const AnalyticsPluginUtils = {
7
9
  /**
10
+ * @deprecated
8
11
  * Statistics server does not accept undefined values and strings containing certain symbols
9
12
  * @param value
10
13
  * @param isCategory
@@ -18,7 +21,11 @@ const AnalyticsPluginUtils = {
18
21
  const regexp = isCategory ? /[.:;!@#^&*(){}\[\]?,%=+\\\/]+/g : /[.:;!@#^&*(){}\[\]?,%=+\\]+/g;
19
22
  return str.replace(regexp, '_');
20
23
  },
24
+ /**
25
+ * @deprecated
26
+ */
21
27
  getPageViewDurationPresentation: durationMs => {
28
+ warnOnDeprecationOfAnalyticsUtilsMethod('getPageViewDurationPresentation');
22
29
  if (durationMs == null) {
23
30
  return 'less-than-1-sec';
24
31
  }
@@ -39,7 +46,11 @@ const AnalyticsPluginUtils = {
39
46
  roundedDuration = roundedDuration > 0 ? roundedDuration : 1;
40
47
  return `less-than-${roundedDuration}-sec`;
41
48
  },
49
+ /**
50
+ * @deprecated
51
+ */
42
52
  getScreenWidthPresentation: () => {
53
+ warnOnDeprecationOfAnalyticsUtilsMethod('getScreenWidthPresentation');
43
54
  /**
44
55
  * Sizes were taken from bootstrap's grid (xs, sm, md, lg)
45
56
  */
@@ -52,14 +63,28 @@ const AnalyticsPluginUtils = {
52
63
  }
53
64
  return '[1200px;inf)';
54
65
  },
55
- npeSaveLowerCase: val => (val || 'unknown').toLowerCase(),
66
+ /**
67
+ * @deprecated
68
+ */
69
+ npeSaveLowerCase: val => {
70
+ warnOnDeprecationOfAnalyticsUtilsMethod('npeSaveLowerCase');
71
+ return (val || 'unknown').toLowerCase();
72
+ },
73
+ /**
74
+ * @deprecated
75
+ */
56
76
  getUserAgentPresentation: () => {
77
+ warnOnDeprecationOfAnalyticsUtilsMethod('getUserAgentPresentation');
57
78
  const name = AnalyticsPluginUtils.npeSaveLowerCase(sniffr.browser.name || 'unknown');
58
79
  const majorVersion = sniffr.browser.version[0];
59
80
  const version = majorVersion || 'unknown';
60
81
  return `${name}$${version}`;
61
82
  },
83
+ /**
84
+ * @deprecated
85
+ */
62
86
  getDevicePixelRatioPresentation: () => {
87
+ warnOnDeprecationOfAnalyticsUtilsMethod('getDevicePixelRatioPresentation');
63
88
  if (!window.devicePixelRatio || !window.devicePixelRatio.toFixed) {
64
89
  return 'unknown';
65
90
  }
@@ -155,7 +155,7 @@ class ButtonController extends RingAngularComponent {
155
155
  return $scope.$eval(attribute);
156
156
  }
157
157
  }
158
- _defineProperty(ButtonController, "$inject", ['$element', '$attrs', '$scope', '$compile', '$log']);
158
+ ButtonController.$inject = ['$element', '$attrs', '$scope', '$compile', '$log'];
159
159
  function createButtonDirective(tagName) {
160
160
  return () => ({
161
161
  restrict: 'E',
@@ -282,7 +282,7 @@ class DialogController extends RingAngularComponent {
282
282
  }
283
283
  }
284
284
  DialogController.$inject = [];
285
- _defineProperty(DialogController, "$inject", ['$scope', '$q', 'dialog', '$element', 'dialogInSidebar', '$compile', '$injector', '$controller', 'rgCompiler', '$sce']);
285
+ DialogController.$inject = ['$scope', '$q', 'dialog', '$element', 'dialogInSidebar', '$compile', '$injector', '$controller', 'rgCompiler', '$sce'];
286
286
  class DialogService extends RingAngularComponent {
287
287
  constructor() {
288
288
  super(...arguments);
@@ -311,7 +311,7 @@ class DialogService extends RingAngularComponent {
311
311
  }
312
312
  }
313
313
  DialogService.$inject = [];
314
- _defineProperty(DialogService, "$inject", ['$log']);
314
+ DialogService.$inject = ['$log'];
315
315
  class DialogInSidebarService extends DialogService {
316
316
  constructor() {
317
317
  super(...arguments);
@@ -320,7 +320,7 @@ class DialogInSidebarService extends DialogService {
320
320
  }
321
321
  }
322
322
  DialogInSidebarService.$inject = [];
323
- _defineProperty(DialogInSidebarService, "$inject", [...DialogService.$inject, 'dialog']);
323
+ DialogInSidebarService.$inject = [...DialogService.$inject, 'dialog'];
324
324
  function rgDialogDirective($timeout) {
325
325
  function link(scope, iElement, iAttrs, dialogCtrl) {
326
326
  const node = iElement[0];
@@ -11,13 +11,12 @@ function getAngularComponentName(name) {
11
11
  return `rg${name}`;
12
12
  }
13
13
  function createAngularComponent(Component) {
14
- var _class;
15
14
  const propKeys = Object.keys(Component.propTypes);
16
15
  const bindings = {};
17
16
  propKeys.forEach(key => {
18
17
  bindings[key] = '<';
19
18
  });
20
- return _class = class AngularComponent extends RingAngularComponent {
19
+ class AngularComponent extends RingAngularComponent {
21
20
  $postLink() {
22
21
  const {
23
22
  $transclude
@@ -63,7 +62,11 @@ function createAngularComponent(Component) {
63
62
  nodes: this.innerNodes
64
63
  }) : null), container);
65
64
  }
66
- }, _defineProperty(_class, "$inject", ['$scope', '$element', '$transclude']), _defineProperty(_class, "bindings", bindings), _defineProperty(_class, "transclude", true), _class;
65
+ }
66
+ _defineProperty(AngularComponent, "bindings", bindings);
67
+ _defineProperty(AngularComponent, "transclude", true);
68
+ AngularComponent.$inject = ['$scope', '$element', '$transclude'];
69
+ return AngularComponent;
67
70
  }
68
71
  function angularComponentFactory(Component, name) {
69
72
  const angularModuleName = `Ring.${name[0].toLowerCase() + name.slice(1)}`;
@@ -5,15 +5,15 @@ class RingAngularComponent {
5
5
  return this;
6
6
  }
7
7
  constructor() {
8
+ var _this$constructor$$in;
8
9
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
9
10
  args[_key] = arguments[_key];
10
11
  }
11
12
  _defineProperty(this, "$inject", {});
12
- this.constructor.$inject.forEach((injectName, i) => {
13
+ ((_this$constructor$$in = this.constructor.$inject) !== null && _this$constructor$$in !== void 0 ? _this$constructor$$in : []).forEach((injectName, i) => {
13
14
  this.$inject[injectName] = args[i];
14
15
  });
15
16
  }
16
17
  }
17
- _defineProperty(RingAngularComponent, "$inject", []);
18
18
 
19
19
  export { RingAngularComponent as default };
@@ -61,7 +61,6 @@ class RingInputComponent extends RingAngularComponent {
61
61
  });
62
62
  }
63
63
  }
64
- _defineProperty(RingInputComponent, "$inject", ['$element']);
65
64
  _defineProperty(RingInputComponent, "require", {
66
65
  ngModelCtrl: '?ngModel'
67
66
  });
@@ -140,6 +139,7 @@ _defineProperty(RingInputComponent, "template", `
140
139
  <div ng-if="!$ctrl.borderless && $ctrl.error" class="${modules_88cfaf40.errorText} ${modules_c40fa551.errorText}">{{$ctrl.error}}</div>
141
140
  </div>
142
141
  `);
142
+ RingInputComponent.$inject = ['$element'];
143
143
  angularModule.component('rgInput', RingInputComponent);
144
144
  var InputNg = angularModule.name;
145
145
 
@@ -26,10 +26,10 @@ class RgLoaderComponent extends RingAngularComponent {
26
26
  this.loader.updateMessage(changes.message.currentValue);
27
27
  }
28
28
  }
29
- _defineProperty(RgLoaderComponent, "$inject", ['$element']);
30
29
  _defineProperty(RgLoaderComponent, "bindings", {
31
30
  message: '@'
32
31
  });
32
+ RgLoaderComponent.$inject = ['$element'];
33
33
  angularModule.component('rgLoader', RgLoaderComponent);
34
34
  var loaderNg = angularModule.name;
35
35
 
@@ -1,10 +1,10 @@
1
- import { _ as _defineProperty } from '../_helpers/_rollupPluginBabelHelpers.js';
2
1
  import angular from 'angular';
3
2
  import { m as modules_e81895c9 } from '../_helpers/button__classes.js';
4
3
  import { applyMethodToClasses } from '../global/dom.js';
5
4
  import RingAngularComponent from '../global/ring-angular-component.js';
6
5
  import { LOADER_BACKGROUND_SELECTOR } from '../button-ng/button-ng.js';
7
6
  import 'classnames';
7
+ import '../_helpers/_rollupPluginBabelHelpers.js';
8
8
  import '../icon-ng/icon-ng.js';
9
9
  import '../icon/icon__constants.js';
10
10
  import '../template-ng/template-ng.js';
@@ -95,7 +95,7 @@ class PromisedClickController extends RingAngularComponent {
95
95
  }
96
96
  }
97
97
  PromisedClickController.$inject = [];
98
- _defineProperty(PromisedClickController, "$inject", ['$scope', '$element', '$attrs', '$parse']);
98
+ PromisedClickController.$inject = ['$scope', '$element', '$attrs', '$parse'];
99
99
  function rgPromisedClickDirective() {
100
100
  return {
101
101
  controller: PromisedClickController
@@ -1,4 +1,3 @@
1
- import { _ as _defineProperty } from '../_helpers/_rollupPluginBabelHelpers.js';
2
1
  import angular from 'angular';
3
2
  import searchIcon from '@jetbrains/icons/search';
4
3
  import RingAngularComponent from '../global/ring-angular-component.js';
@@ -9,6 +8,7 @@ import IconNG from '../icon-ng/icon-ng.js';
9
8
  import InputNg from '../input-ng/input-ng.js';
10
9
  import { getShortcutTitle } from '../shortcuts/shortcut-title.js';
11
10
  import HintPopupTpl from './shortcuts-hint-ng__template.js';
11
+ import '../_helpers/_rollupPluginBabelHelpers.js';
12
12
  import 'focus-trap';
13
13
  import '../global/dom.js';
14
14
  import '../shortcuts/core.js';
@@ -80,7 +80,7 @@ class HintPopupService extends RingAngularComponent {
80
80
  }, popupConfig));
81
81
  }
82
82
  }
83
- _defineProperty(HintPopupService, "$inject", ['dialog', 'shortcuts']);
83
+ HintPopupService.$inject = ['dialog', 'shortcuts'];
84
84
  function shortcutKeySymbolFilter(shortcut) {
85
85
  return getShortcutTitle(shortcut);
86
86
  }
@@ -1,4 +1,3 @@
1
- import { _ as _defineProperty } from '../_helpers/_rollupPluginBabelHelpers.js';
2
1
  import angular from 'angular';
3
2
  import chevronRightIcon from '@jetbrains/icons/chevron-right';
4
3
  import chevronLeftIcon from '@jetbrains/icons/chevron-left';
@@ -11,6 +10,7 @@ import buttonTemplate from './sidebar-ng__button-template.js';
11
10
  import 'just-debounce-it';
12
11
  import 'element-resize-detector';
13
12
  import '../global/dom.js';
13
+ import '../_helpers/_rollupPluginBabelHelpers.js';
14
14
  import '../icon/icon__constants.js';
15
15
  import '../template-ng/template-ng.js';
16
16
  import '../_helpers/icon.js';
@@ -51,7 +51,7 @@ class SidebarController extends RingAngularComponent {
51
51
  }
52
52
  }
53
53
  SidebarController.$inject = [];
54
- _defineProperty(SidebarController, "$inject", ['$scope']);
54
+ SidebarController.$inject = ['$scope'];
55
55
  function rgSidebarDirective() {
56
56
  return {
57
57
  restrict: 'E',