@base-framework/base 2.6.0 → 2.6.1

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 (190) hide show
  1. package/base.min.js +1 -0
  2. package/es5/base.js +2968 -0
  3. package/es5/modules/ajax.js +663 -0
  4. package/es5/modules/animation.js +188 -0
  5. package/es5/modules/animations.js +1080 -0
  6. package/es5/modules/atom.js +65 -0
  7. package/es5/modules/component.js +1310 -0
  8. package/es5/modules/data-binder.js +1131 -0
  9. package/es5/modules/data.js +1808 -0
  10. package/es5/modules/date.js +525 -0
  11. package/es5/modules/form-validator.js +324 -0
  12. package/es5/modules/history.js +126 -0
  13. package/es5/modules/html-builder.js +461 -0
  14. package/es5/modules/layout.js +1679 -0
  15. package/es5/modules/mouse.js +124 -0
  16. package/es5/modules/nav-link.js +123 -0
  17. package/es5/modules/olderversions/animations-ease.js +1095 -0
  18. package/es5/modules/olderversions/animations-update.js +1048 -0
  19. package/es5/modules/olderversions/base-animations.js +636 -0
  20. package/es5/modules/olderversions/base-component-class.js +100 -0
  21. package/es5/modules/olderversions/base-data-binder-1.js +407 -0
  22. package/es5/modules/olderversions/base-data-binder-class.js +358 -0
  23. package/es5/modules/olderversions/base-layout-parser-class.js +172 -0
  24. package/es5/modules/olderversions/base-mode-1.js +777 -0
  25. package/es5/modules/olderversions/base-model-class.js +585 -0
  26. package/es5/modules/olderversions/data-binder/element-binding/base-data-binder-class.js +358 -0
  27. package/es5/modules/olderversions/data-binder/element-binding/base-model-class.js +585 -0
  28. package/es5/modules/olderversions/data-binder/model-binding/base-data-binder-class.js +353 -0
  29. package/es5/modules/olderversions/data-binder/model-binding/base-model-class.js +604 -0
  30. package/es5/modules/olderversions/data-binder-update-watcher.js +640 -0
  31. package/es5/modules/olderversions/data-tracker.js +187 -0
  32. package/es5/modules/olderversions/event-update.js +666 -0
  33. package/es5/modules/olderversions/nav-link.js +119 -0
  34. package/es5/modules/olderversions/router-with-templates-1.js +785 -0
  35. package/es5/modules/olderversions/router-with-templates.js +701 -0
  36. package/es5/modules/prototypes/ajax.js +657 -0
  37. package/es5/modules/prototypes/atom.js +65 -0
  38. package/es5/modules/prototypes/component.js +972 -0
  39. package/es5/modules/prototypes/data-binder.js +1089 -0
  40. package/es5/modules/prototypes/data.js +1290 -0
  41. package/es5/modules/prototypes/html-builder.js +414 -0
  42. package/es5/modules/prototypes/layout.js +879 -0
  43. package/es5/modules/router.js +1680 -0
  44. package/es5/modules/state.js +274 -0
  45. package/es6/.jshintrc +3 -0
  46. package/es6/base.js +41 -0
  47. package/es6/core.js +1 -0
  48. package/es6/data-tracker.js +351 -0
  49. package/es6/events.js +602 -0
  50. package/es6/legacy/es5/base.js +2968 -0
  51. package/es6/legacy/es5/modules/ajax.js +663 -0
  52. package/es6/legacy/es5/modules/animation.js +188 -0
  53. package/es6/legacy/es5/modules/animations.js +1080 -0
  54. package/es6/legacy/es5/modules/atom.js +65 -0
  55. package/es6/legacy/es5/modules/component.js +1310 -0
  56. package/es6/legacy/es5/modules/data-binder.js +1131 -0
  57. package/es6/legacy/es5/modules/data.js +1808 -0
  58. package/es6/legacy/es5/modules/date.js +525 -0
  59. package/es6/legacy/es5/modules/form-validator.js +324 -0
  60. package/es6/legacy/es5/modules/history.js +126 -0
  61. package/es6/legacy/es5/modules/html-builder.js +461 -0
  62. package/es6/legacy/es5/modules/layout.js +1679 -0
  63. package/es6/legacy/es5/modules/mouse.js +124 -0
  64. package/es6/legacy/es5/modules/nav-link.js +123 -0
  65. package/es6/legacy/es5/modules/olderversions/animations-ease.js +1095 -0
  66. package/es6/legacy/es5/modules/olderversions/animations-update.js +1048 -0
  67. package/es6/legacy/es5/modules/olderversions/base-animations.js +636 -0
  68. package/es6/legacy/es5/modules/olderversions/base-component-class.js +100 -0
  69. package/es6/legacy/es5/modules/olderversions/base-data-binder-1.js +407 -0
  70. package/es6/legacy/es5/modules/olderversions/base-data-binder-class.js +358 -0
  71. package/es6/legacy/es5/modules/olderversions/base-layout-parser-class.js +172 -0
  72. package/es6/legacy/es5/modules/olderversions/base-mode-1.js +777 -0
  73. package/es6/legacy/es5/modules/olderversions/base-model-class.js +585 -0
  74. package/es6/legacy/es5/modules/olderversions/data-binder/element-binding/base-data-binder-class.js +358 -0
  75. package/es6/legacy/es5/modules/olderversions/data-binder/element-binding/base-model-class.js +585 -0
  76. package/es6/legacy/es5/modules/olderversions/data-binder/model-binding/base-data-binder-class.js +353 -0
  77. package/es6/legacy/es5/modules/olderversions/data-binder/model-binding/base-model-class.js +604 -0
  78. package/es6/legacy/es5/modules/olderversions/data-binder-update-watcher.js +640 -0
  79. package/es6/legacy/es5/modules/olderversions/data-tracker.js +187 -0
  80. package/es6/legacy/es5/modules/olderversions/event-update.js +666 -0
  81. package/es6/legacy/es5/modules/olderversions/nav-link.js +119 -0
  82. package/es6/legacy/es5/modules/olderversions/router-with-templates-1.js +785 -0
  83. package/es6/legacy/es5/modules/olderversions/router-with-templates.js +701 -0
  84. package/es6/legacy/es5/modules/prototypes/ajax.js +657 -0
  85. package/es6/legacy/es5/modules/prototypes/atom.js +65 -0
  86. package/es6/legacy/es5/modules/prototypes/component.js +972 -0
  87. package/es6/legacy/es5/modules/prototypes/data-binder.js +1089 -0
  88. package/es6/legacy/es5/modules/prototypes/data.js +1290 -0
  89. package/es6/legacy/es5/modules/prototypes/html-builder.js +414 -0
  90. package/es6/legacy/es5/modules/prototypes/layout.js +879 -0
  91. package/es6/legacy/es5/modules/router.js +1680 -0
  92. package/es6/legacy/es5/modules/state.js +274 -0
  93. package/es6/main.js +1331 -0
  94. package/es6/modules/ajax/ajax.js +514 -0
  95. package/es6/modules/animation/animation.js +236 -0
  96. package/es6/modules/animations/animation-controller.js +231 -0
  97. package/es6/modules/animations/animation.js +64 -0
  98. package/es6/modules/animations/attr-movement.js +66 -0
  99. package/es6/modules/animations/css-movement.js +170 -0
  100. package/es6/modules/animations/movement.js +131 -0
  101. package/es6/modules/animations/value.js +187 -0
  102. package/es6/modules/atom/atom.js +54 -0
  103. package/es6/modules/component/component.js +230 -0
  104. package/es6/modules/component/event-helper.js +119 -0
  105. package/es6/modules/component/jot.js +144 -0
  106. package/es6/modules/component/state-helper.js +262 -0
  107. package/es6/modules/component/unit.js +551 -0
  108. package/es6/modules/data/attrs.js +40 -0
  109. package/es6/modules/data/basic-data.js +500 -0
  110. package/es6/modules/data/data-utils.js +29 -0
  111. package/es6/modules/data/data.js +3 -0
  112. package/es6/modules/data/deep-data.js +541 -0
  113. package/es6/modules/data/model-service.js +528 -0
  114. package/es6/modules/data/model.js +133 -0
  115. package/es6/modules/data/simple-data.js +33 -0
  116. package/es6/modules/data-binder/connection-tracker.js +113 -0
  117. package/es6/modules/data-binder/connection.js +16 -0
  118. package/es6/modules/data-binder/data-binder.js +352 -0
  119. package/es6/modules/data-binder/data-pub-sub.js +141 -0
  120. package/es6/modules/data-binder/data-source.js +56 -0
  121. package/es6/modules/data-binder/element-source.js +219 -0
  122. package/es6/modules/data-binder/one-way-connection.js +46 -0
  123. package/es6/modules/data-binder/one-way-source.js +43 -0
  124. package/es6/modules/data-binder/source.js +36 -0
  125. package/es6/modules/data-binder/two-way-connection.js +75 -0
  126. package/es6/modules/data-binder/two-way-source.js +41 -0
  127. package/es6/modules/date/date.js +544 -0
  128. package/es6/modules/history/history.js +89 -0
  129. package/es6/modules/html-builder/html-builder.js +434 -0
  130. package/es6/modules/import/import.js +390 -0
  131. package/es6/modules/layout/layout-builder.js +1269 -0
  132. package/es6/modules/layout/layout-parser.js +134 -0
  133. package/es6/modules/layout/watcher-helper.js +282 -0
  134. package/es6/modules/mouse/mouse.js +114 -0
  135. package/es6/modules/router/component-helper.js +163 -0
  136. package/es6/modules/router/history-controller.js +216 -0
  137. package/es6/modules/router/nav-link.js +124 -0
  138. package/es6/modules/router/route.js +401 -0
  139. package/es6/modules/router/router.js +789 -0
  140. package/es6/modules/router/utils.js +31 -0
  141. package/es6/modules/state/state-target.js +91 -0
  142. package/es6/modules/state/state.js +171 -0
  143. package/es6/package-lock.json +13 -0
  144. package/es6/package.json +28 -0
  145. package/es6/shared/objects.js +99 -0
  146. package/legacy/es5/base.js +2968 -0
  147. package/legacy/es5/modules/ajax.js +663 -0
  148. package/legacy/es5/modules/animation.js +188 -0
  149. package/legacy/es5/modules/animations.js +1080 -0
  150. package/legacy/es5/modules/atom.js +65 -0
  151. package/legacy/es5/modules/component.js +1310 -0
  152. package/legacy/es5/modules/data-binder.js +1131 -0
  153. package/legacy/es5/modules/data.js +1808 -0
  154. package/legacy/es5/modules/date.js +525 -0
  155. package/legacy/es5/modules/form-validator.js +324 -0
  156. package/legacy/es5/modules/history.js +126 -0
  157. package/legacy/es5/modules/html-builder.js +461 -0
  158. package/legacy/es5/modules/layout.js +1679 -0
  159. package/legacy/es5/modules/mouse.js +124 -0
  160. package/legacy/es5/modules/nav-link.js +123 -0
  161. package/legacy/es5/modules/olderversions/animations-ease.js +1095 -0
  162. package/legacy/es5/modules/olderversions/animations-update.js +1048 -0
  163. package/legacy/es5/modules/olderversions/base-animations.js +636 -0
  164. package/legacy/es5/modules/olderversions/base-component-class.js +100 -0
  165. package/legacy/es5/modules/olderversions/base-data-binder-1.js +407 -0
  166. package/legacy/es5/modules/olderversions/base-data-binder-class.js +358 -0
  167. package/legacy/es5/modules/olderversions/base-layout-parser-class.js +172 -0
  168. package/legacy/es5/modules/olderversions/base-mode-1.js +777 -0
  169. package/legacy/es5/modules/olderversions/base-model-class.js +585 -0
  170. package/legacy/es5/modules/olderversions/data-binder/element-binding/base-data-binder-class.js +358 -0
  171. package/legacy/es5/modules/olderversions/data-binder/element-binding/base-model-class.js +585 -0
  172. package/legacy/es5/modules/olderversions/data-binder/model-binding/base-data-binder-class.js +353 -0
  173. package/legacy/es5/modules/olderversions/data-binder/model-binding/base-model-class.js +604 -0
  174. package/legacy/es5/modules/olderversions/data-binder-update-watcher.js +640 -0
  175. package/legacy/es5/modules/olderversions/data-tracker.js +187 -0
  176. package/legacy/es5/modules/olderversions/event-update.js +666 -0
  177. package/legacy/es5/modules/olderversions/nav-link.js +119 -0
  178. package/legacy/es5/modules/olderversions/router-with-templates-1.js +785 -0
  179. package/legacy/es5/modules/olderversions/router-with-templates.js +701 -0
  180. package/legacy/es5/modules/prototypes/ajax.js +657 -0
  181. package/legacy/es5/modules/prototypes/atom.js +65 -0
  182. package/legacy/es5/modules/prototypes/component.js +972 -0
  183. package/legacy/es5/modules/prototypes/data-binder.js +1089 -0
  184. package/legacy/es5/modules/prototypes/data.js +1290 -0
  185. package/legacy/es5/modules/prototypes/html-builder.js +414 -0
  186. package/legacy/es5/modules/prototypes/layout.js +879 -0
  187. package/legacy/es5/modules/router.js +1680 -0
  188. package/legacy/es5/modules/state.js +274 -0
  189. package/package.json +8 -3
  190. package/update +16 -0
