@litejs/ui 22.12.0 → 23.3.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.
package/load.js CHANGED
@@ -29,9 +29,8 @@
29
29
  // What's New in MSXML 6.0: https://msdn.microsoft.com/en-us/library/ms753751.aspx
30
30
 
31
31
  !function(window, Function, setTimeout) {
32
- xhr._s = new Date
32
+ xhr._s = new Date()
33
33
  var loaded = {}
34
- , urlEscRe = /[+#\s]+/g
35
34
  /*** activex ***/
36
35
  , XMLHttpRequest = +"\v1" && window.XMLHttpRequest || Function("return new ActiveXObject('Microsoft.XMLHTTP')")
37
36
  /**/
@@ -52,7 +51,7 @@
52
51
 
53
52
  /*** onerror ***/
54
53
  , lastError
55
- , unsentErrors = []
54
+ , unsentErrors = xhr._e = []
56
55
  , onerror = window.onerror = function(message, file, line, col, error) {
57
56
  // Do not send multiple copies of the same error.
58
57
  // file = document.currentScript.src || import.meta.url
@@ -63,10 +62,9 @@
63
62
  , message
64
63
  ].join(":")
65
64
  ) && 1 == unsentErrors.push(
66
- [ lastError
67
- // Error().stacktrace in Opera
65
+ [ +new Date()
66
+ , lastError
68
67
  , error && (error.stack || error.stacktrace) || "-"
69
- , +new Date()
70
68
  , "" + location
71
69
  ]
72
70
  )) setTimeout(sendErrors, 307)
@@ -118,11 +116,7 @@
118
116
  // if (sessionID) xhr.setRequestHeader("Cookie", sessionID);
119
117
  // if (xhr.getResponseHeader("Set-Cookie")) sessionID = xhr.getResponseHeader("Set-Cookie");
120
118
 
121
-
122
- // encodeURI("A + B").replace(/%5[BD]/g, decodeURI).replace(/\+/g, "%2B").replace(/%20/g, "+")
123
- // unescape("A+%2B+B".replace(/\+/g, " "))
124
- xhr.open(method, url.replace(urlEscRe, encodeURIComponent).replace(/%20/g, "+"), next !== true)
125
-
119
+ xhr.open(method, url, next !== true)
126
120
 
127
121
  // With IE 8 XMLHttpRequest gains the timeout property.
128
122
  // With the timeout property, Web developers can specify
@@ -247,7 +241,7 @@
247
241
  function exec() {
248
242
  if (res[pos]) {
249
243
  try {
250
- ;(xhr[files[pos].split("?")[0].split(".").pop()] || execScript)(res[pos])
244
+ ;(xhr[files[pos].replace(/[^?]+\.|\?.*/g, "")] || execScript)(res[pos])
251
245
  } catch(e) {
252
246
  onerror(e, files[pos])
253
247
  }
@@ -261,7 +255,7 @@
261
255
  /**/
262
256
  else {
263
257
  if (next) next()
264
- if (res = cb.x) {
258
+ if ((res = cb.x)) {
265
259
  for (i = 0; res[i];) res[i++](0, "", res[i++], res[i++])
266
260
  }
267
261
  }
@@ -275,5 +269,5 @@
275
269
  /**/
276
270
 
277
271
  function nop() {}
278
- }(this, Function, setTimeout)
272
+ }(this, Function, setTimeout) // jshint ignore:line
279
273
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litejs/ui",
3
- "version": "22.12.0",
3
+ "version": "23.3.1",
4
4
  "description": "UI engine for LiteJS full-stack framework",
5
5
  "license": "MIT",
6
6
  "author": "Lauri Rooden <lauri@rooden.ee>",
@@ -21,25 +21,27 @@
21
21
  "el",
22
22
  "polyfill"
23
23
  ],
24
+ "scripts": {
25
+ "test": "TZ='Europe/Tallinn' lj test test/index.js --brief --coverage && jshint --verbose *.js src/*.js binding/*.js polyfill/*.js"
26
+ },
27
+ "devDependencies": {
28
+ "@litejs/cli": "23.3.0",
29
+ "jshint": "2.13.6"
30
+ },
24
31
  "litejs": {
25
32
  "build": "lj b --out=test/index.html test/dev.html"
26
33
  },
27
34
  "jshintConfig": {
35
+ "esversion": 5,
28
36
  "asi": true,
37
+ "evil": true,
29
38
  "laxcomma": true,
30
39
  "maxdepth": 6,
40
+ "node": true,
41
+ "nonbsp": true,
42
+ "undef": true,
43
+ "unused": true,
44
+ "shadow": "outer",
31
45
  "quotmark": "double"
32
- },
33
- "c8": {
34
- "check-coverage": true,
35
- "branches": 100,
36
- "lines": 100,
37
- "functions": 100,
38
- "statements": 100,
39
- "reporter": [
40
- "lcov",
41
- "text",
42
- "html"
43
- ]
44
46
  }
45
47
  }
