efront 3.10.4 → 3.11.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.
@@ -9,3 +9,4 @@
9
9
  params: options ::params-:key
10
10
  invoke: options ::invoke-:key?:params
11
11
  version: options ::version
12
+ uptime: options ::uptime
@@ -20,4 +20,9 @@
20
20
  <padding>
21
21
  服务器版本&nbsp;&nbsp;<span -text="String(version)"></span>
22
22
  </padding>
23
- </block>
23
+ </block>
24
+ <block>
25
+ <padding>
26
+ 启动时间&nbsp;&nbsp;<span -text="filterTime(hrtime)"></span>
27
+ </padding>
28
+ </block>
@@ -4,6 +4,8 @@ function main() {
4
4
  renderWithDefaults(page, {
5
5
  status: [],
6
6
  version: data.from("version"),
7
+ hrtime: data.from("uptime", a => Date.now() - a * 1000),
8
+ filterTime,
7
9
  async run(id, target) {
8
10
  target.setAttribute('pending', '')
9
11
  try {
@@ -33,7 +33,6 @@
33
33
  };
34
34
  var parseMenuList = function (items) {
35
35
  if (items instanceof Array) {
36
- console.log(items)
37
36
  return items;
38
37
  }
39
38
  if (items instanceof Object) {
@@ -1,8 +1,12 @@
1
1
  // 激活 自定义的 active 事件
2
- function active(target, value, item) {
2
+ function active(target, value, item, targetElement) {
3
3
  var activeEvent = createEvent("active");
4
4
  activeEvent.item = item;
5
5
  activeEvent.value = value;
6
+ if (targetElement) {
7
+ if (Object.defineProperty) Object.defineProperty(activeEvent, 'currentTarget', { value: targetElement });
8
+ else activeEvent.currentTarget = targetElement;
9
+ }
6
10
  activeEvent = dispatch(target, activeEvent);
7
11
  return activeEvent && !activeEvent.defaultPrevented;
8
12
  }
@@ -0,0 +1,47 @@
1
+ var keyMap = {};
2
+ on("keydown")(window, function (event) {
3
+ var { which } = event;
4
+ switch (event.which) {
5
+ case 18:
6
+ event.preventDefault();
7
+ break;
8
+ default:
9
+ var key = String.fromCharCode(which);
10
+ var elems = keyMap[key];
11
+ if (elems) while (elems.length) {
12
+ var elem = elems[elems.length - 1];
13
+ if (isMounted(elem)) break;
14
+ else elems.pop();
15
+ }
16
+ if (elem) {
17
+ var parent = elem.parentNode;
18
+ if (event.altKey || parent === document.activeElement || parent.ispop) {
19
+ event.preventDefault();
20
+ elem.click();
21
+ }
22
+ }
23
+ }
24
+ });
25
+ var bindAccesskey = function (btn, k) {
26
+ if (!keyMap[k]) keyMap[k] = [];
27
+ removeFromList(keyMap[k], btn);
28
+ keyMap[k].push(btn);
29
+ once("remove")(btn, function () {
30
+ removeFromList(keyMap[k], btn);
31
+ });
32
+ };
33
+ var getKeyFromText = function (btn) {
34
+ var { innerText } = btn;
35
+ var match = /\(\s*\_?\w\s*\)|\[\s*\_?\w\s*\]|\{\s*\_?\w\s*\}/.exec(innerText);
36
+ if (match) {
37
+ var accesskey = match[0].replace(/^\W*(\w)\W*$/g, '$1');
38
+ } else {
39
+ var accesskey = btn.getAttribute("accesskey");
40
+ }
41
+ if (!accesskey) return;
42
+ return accesskey.toUpperCase();
43
+ }
44
+ function main(elem, key = getKeyFromText(elem)) {
45
+ bindAccesskey(elem, key);
46
+ return elem;
47
+ }
@@ -2,29 +2,6 @@ var _label = createElement("span");
2
2
  var track = createElement(div);
3
3
  track.className = "track";
4
4
  _label.className = "label";
5
- var keyMap = {};
6
- on("keydown")(window, function (event) {
7
- var { which } = event;
8
- switch (event.which) {
9
- case 18:
10
- event.preventDefault();
11
- break;
12
- default:
13
- if (event.altKey) {
14
- var key = String.fromCharCode(which);
15
- var element = keyMap[key];
16
-
17
- if (element) {
18
- if (isMounted(element)) {
19
- dispatch(window, 'mousedown');
20
- element.click();
21
- } else {
22
- delete keyMap[key];
23
- }
24
- }
25
- }
26
- }
27
- });
28
5
 
29
6
  var btn = document.createElement("button");
30
7
  btn.tabIndex = 0;
@@ -76,17 +53,6 @@ var touchstart = function () {
76
53
  var canceltouchend = ontouchend(this, cancel);
77
54
  active.call(this);
78
55
  };
79
- var bindAccesskey = function (btn) {
80
- var { innerText } = btn;
81
- var match = /\(\s*\_?\w\s*\)|\[\s*\_?\w\s*\]|\{\s*\_?\w\s*\}/.exec(innerText);
82
- if (match) {
83
- var accesskey = match[0].replace(/^\W*(\w)\W*$/g, '$1');
84
- } else {
85
- var accesskey = btn.getAttribute("accesskey");
86
- }
87
- if (!accesskey) return;
88
- keyMap[accesskey.toUpperCase()] = btn;
89
- };
90
56
  function button(texter, type) {
91
57
  var tracker = createElement(track);
92
58
  var _texter;
@@ -254,13 +254,15 @@ function stringify(color) {
254
254
  }
255
255
  }
256
256
  function doWith(manager, color, args) {
257
- var c = parse(color);
257
+ var isparsed = color instanceof Array,
258
+ c = isparsed ? color : parse(color);
258
259
  if (!c) {
259
260
  console.warn(`颜色数据不正确:${color}`);
260
261
  return color;
261
262
  }
262
263
  c = manager(c, args);
263
- return stringify(c);
264
+ if (!isparsed) c = stringify(c);
265
+ return c;
264
266
  }
265
267
 
266
268
  function normal([r, g, b]) {
@@ -962,7 +962,7 @@ var data = {
962
962
  instanceDataMap[instanceId] = data;
963
963
  }
964
964
  setItem(instanceId, data, rememberWithStorage);
965
- fireListener(instanceId);
965
+ fireListener(instanceId, data);
966
966
  return instanceDataMap[instanceId];
967
967
  },
968
968
  patchInstance(instanceId, data, rememberWithStorage = 0) {
@@ -999,7 +999,7 @@ var data = {
999
999
  if (!~listeners.indexOf(callback)) {
1000
1000
  listeners.push(callback);
1001
1001
  }
1002
- callback(this.getInstance(instanceId));
1002
+ if (hasItem(instanceId)) callback(getItem(instanceId));
1003
1003
  },
1004
1004
  unbindInstance(instanceId, callback) {
1005
1005
  if (!instanceListenerMap[instanceId]) return;
@@ -1047,12 +1047,15 @@ function getItem(instanceId, onlyFromLocalStorage = false) {
1047
1047
  }
1048
1048
  return data;
1049
1049
  }
1050
+ function hasItem(instanceId) {
1051
+ const storageId = userPrefix + instanceId + pagePathName;
1052
+ return sessionStorage.getItem(storageId) || localStorage.getItem(storageId);
1053
+ }
1050
1054
  var instanceListenerMap = {};
1051
- var fireListener = function (instanceId) {
1055
+ var fireListener = function (instanceId, data) {
1052
1056
  var listeners = instanceListenerMap[instanceId];
1053
1057
  if (!listeners) return;
1054
- var instance = instanceDataMap[instanceId];
1055
- listeners.forEach(a => a(instance));
1058
+ listeners.forEach(a => a(data));
1056
1059
  };
1057
1060
  data.setItem = data.setInstance;
1058
1061
  data.getItem = data.getInstance;
@@ -148,20 +148,24 @@ function main(elem, mode) {
148
148
  case "x":
149
149
  case "horizonal":
150
150
  var direction = 'x';
151
+ mode = "horizonal";
151
152
  case "v":
152
153
  case "y":
153
154
  case "vertical":
154
- var emit = function (item) {
155
- active(elem, item, item.value);
155
+ var emit = function (item, target) {
156
+ active(elem, item, item.value, target);
156
157
  };
157
158
  if ("$src" in elem) {
158
159
  getGenerator(elem);
159
160
  care(elem, function (src) {
160
161
  menuList(elem, getTreeFromData(src), emit, direction);
162
+ elem.registerAsRoot();
161
163
  });
162
- } else {
164
+ }
165
+ else {
163
166
  var nodes = getArrayNodes(elem);
164
- elem = menuList(elem, nodes, emit);
167
+ elem = menuList(elem, nodes, emit, direction);
168
+ elem.registerAsRoot();
165
169
  }
166
170
  break;
167
171
  default:
@@ -92,12 +92,19 @@ body:active & {
92
92
  display: block;
93
93
  overflow: hidden;
94
94
  text-overflow: hidden;
95
- height: 40px;
95
+ line-height: 40px;
96
96
  position: relative;
97
- border: 1px solid #18333c;
98
- background-color: #18333c;
99
- box-shadow: inset 0 0 12px #51ddf6, inset 0px -120px 120px -120px #51ddf6;
100
- border-right: none;
97
+ border-bottom: 1px solid #18333c;
98
+ padding: 0;
99
+
100
+ menu-item {
101
+ display: inline-block;
102
+
103
+ &.has-children:after {
104
+ padding-top: 3px;
105
+ content: "﹀";
106
+ }
107
+ }
101
108
 
102
109
  >div {
103
110
  vertical-align: top;
@@ -1,3 +1,3 @@
1
- <i ng-class="menu.icon" ng-if='useIcon||hasIcon||menu.icon'></i>
2
- <span ng-model="menu.name"></span>
1
+ <i ng-class="icon" ng-if='useIcon||hasIcon'></i>
2
+ <span ng-html="name"></span>
3
3
  <s></s>
@@ -1,11 +1,15 @@
1
1
  function main(elem, scope, hasIcon) {
2
2
  var item = elem || document.createElement('menu-item');
3
3
  item.innerHTML = menuItem;
4
- if (isObject(scope) && scope !== elem.$scope) {
5
- render(item, { menu: scope, useIcon: hasIcon, hasIcon })
4
+ if (isObject(scope) && scope !== item.$scope) {
6
5
  }
7
6
  else {
8
- extendIfNeeded(elem.$scope, { useIcon: false, hasIcon: false })
7
+ var scope = item.$scope;
9
8
  }
9
+ if (scope.menu) scope = scope.menu;
10
+ var name = scope.name;
11
+ var icon = scope.icon;
12
+ if (hasIcon === undefined) hasIcon = !!icon;
13
+ render(item.children, { useIcon: hasIcon, hasIcon, name, icon });
10
14
  return item;
11
15
  }
@@ -1,4 +1,4 @@
1
- <menu-item ng-repeat="menu in menus" ng-if="!menu.hidden" ng-click="open(menu,event)"
2
- ng-mouseleave="clearTimeout(popTimer)" ng-mouseenter="popTimer=popMenu(menu,event)"
1
+ <menu-item ng-repeat="menu in menus" ng-if="!menu.hidden" ng-click="open.call(this)"
2
+ ng-mouseleave="cancel()" ng-mouseenter="popMenu.call(this)"
3
3
  ng-class="{'has-children':menu.children&&menu.children.length,'warn':menu.type==='danger'||menu.type==='warn'||menu.type==='red'}">
4
4
  </menu-item>
@@ -1,4 +1,4 @@
1
- var mounted_menus = [], releaseTimer = 0;
1
+ var mounted_menus = [], releaseTimer = 0, root_menu;
2
2
  var release = function () {
3
3
  clear();
4
4
  releaseTimer = setTimeout(function () {
@@ -8,46 +8,224 @@ var release = function () {
8
8
  var clear = function () {
9
9
  clearTimeout(releaseTimer);
10
10
  };
11
+ var unfocus = function () {
12
+ remove(mounted_menus);
13
+ this.ispop = false;
14
+ };
15
+ var setFocus = function (focused = this.firstMenu) {
16
+ var page = this;
17
+ if (page.ispop || page === document.activeElement) {
18
+ if (page.focused !== focused) {
19
+ if (page.focused) removeClass(page.focused, 'focus');
20
+ if (focused) addClass(focused, "focus");
21
+ page.focused = focused;
22
+ }
23
+ }
24
+ else {
25
+ if (page.focused) {
26
+ removeClass(page.focused, 'focus');
27
+ page.focused = null;
28
+ }
29
+ }
30
+ };
31
+ var moveFocus = function (delta) {
32
+ var page = this;
33
+ var focused = page.focused;
34
+ var newIndex = 0;
35
+ if (!focused) {
36
+ if (delta > 0) newIndex = 0;
37
+ else newIndex = page.total - 1;
38
+ }
39
+ else {
40
+ var newIndex = focused.index + delta;
41
+ var total = page.total;
42
+ if (page !== root_menu) {
43
+ total++;
44
+ }
45
+ if (newIndex < 0) newIndex = total + newIndex;
46
+ if (newIndex > total - 1) newIndex = newIndex - total;
47
+ }
48
+
49
+ var e = page.getIndexedElement(newIndex);
50
+ if (!e) page.setFocus(null);
51
+ else page.open(e);
52
+ };
53
+ var openFocus = function () {
54
+ var menu = mounted_menus[mounted_menus.length - 1] || root_menu;
55
+ if (!menu.ispop) menu.ispop = 1;
56
+ menu.open(menu.focused);
57
+ };
58
+ var closeFocus = function () {
59
+ var menu = mounted_menus[mounted_menus.length - 1];
60
+ remove(menu);
61
+ };
62
+ var keyAction = function (deltax, deltay) {
63
+ if (root_menu !== document.activeElement) return;
64
+ var menu = mounted_menus[mounted_menus.length - 1];
65
+ if (menu) var parent = mounted_menus[mounted_menus.length - 2] || root_menu;
66
+ else menu = root_menu;
67
+
68
+ if (menu.direction === 'y') {
69
+ if (deltax === 1) {
70
+ if (menu.focused) openFocus();
71
+ else if (parent && parent.direction !== 'y') {
72
+ parent.moveFocus(deltax);
73
+ }
74
+ }
75
+ else if (deltax === -1) {
76
+ if (parent) {
77
+ if (parent.direction === 'y') remove(mounted_menus.pop());
78
+ else if (!menu.focused) parent.moveFocus(deltax);
79
+ }
80
+ }
81
+ else {
82
+ menu.moveFocus(deltay);
83
+ }
84
+ }
85
+ else {
86
+ if (deltay === 1) {
87
+ if (menu.focused) openFocus();
88
+ else if (parent && parent.direction === 'y') {
89
+ parent.moveFocus(deltay);
90
+ }
91
+ }
92
+ else if (deltay === -1) {
93
+ if (parent) {
94
+ if (parent.direction !== 'y') remove(mounted_menus.pop());
95
+ else if (!menu.focused) parent.moveFocus(deltay);
96
+ }
97
+ }
98
+ else {
99
+ menu.moveFocus(deltax);
100
+ }
101
+ }
102
+ };
103
+ function keyalt() {
104
+ if (root_menu === document.activeElement) root_menu.blur();
105
+ else {
106
+ root_menu.tabIndex = 0;
107
+ root_menu.focus();
108
+ }
109
+ root_menu.setFocus();
110
+ }
111
+ function keyesc() {
112
+ if (root_menu === document.activeElement && !mounted_menus.length) {
113
+ if (!root_menu.ispop) root_menu.blur(), root_menu.setFocus();
114
+ else root_menu.ispop = false;
115
+ }
116
+ }
117
+ function keyup() {
118
+ keyAction(0, -1);
119
+ }
120
+ function keydown() {
121
+ keyAction(0, 1);
122
+ }
123
+ function keyleft() {
124
+ keyAction(-1, 0)
125
+ }
126
+ function keyright() {
127
+ keyAction(1, 0);
128
+ }
129
+ function keyspace() {
130
+ if (root_menu !== document.activeElement) return;
131
+ var menu = mounted_menus[mounted_menus.length - 1] || root_menu;
132
+ menu.focused.click();
133
+ }
134
+ function register() {
135
+ // on('keydown.alt')(window, e => e.preventDefault());
136
+ on('keydown.alt.')(window, keyalt);
137
+ on('keydown.esc')(window, keyesc);
138
+ on('keydown.left')(window, keyleft);
139
+ on('keydown.right')(window, keyright);
140
+ on('keydown.up')(window, keyup);
141
+ on('keydown.down')(window, keydown);
142
+ on('keydown.enter')(window, keyspace);
143
+ on('keydown.space')(window, keyspace);
144
+ root_menu = this;
145
+ }
11
146
  function main(page, items, active, direction = 'y') {
12
147
  if (!isNode(page)) {
13
148
  var page = div();
14
149
  }
15
150
  var main = this;
16
- function popMenu(item, event) {
151
+ if (direction !== 'x') page.ispop = true;
152
+ function popMenu(item, target) {
17
153
  if (page.active) {
18
154
  clear();
19
155
  remove(page.active);
20
156
  }
157
+ page.setFocus(target);
21
158
  if (!item.children || !item.children.length) return;
22
159
  var clone = template.cloneNode();
160
+ clone.$parentScopes = page.$parentScopes;
161
+ clone.$src = src;
23
162
  clone.innerHTML = template.innerHTML;
24
163
  var menu = main(clone, item.children, active);
25
164
  mounted_menus.push(menu);
26
-
27
165
  page.active = menu;
28
- popup(menu, event.target);
29
- var offleave0 = on("mouseleave")(event.target, release);
30
- var offenter0 = on("mouseenter")(event.target, clear);
31
- var offleave1 = on("mouseleave")(menu, release);
32
- var offenter1 = on("mouseenter")(menu, clear);
166
+ menu.root = page.root || page;
167
+ popup(menu, target);
168
+ if (page.ispop === true) {
169
+ var offleave0 = on("mouseleave")(target, release);
170
+ var offleave1 = on("mouseleave")(menu, release);
171
+ var offenter0 = on("mouseenter")(target, clear);
172
+ var offenter1 = on("mouseenter")(menu, clear);
173
+ } else {
174
+ page.ispop = 1;
175
+ page.tabIndex = 0;
176
+ page.focus();
177
+ }
178
+ on("mousedown")(menu, e => e.preventDefault());
33
179
  once("remove")(menu, function () {
34
- removeFromList(mounted_menus, page.active);
35
- offleave0();
36
- offenter0();
37
- offleave1();
38
- offenter1();
180
+ removeFromList(mounted_menus, this);
181
+ if (offleave0) offleave0();
182
+ if (offleave1) offleave1();
183
+ if (offenter0) offenter0();
184
+ if (offenter1) offenter1();
39
185
  });
40
186
  }
41
-
42
- var template = page.tempalte || page.cloneNode();
187
+ if (!page.ispop) on("blur")(page, unfocus);
188
+ var template = page.tempalte || document.createElement("ylist");
43
189
  if (!page.tempalte) {
44
190
  template.className = '';
45
191
  template.removeAttribute('mode');
46
192
  template.innerHTML = page.innerHTML;
47
193
  page.tempalte = template;
48
194
  }
195
+ var popTimer = 0;
196
+ var open = function () {
197
+ cancel();
198
+ var elem = this;
199
+ page.setFocus(elem);
200
+ if (page.ispop) popTimer = setTimeout(function () {
201
+ popMenu(elem.menu, elem);
202
+ }, 60);
203
+ };
204
+ var cancel = function () {
205
+ clearTimeout(popTimer);
206
+ }
207
+ var fire = function () {
208
+ cancel();
209
+ var pop = active(this.menu, this);
210
+ if (pop === false) return;
211
+ var root = page.root || page;
212
+ if (root.ispop === 1) root.ispop = false;
213
+ if (page.active && page.active.target === this) {
214
+ if (!mounted_menus.length) {
215
+ popMenu(this.menu, this);
216
+ }
217
+ else {
218
+ unfocus.call(page);
219
+ }
220
+ }
221
+ else {
222
+ while (mounted_menus.length && mounted_menus[mounted_menus.length - 1] !== page) remove(mounted_menus.pop());
223
+ popMenu(this.menu, this);
224
+ }
225
+ };
226
+
227
+
49
228
  if (!page.children.length || page.menutype === 1) {
50
- page.innerHTML = menuList;
51
229
  page.menutype = 1;
52
230
  var hasIcon = function () {
53
231
  var menus = items;
@@ -58,42 +236,93 @@ function main(page, items, active, direction = 'y') {
58
236
  }
59
237
  return false;
60
238
  };
61
- render(page, {
62
- "menu-item": function () {
63
- return button(
64
- menuItem.apply(null, arguments)
239
+ var $scope = {
240
+ "menu-item": function (e, s) {
241
+ var a = bindAccesskey(
242
+ menuItem(e, s, this.hasIcon)
65
243
  );
244
+ if (!page.firstMenu) {
245
+ page.firstMenu = a;
246
+ }
247
+ return a;
66
248
  },
67
249
  menus: items,
68
250
  hasIcon: hasIcon(),
69
- open(menu, event) {
70
- active(menu, event);
71
- },
72
- popTimer: 0,
73
- popMenu() {
74
- var args = arguments;
75
- return setTimeout(function () {
76
- popMenu.apply(null, args);
77
- }, 60);
78
- },
79
- });
80
- vbox(page);
251
+ open: fire,
252
+ cancel,
253
+ popMenu: open,
254
+ };
255
+ if (page.$src) {
256
+ var src = page.$src;
257
+ var parentScopes = page.$parentScopes;
258
+ var itemName = src.itemName;
259
+ var className = `{'has-children':${itemName}.children&&${itemName}.children.length,'warn':${itemName}.type==='danger'||${itemName}.type==='warn'||${itemName}.type==='red'}`;
260
+ var notHidden = `!${itemName}.hidden`;
261
+
262
+ list(page, function (index) {
263
+ var item = items[index];
264
+ if (!item) return;
265
+ var a = $scope["menu-item"](null, item);
266
+ var scope = {};
267
+ if (item instanceof Item) item = item.value;
268
+ if (src.itemName) scope[src.itemName] = item;
269
+ else scope.$item = item;
270
+ if (src.keyName) scope[src.keyName] = index;
271
+ else scope.$key = index;
272
+ if (src.indexName) scope[src.indexName] = index;
273
+ else scope.$index = index;
274
+ if (src.srcName) scope[src.srcName] = items;
275
+ if (src.itemName) a.setAttribute("e-if", notHidden);
276
+ a.menu = item;
277
+ on("mouseleave")(a, cancel);
278
+ on("mouseenter")(a, open);
279
+ on("click")(a, fire);
280
+ a.setAttribute("e-class", className);
281
+ render(a, scope, parentScopes);
282
+ return a;
283
+ });
284
+ on("append")(page, function () {
285
+ this.go(0);
286
+ })
287
+ }
288
+ else {
289
+ page.innerHTML = menuList;
290
+ render(page, $scope);
291
+ vbox(page);
292
+ }
293
+ page.total = items.length;
81
294
  page.renders.unshift(function () {
82
295
  this.$scope.hasIcon = hasIcon();
83
296
  });
84
- } else {
297
+ }
298
+ else {
85
299
  var generator = getGenerator(page);
300
+
86
301
  list(page, function (index) {
87
302
  var elem = generator(index);
88
303
  if (!elem) return;
89
- on("mouseenter")(elem, function (event) {
90
- popMenu(this.src[index], event);
91
- });
92
- on("click")(elem, function (event) {
93
- active(this.src[index], event);
94
- });
304
+ if (!page.firstMenu) {
305
+ page.firstMenu = elem;
306
+ page.total = this.src.length;
307
+ }
308
+ elem.menu = this.src[index];
309
+ on("mouseleave")(elem, cancel);
310
+ on("mouseenter")(elem, open);
311
+ on("click")(elem, fire);
95
312
  return elem;
96
313
  }, direction);
97
314
  }
315
+ page.open = function (a) {
316
+ open.call(a);
317
+ };
318
+ page.active = function (a) {
319
+ fire.call(a);
320
+ };
321
+ page.registerAsRoot = register;
322
+ page.setFocus = setFocus;
323
+ page.moveFocus = moveFocus;
324
+ page.openFocus = openFocus;
325
+ page.closeFocus = closeFocus;
326
+ page.direction = direction;
98
327
  return page;
99
328
  }
@@ -17,10 +17,15 @@
17
17
  color: inherit;
18
18
  box-shadow: none;
19
19
  text-align: inherit;
20
- &.warn{
20
+
21
+ &.warn {
21
22
  color: #c28;
22
23
  }
23
24
 
25
+ &.focus {
26
+ color: #29c;
27
+ }
28
+
24
29
  &.has-children {
25
30
  padding: 0 24px 0 16px;
26
31