@@ -0,0 +1,219 @@
1
+ import {base} from '../../core.js';
2
+ import {TwoWaySource} from './two-way-source.js';
3
+
4
+ /**
5
+ * This will set an element attr by the setAttribute method.
6
+ *
7
+ * @param {object} element
8
+ * @param {string} attr
9
+ * @param {mixed} value
10
+ */
11
+ const SetAttr = (element, attr, value) =>
12
+ {
13
+ base.setAttr(element, attr, value);
14
+ };
15
+
16
+ const UpdateRadioAttr = (element, attr, value) =>
17
+ {
18
+ element.checked = (element.value === value);
19
+ };
20
+
21
+ const UpdateCheckboxAttr = (element, attr, value) =>
22
+ {
23
+ value = (value == 1);
24
+ UpdateAttr(element, attr, value);
25
+ };
26
+
27
+ /**
28
+ * This will update an element attr by the bracket notation.
29
+ *
30
+ * @param {object} element
31
+ * @param {string} attr
32
+ * @param {nixed} value
33
+ */
34
+ const UpdateAttr = (element, attr, value) =>
35
+ {
36
+ element[attr] = value;
37
+ };
38
+
39
+ const GetAttr = (element, attr) =>
40
+ {
41
+ return base.getAttr(element, attr);
42
+ };
43
+
44
+ const GetAttribute = (element, attr) =>
45
+ {
46
+ return element[attr];
47
+ };
48
+
49
+ /**
50
+ * ElementSource
51
+ *
52
+ * This will create an element source to use with
53
+ * a connection.
54
+ * @class
55
+ * @augments TwoWaySource
56
+ */
57
+ export class ElementSource extends TwoWaySource
58
+ {
59
+ /**
60
+ * @constructor
61
+ * @param {object} element
62
+ * @param {string} attr
63
+ * @param {(string|function)} [filter]
64
+ */
65
+ constructor(element, attr, filter)
66
+ {
67
+ super();
68
+ this.element = element;
69
+ this.attr = this.getAttrBind(attr);
70
+ this.addSetMethod(element, this.attr);
71
+
72
+ this.filter = (typeof filter === 'string')? this.setupFilter(filter) : filter;
73
+ }
74
+
75
+ addSetMethod(element, attr)
76
+ {
77
+ if(attr.substring(4, 1) === '-')
78
+ {
79
+ this.setValue = SetAttr;
80
+ this.getValue = GetAttr;
81
+ }
82
+ else
83
+ {
84
+ this.getValue = GetAttribute;
85
+
86
+ var type = element.type;
87
+ if(type)
88
+ {
89
+ switch(type)
90
+ {
91
+ case 'checkbox':
92
+ this.setValue = UpdateCheckboxAttr;
93
+ return;
94
+ case 'radio':
95
+ this.setValue = UpdateRadioAttr;
96
+ return;
97
+ }
98
+ }
99
+
100
+ this.setValue = UpdateAttr;
101
+ }
102
+ }
103
+
104
+ /**
105
+ * This will get the bind attribute.
106
+ *
107
+ * @param {string} [customAttr]
108
+ * @return {string}
109
+ */
110
+ getAttrBind(customAttr)
111
+ {
112
+ /* this will setup the custom attr if the prop
113
+ has specified one. */
114
+ if(customAttr)
115
+ {
116
+ return customAttr;
117
+ }
118
+
119
+ let attr = 'textContent';
120
+ /* if no custom attr has been requested we will get the
121
+ default attr of the element */
122
+ let element = this.element;
123
+ if(!(element && typeof element === 'object'))
124
+ {
125
+ return attr;
126
+ }
127
+
128
+ let tagName = element.tagName.toLowerCase();
129
+ if (tagName === "input" || tagName === "textarea" || tagName === "select")
130
+ {
131
+ let type = element.type;
132
+ if(type)
133
+ {
134
+ switch(type)
135
+ {
136
+ case 'checkbox':
137
+ attr = 'checked';
138
+ break;
139
+ case 'file':
140
+ attr = 'files';
141
+ break;
142
+ default:
143
+ attr = 'value';
144
+ }
145
+ }
146
+ else
147
+ {
148
+ attr = 'value';
149
+ }
150
+ }
151
+ return attr;
152
+ }
153
+
154
+ /**
155
+ * This will setup a filter callBack.
156
+ *
157
+ * @param {string} filter
158
+ * @return {function}
159
+ */
160
+ setupFilter(filter)
161
+ {
162
+ let pattern = /(\[\[[^\]]+\]\])/;
163
+ return (value) =>
164
+ {
165
+ return filter.replace(pattern, value);
166
+ };
167
+ }
168
+
169
+ /**
170
+ * This will set a value on an element.
171
+ *
172
+ * @param {*} value
173
+ */
174
+ set(value)
175
+ {
176
+ let element = this.element;
177
+ if(!element || typeof element !== 'object')
178
+ {
179
+ return false;
180
+ }
181
+
182
+ /* this will check to apply the option filter before
183
+ setting the value */
184
+ if(this.filter)
185
+ {
186
+ value = this.filter(value);
187
+ }
188
+
189
+ this.setValue(element, this.attr, value);
190
+ }
191
+
192
+ /**
193
+ * This will get the value from an element.
194
+ */
195
+ get()
196
+ {
197
+ let element = this.element;
198
+ if(!element || typeof element !== 'object')
199
+ {
200
+ return '';
201
+ }
202
+
203
+ return this.getValue(element, this.attr);
204
+ }
205
+
206
+ /**
207
+ * The callBack when updated.
208
+ *
209
+ * @param {*} value
210
+ * @param {object} committer
211
+ */
212
+ callBack(value, committer)
213
+ {
214
+ if(committer !== this.element)
215
+ {
216
+ this.set(value);
217
+ }
218
+ }
219
+ }
@@ -0,0 +1,46 @@
1
+ import {OneWaySource} from './one-way-source.js';
2
+ import {Connection} from './connection.js';
3
+
4
+ /**
5
+ * OneWayConnection
6
+ *
7
+ * This will create a one way connection.
8
+ * @class
9
+ * @augments Connection
10
+ */
11
+ export class OneWayConnection extends Connection
12
+ {
13
+ /**
14
+ * @constructor
15
+ */
16
+ constructor()
17
+ {
18
+ super();
19
+
20
+ /**
21
+ * @member {object} source
22
+ */
23
+ this.source = null;
24
+ }
25
+
26
+ /**
27
+ * This will setup the connection source.
28
+ *
29
+ * @param {object} data
30
+ * @return {object}
31
+ */
32
+ addSource(data)
33
+ {
34
+ return (this.source = new OneWaySource(data));
35
+ }
36
+
37
+ /**
38
+ * This will be used to unsubscribe.
39
+ * @override
40
+ */
41
+ unsubscribe()
42
+ {
43
+ this.source.unsubscribe();
44
+ this.source = null;
45
+ }
46
+ }
@@ -0,0 +1,43 @@
1
+ import {Source} from './source.js';
2
+
3
+ /**
4
+ * OneWaySource
5
+ *
6
+ * This will create a one way source to use with
7
+ * a connection.
8
+ * @class
9
+ * @augments Source
10
+ */
11
+ export class OneWaySource extends Source
12
+ {
13
+ /**
14
+ * This will setup the data source.
15
+ *
16
+ * @param {object} data
17
+ */
18
+ constructor(data)
19
+ {
20
+ super();
21
+ this.data = data;
22
+ }
23
+
24
+ /**
25
+ * This will subscribe to a message.
26
+ *
27
+ * @param {string} msg
28
+ * @param {function} callBack
29
+ */
30
+ subscribe(msg, callBack)
31
+ {
32
+ this.msg = msg;
33
+ this.token = this.data.on(msg, callBack);
34
+ }
35
+
36
+ /**
37
+ * This will unsubscribe from the message.
38
+ */
39
+ unsubscribe()
40
+ {
41
+ this.data.off(this.msg, this.token);
42
+ }
43
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Source
3
+ *
4
+ * This will create a new source to use with
5
+ * a connection.
6
+ * @class
7
+ */
8
+ export class Source
9
+ {
10
+ /**
11
+ * @constructor
12
+ */
13
+ constructor()
14
+ {
15
+ /**
16
+ * @member {string} msg
17
+ * @protected
18
+ */
19
+ this.msg = null;
20
+
21
+ /**
22
+ * @member {string} token
23
+ */
24
+ this.token = null;
25
+ }
26
+
27
+ /**
28
+ * This will set the token.
29
+ *
30
+ * @param {string} token
31
+ */
32
+ setToken(token)
33
+ {
34
+ this.token = token;
35
+ }
36
+ }
@@ -0,0 +1,75 @@
1
+ import {DataSource} from './data-source.js';
2
+ import {ElementSource} from './element-source.js';
3
+ import {Connection} from './connection.js';
4
+
5
+ /**
6
+ * TwoWayConnection
7
+ *
8
+ * This will setup a two way connection.
9
+ * @class
10
+ * @augments Connection
11
+ */
12
+ export class TwoWayConnection extends Connection
13
+ {
14
+ /**
15
+ * @constructor
16
+ */
17
+ constructor()
18
+ {
19
+ super();
20
+
21
+ this.element = null;
22
+ this.data = null;
23
+ }
24
+
25
+ /**
26
+ * This will add the element source.
27
+ *
28
+ * @param {object} element
29
+ * @param {string} attr
30
+ * @param {(string|function)} filter
31
+ * @return {object}
32
+ */
33
+ addElement(element, attr, filter)
34
+ {
35
+ return (this.element = new ElementSource(element, attr, filter));
36
+ }
37
+
38
+ /**
39
+ * This will add the data source.
40
+ *
41
+ * @param {object} data
42
+ * @param {string} prop
43
+ * @return {object}
44
+ */
45
+ addData(data, prop)
46
+ {
47
+ return (this.data = new DataSource(data, prop));
48
+ }
49
+
50
+ /**
51
+ * This will unsubscribe from a source.
52
+ *
53
+ * @param {object} source
54
+ */
55
+ unsubscribeSource(source)
56
+ {
57
+ if(source)
58
+ {
59
+ source.unsubscribe();
60
+ }
61
+ }
62
+
63
+ /**
64
+ * This will be used to unsubscribe.
65
+ * @override
66
+ */
67
+ unsubscribe()
68
+ {
69
+ this.unsubscribeSource(this.element);
70
+ this.unsubscribeSource(this.data);
71
+
72
+ this.element = null;
73
+ this.data = null;
74
+ }
75
+ }
@@ -0,0 +1,41 @@
1
+ import {Source} from './source.js';
2
+ import {pubSub} from './data-pub-sub.js';
3
+
4
+ /**
5
+ * TwoWaySource
6
+ *
7
+ * This will create a two way source to use with
8
+ * a connection.
9
+ * @class
10
+ * @augments Source
11
+ */
12
+ export class TwoWaySource extends Source
13
+ {
14
+ /**
15
+ * This will subscribe to a message.
16
+ *
17
+ * @param {string} msg
18
+ */
19
+ subscribe(msg)
20
+ {
21
+ this.msg = msg;
22
+ let callBack = this.callBack.bind(this);
23
+ this.token = pubSub.on(msg, callBack);
24
+ }
25
+
26
+ /**
27
+ * This will unsubscribe from a message.
28
+ */
29
+ unsubscribe()
30
+ {
31
+ pubSub.off(this.msg, this.token);
32
+ }
33
+
34
+ /**
35
+ * Override this to setup cource callBack.
36
+ */
37
+ callBack()
38
+ {
39
+
40
+ }
41
+ }