package/pointer.js CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
+ /* global El */
2
3
  !function(Event, document) {
3
4
  var firstEl, lastDist, lastAngle, pinchThreshhold, mode
4
5
  , TOUCH_FLAG = "-tf"
@@ -167,6 +168,6 @@
167
168
  supportsPointer = 'onpointermove' in window.document;
168
169
  supportsTouchForceChange = 'ontouchforcechange' in window.document;
169
170
  */
170
- }(Event, document)
171
+ }(Event, document) // jshint ignore:line
171
172
 
172
173
 
@@ -15,7 +15,7 @@
15
15
  var i = 64,
16
16
  ba = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),
17
17
  bm = {"=":0};
18
- bm[ba[--i]]=i;
18
+ (bm[ba[--i]] = i);
19
19
  );
20
20
 
21
21
  // base64_encode
@@ -24,13 +24,14 @@
24
24
  b = s.charCodeAt(i++)<<16 | s.charCodeAt(i++)<<8 | s.charCodeAt(i++)
25
25
  out.push(ba[b>>18&0x3f], ba[b>>12&0x3f], ba[b>>6&0x3f], ba[b&0x3f])
26
26
  }
27
- if (len%=3) out.splice(len-3, 2, len==1?"==":"=")
27
+ if ((len %= 3)) out.splice((len - 3), 2, len == 1 ? "==" : "=")
28
28
  return out.join("")
29
29
  }
30
30
 
31
31
  // base64_decode
32
32
  exports.atob = function(s) {
33
- for (var b, out=[], i=0, len=s.length, s=s.split(""); i < len; ) {
33
+ s = s.split("")
34
+ for (var b, out=[], i=0, len=s.length; i < len; ) {
34
35
  b = bm[s[i++]]<<18 | bm[s[i++]]<<12 | bm[s[i++]]<<6 | bm[s[i++]]
35
36
  out.push(b>>16 & 0xff, b>>8 & 0xff, b & 0xff)
36
37
  }
@@ -38,5 +39,5 @@
38
39
  return String.fromCharCode.apply(null, out)
39
40
  }
40
41
  }
41
- }(this)
42
+ }(this) /* jshint -W030 */
42
43
 
package/polyfill/index.js CHANGED
@@ -19,6 +19,8 @@
19
19
  // Event, assign, entries, values, from, sendBeacon, matches, closest
20
20
 
21
21
 
22
+ /* global El, xhr */
23
+ /* c8 ignore start */
22
24
  !function(window, Function) {
23
25
 
24
26
  // Array#flat() - Chrome69, Edge79, Firefox62, Safari12
@@ -32,7 +34,7 @@
32
34
  , O = window
33
35
  , patched = (window.xhr || window)._p = []
34
36
  , jsonRe = /[\x00-\x1f\x22\x5c]/g
35
- , JSONmap = {"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t",'"':'\\"',"\\":"\\\\"}
37
+ , JSONmap = {"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\"":"\\\"","\\":"\\\\"}
36
38
  , hasOwn = JSONmap.hasOwnProperty
37
39
  , esc = escape
38
40
  , document = patch("document", {body:{}})
@@ -40,9 +42,9 @@
40
42
  // JScript engine in IE<9 does not recognize vertical tabulation character
41
43
  // The documentMode is an IE only property, supported from IE8
42
44
  , a = document.documentMode | 0, b, c
43
- , ie678 = !+"\v1" && a < 9
45
+ , ie678 = !+"\v1" && a < 9 // jshint ignore:line
44
46
  , ie6789 = ie678 || a == 9
45
- , ie67 = ie678 && a < 8
47
+ //, ie67 = ie678 && a < 8
46
48
  , EV = "Event"
47
49
  , Event = patch(
48
50
  EV,
@@ -143,7 +145,7 @@
143
145
  , preventDefault = e.preventDefault.bind(e)
144
146
  , stopPropagation = e.stopPropagation.bind(e)
145
147
  , i = 0
146
- for (; touch = touches[i++]; ) {
148
+ for (; (touch = touches[i++]); ) {
147
149
  touch.pointerId = touch.identifier + 2
148
150
  touch.pointerType = "touch"
149
151
  touch.width = 2 * (touch.radiusX || touch.webkitRadiusX || 0)
@@ -200,7 +202,7 @@
200
202
  /**/
201
203
  var data = {
202
204
  setItem: function(id, val) {
203
- return data[id] = "" + val
205
+ return (data[id] = "" + val)
204
206
  },
205
207
  getItem: function(id) {
206
208
  return data[id]
@@ -240,7 +242,7 @@
240
242
  stringify: function stringify(o) {
241
243
  // IE 8 serializes `undefined` as `"undefined"`
242
244
  return (
243
- isStr(o) ? '"' + o.replace(jsonRe, jsonFn) + '"' :
245
+ isStr(o) ? "\"" + o.replace(jsonRe, jsonFn) + "\"" :
244
246
  o && typeof o == "object" ? (
245
247
  isFn(o.toJSON) ? stringify(o.toJSON()) :
246
248
  isArr(o) ? "[" + o.map(stringify) + "]" :
@@ -253,7 +255,7 @@
253
255
  })
254
256
 
255
257
  /*** ie9 ***/
256
- patch("matchMedia", "b=a||'all';return{media:b,matches:X?X.matchMedium(b):!1,addEventListener:Y}", 0, window.styleMedia || window.media, nop)
258
+ patch("matchMedia", "b=a||'all';return{media:b,matches:X?X.matchMedium(b):!1,addListener:Y}", 0, window.styleMedia || window.media, nop)
257
259
  /**/
258
260
 
259
261
  O = patch("performance")
@@ -278,12 +280,13 @@
278
280
  // Chrome7, FF4, IE9, Opera 11.60, Safari 5.1.4
279
281
  patch("bind", "b=S.call(A,1);c=function(){return t.apply(this instanceof c?this:a,b.concat(S.call(arguments)))};if(t[P])c[P]=t[P];return c")
280
282
 
281
-
282
283
  O = Object
283
- patch("assign", "var k,i=1,l=A.length;for(;i<l;)if(t=A[i++])for(k in t)if(o.call(t,k))a[k]=t[k];return a")
284
+ patch("assign", "for(var k,i=1,l=A.length;i<l;)if(t=A[i++])for(k in t)if(o.call(t,k))a[k]=t[k];return a")
284
285
  patch("create", "X[P]=a||Y;return new X", 0, nop, {
285
286
  // oKeys is undefined at this point
286
- constructor: oKeys, hasOwnProperty: oKeys, isPrototypeOf: oKeys, propertyIsEnumerable: oKeys,
287
+ constructor: oKeys,
288
+ hasOwnProperty: oKeys, // jshint ignore:line
289
+ isPrototypeOf: oKeys, propertyIsEnumerable: oKeys,
287
290
  toLocaleString: oKeys, toString: oKeys, valueOf: oKeys
288
291
  })
289
292
  a = "c=[];for(b in a)o.call(a,b)&&c.push("
@@ -319,6 +322,13 @@
319
322
  patch("reduce", b + "[++i];while(++i<l)" + c)
320
323
  patch("reduceRight", b + "[--l];i=l;while(i--)" + c)
321
324
 
325
+ // Safari12 bug, any modification to the original array before calling `reverse` makes bug disappear
326
+ // Fixed in Safari 12.0.1 and iOS 12.1 on October 30, 2018
327
+ // patch("reverse", "if(X(t))t.length=t.length;return O.call(t)", "2,1" != [1, 2].reverse(), isArr)
328
+
329
+ // In ES3 standard the second deleteCount argument is required, IE<=8 requires deleteCount
330
+ patch("splice", "if(b===Y)A[1]=t.length-a;return O.apply(t,A)", "1,2" != [1, 2].splice(0))
331
+
322
332
  b = a + "while(++i<l)if(i in t)"
323
333
  patch("every", b + "if(!a.call(b,t[i],i,t))return!1;return!0")
324
334
  patch("forEach", b + "a.call(b,t[i],i,t)")
@@ -352,20 +362,28 @@
352
362
  // patch("head", document.getElementsByTagName("head")[0])
353
363
  // HTMLElement (IE9) -> Element (IE8)
354
364
  O = document.body
355
- var selectorRe = /([.#:[])([-\w]+)(?:\((.+?)\)|([~^$*|]?)=(("|')(?:\\?.)*?\6|[-\w]+))?]?/g
356
- , selectorLastRe = /([~\s>+]*)(?:("|')(?:\\?.)*?\2|\(.+?\)|[^\s+>])+$/
357
- , selectorSplitRe = /\s*,\s*(?=(?:[^'"()]|"(?:\\?.)*?"|'(?:\\?.)*?'|\(.+?\))+$)/
358
- , selectorCache = {}
365
+ var selectorCache = {}
366
+ , selectorRe = /([.#:[])([-\w]+)(?:\(((?:[^()]|\([^)]+\))+?)\)|([~^$*|]?)=(("|')(?:\\.|[^\\])*?\6|[-\w]+))?]?/g
367
+ , selectorLastRe = /([\s>+~]*)(?:("|')(?:\\.|[^\\])*?\2|\((?:[^()]|\([^()]+\))+?\)|~=|[^'"()\s>+~])+$/
368
+ , selectorSplitRe = /\s*,\s*(?=(?:[^'"()]|"(?:\\.|[^\\"])*?"|'(?:\\.|[^\\'])*?'|\((?:[^()]|\([^()]+\))+?\))+$)/
359
369
  , selectorMap = {
370
+ "empty": "!_.lastChild",
371
+ "enabled": "!m(_,':disabled')",
360
372
  "first-child": "(a=_.parentNode)&&a.firstChild==_",
373
+ "lang": "m(c(_,'[lang]'),'[lang|='+v+']')",
361
374
  "last-child": "(a=_.parentNode)&&a.lastChild==_",
375
+ "link": "m(_,'a[href]')",
376
+ "only-child": "(a=_.parentNode)&&a.firstChild==a.lastChild",
362
377
  ".": "~_.className.split(/\\s+/).indexOf(a)",
363
378
  "#": "_.id==a",
364
379
  "^": "!a.indexOf(v)",
365
380
  "|": "a.split('-')[0]==v",
366
381
  "$": "a.slice(-v.length)==v",
367
382
  "~": "~a.split(/\\s+/).indexOf(v)",
368
- "*": "~a.indexOf(v)"
383
+ "*": "~a.indexOf(v)",
384
+ ">>": "m(_.parentNode,v)",
385
+ "++": "m(_.previousSibling,v)",
386
+ "": "c(_.parentNode,v)"
369
387
  }
370
388
  , matches = patch("matches", "return!!X(a)(t)", 0, selectorFn)
371
389
  , closest = patch("closest", "return X(t,'parentNode',a,1)", 0, walk)
@@ -377,8 +395,8 @@
377
395
  //patch("removeEventListener")
378
396
 
379
397
  function selectorFn(str) {
380
- // jshint evil:true
381
- return selectorCache[str] ||
398
+ if (str != null && typeof str !== "string") throw Error("Invalid selector")
399
+ return selectorCache[str || ""] ||
382
400
  (selectorCache[str] = Function("m,c", "return function(_,v,a,b){return " +
383
401
  str.split(selectorSplitRe).map(function(sel) {
384
402
  var relation, from
@@ -391,12 +409,12 @@
391
409
  , tag = sel.slice(from).replace(selectorRe, function(_, op, key, subSel, fn, val, quotation) {
392
410
  rules.push(
393
411
  "((v='" +
394
- (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/'/g, "\\'") +
412
+ (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/[\\']/g, "\\$&") +
395
413
  "'),(a='" + key + "'),1)"
396
414
  ,
397
415
  selectorMap[op == ":" ? key : op] ||
398
416
  "(a=_.getAttribute(a))" +
399
- (fn ? "&&" + selectorMap[fn] : val ? "==v" : "")
417
+ (fn ? "&&" + selectorMap[fn] : val ? "==v" : "!==null")
400
418
  )
401
419
  return ""
402
420
  })
@@ -451,7 +469,8 @@
451
469
  src || {}
452
470
  ))
453
471
  }
454
- }(this, Function)
472
+ }(this, Function) // jshint ignore:line
473
+ /* c8 ignore stop */
455
474
 
456
475
 
457
476
 
@@ -43,7 +43,7 @@
43
43
  if (!done) {
44
44
  promise._s = state || false
45
45
  promise._v = val
46
- for (done = 0; val = promise._d[done++]; ) {
46
+ for (done = 0; (val = promise._d[done++]); ) {
47
47
  handle(promise, val)
48
48
  }
49
49
  }
@@ -53,7 +53,7 @@
53
53
  if (val === promise)
54
54
  end(TypeError("A promise resolved with itself"))
55
55
  if (!done) try {
56
- if (done = getThen(val)) {
56
+ if ((done = getThen(val))) {
57
57
  resolve(promise, done)
58
58
  } else {
59
59
  end(val, state = true)
@@ -100,7 +100,7 @@
100
100
  }
101
101
  function resolveThen(i, then) {
102
102
  try {
103
- if (then = getThen(arr[i]))
103
+ if ((then = getThen(arr[i])))
104
104
  then(function (val) {
105
105
  arr[i] = val
106
106
  resolveThen(i)
@@ -131,11 +131,11 @@
131
131
 
132
132
  Promise.race = function (values) {
133
133
  return new Promise(function (resolve, reject, val, i) {
134
- for (i = 0; val = values[i++]; ) {
134
+ for (i = 0; (val = values[i++]); ) {
135
135
  val.then(resolve, reject)
136
136
  }
137
137
  })
138
138
  }
139
- }(this)
139
+ }(this) /* jshint -W030 */
140
140
 
141
141
 
@@ -94,5 +94,5 @@
94
94
  return decodeURIComponent(escape(fromCharCode.apply(null, arr)))
95
95
  }
96
96
  }
97
- }(this)
97
+ }(this) /* jshint -W030 */
98
98
 
package/polyfill/typed.js CHANGED
@@ -15,7 +15,7 @@
15
15
  , proto = Array.prototype
16
16
 
17
17
  for (; i--; ) {
18
- if (t = exports[typed[i]]) {
18
+ if ((t = exports[typed[i]])) {
19
19
  for (k in Array) if (!t[k]) {
20
20
  t[k] = Array[k]
21
21
  }
@@ -27,5 +27,5 @@
27
27
  exports[typed[i]] = Array
28
28
  }
29
29
  }
30
- }(this, Array)
30
+ }(this, Array) /* jshint -W030 */
31
31
 
package/svg.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /* litejs.com/MIT-LICENSE.txt */
3
3
 
4
4
 
5
-
5
+ /* global El */
6
6
  !function(SVGElement, document, bindings) {
7
7
  var ns = "http://www.w3.org/2000/svg"
8
8
  , xlinkNs = "http://www.w3.org/1999/xlink"
@@ -115,5 +115,5 @@
115
115
  function populateSvgElements(name) {
116
116
  El.cache[name] = document.createElementNS(ns, name)
117
117
  }
118
- }(this.SVGElement, document, El.bindings)
118
+ }(this.SVGElement, document, El.bindings) // jshint ignore:line
119
119
 
package/hello.js DELETED
@@ -1,136 +0,0 @@
1
-
2
- !function(window, document, xhr) {
3
- var auth, hash, poll
4
- , events = []
5
-
6
- // JSON.parse and sessionStorage IE8
7
-
8
- Object.each({ DELETE: "del", GET: 0, PATCH: 0, POST: 0, PUT:0 }, addMethod)
9
-
10
- xhr.addMethod = addMethod
11
- xhr.hello = hello
12
-
13
- function hello(data, next) {
14
- var put = {
15
- a: nameStorage(window).a
16
- }
17
- if (!put.a) {
18
- put.b = nameStorage(window.opener).a || sessionStorage.getItem("act")
19
- put.c = document.referrer
20
- }
21
-
22
- xhr.put("/hello", function(err, json) {
23
- auth = json && json.authorization
24
- poll = json && json.user
25
- if (json && json.a) {
26
- nameStorage(window, {a: json.a})
27
- hash = json.a
28
- }
29
- if (next) {
30
- next.call(this, err, json)
31
- }
32
- setTimeout(xhrPoll, 1500)
33
- onFocus()
34
- }, Object.assign(put, data))
35
- }
36
-
37
- xhr.logout = function() {
38
- xhr.del("/hello", function(err, json) {
39
- authorization = null
40
- location.reload()
41
- })
42
- }
43
- /*, ws
44
- try {
45
- new WebSocket("ws" + location.protocol.slice(4) + "//" + location.host + "/events")
46
- .addEventListener("open", function(ev) {
47
- ws = this
48
- ws.send(put)
49
- })
50
- } catch(e) {}
51
- function wsReq(method, url, next, data) {
52
- // Prior to version 11, Firefox only supported sending data as a string.
53
- ws.send(JSON.stringify({method:method,url:url,data:data}))
54
- }
55
- */
56
-
57
- El.on(window, "focus", onFocus)
58
- El.on(window, "unload", function() {
59
- xhr.unload = true
60
- if (events.length) navigator.sendBeacon("/events", JSON.stringify(events))
61
- })
62
-
63
- function addMethod(name, method) {
64
- xhr[name || method.toLowerCase()] = xhr[method] = xhrReq.bind(null, method)
65
- }
66
-
67
- function xhrReq(method, url, next, data) {
68
- var req = xhr(method, url, function onResponse(err, txt) {
69
- var body = (
70
- req.getResponseHeader("Content-Type") == "application/json" ?
71
- JSON.parse(txt) :
72
- { message: txt, code: err }
73
- )
74
- if (next && next.call(this, err, body, req) === true) return
75
- if (err) {
76
- View.emit(
77
- View._e["xhr:" + err] ? "xhr:" + err : "xhr:err",
78
- body, method, url, data, onResponse, xhrSend
79
- )
80
- }
81
- })
82
- xhrSend(req, data)
83
- return req
84
- }
85
-
86
- function xhrSend(req, data) {
87
- if (auth) {
88
- req.setRequestHeader("Authorization", auth)
89
- }
90
- if (data) {
91
- req.setRequestHeader("Content-Type", "application/json")
92
- }
93
- req.send(data ? JSON.stringify(data) : null)
94
- }
95
-
96
- function xhrPoll() {
97
- if (poll) {
98
- xhr.post("/events", pollHandler, events.length > 0 ? events.splice(0) : null)
99
- }
100
- }
101
-
102
- function pollHandler(err, res) {
103
- var i = 0
104
- , events = !err && (Array.isArray(res) ? res : res.events)
105
- , len = events && events.length || 0
106
-
107
- if (len) for (; i < len; ) {
108
- try {
109
- View.emit("event", events[i++])
110
- } catch(e) {
111
- console.error(e)
112
- }
113
- }
114
-
115
- setTimeout(xhrPoll, err ? 6000 : 600)
116
- }
117
-
118
- function nameStorage(win, append) {
119
- var data = {}
120
- try {
121
- // RE against XSS
122
- data = JSON.parse(win.name.match(/^{[\w:"]*}$/)[0])
123
- } catch(e) {}
124
- if (append) {
125
- win.name = JSON.stringify(Object.assign(data, append))
126
- }
127
- return data
128
- }
129
-
130
- function onFocus() {
131
- if (hash && document.hasFocus()) {
132
- sessionStorage.setItem("act", hash)
133
- }
134
- }
135
- }(this, document, xhr)
136
-