rapydscript-ns 0.8.2 → 0.8.4

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 (141) hide show
  1. package/.agignore +1 -1
  2. package/.github/workflows/ci.yml +38 -38
  3. package/=template.pyj +5 -5
  4. package/CHANGELOG.md +39 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_DIFFERENCES_REPORT.md +291 -0
  8. package/PYTHON_FEATURE_COVERAGE.md +106 -15
  9. package/README.md +831 -52
  10. package/TODO.md +4 -286
  11. package/add-toc-to-readme +2 -2
  12. package/bin/export +75 -75
  13. package/bin/rapydscript +70 -70
  14. package/bin/web-repl-export +102 -102
  15. package/build +2 -2
  16. package/language-service/index.js +4623 -0
  17. package/language-service/language-service.d.ts +40 -0
  18. package/package.json +9 -7
  19. package/publish.py +37 -37
  20. package/release/baselib-plain-pretty.js +2006 -229
  21. package/release/baselib-plain-ugly.js +70 -3
  22. package/release/compiler.js +11554 -3870
  23. package/release/signatures.json +31 -29
  24. package/session.vim +4 -4
  25. package/setup.cfg +2 -2
  26. package/src/ast.pyj +93 -1
  27. package/src/baselib-builtins.pyj +99 -2
  28. package/src/baselib-containers.pyj +107 -4
  29. package/src/baselib-errors.pyj +44 -0
  30. package/src/baselib-internal.pyj +124 -5
  31. package/src/baselib-itertools.pyj +97 -97
  32. package/src/baselib-str.pyj +32 -1
  33. package/src/compiler.pyj +36 -36
  34. package/src/errors.pyj +30 -30
  35. package/src/lib/aes.pyj +646 -646
  36. package/src/lib/collections.pyj +1 -1
  37. package/src/lib/copy.pyj +120 -0
  38. package/src/lib/elementmaker.pyj +83 -83
  39. package/src/lib/encodings.pyj +126 -126
  40. package/src/lib/gettext.pyj +569 -569
  41. package/src/lib/itertools.pyj +580 -580
  42. package/src/lib/math.pyj +193 -193
  43. package/src/lib/numpy.pyj +10 -10
  44. package/src/lib/operator.pyj +11 -11
  45. package/src/lib/pythonize.pyj +20 -20
  46. package/src/lib/random.pyj +118 -118
  47. package/src/lib/re.pyj +470 -470
  48. package/src/lib/react.pyj +74 -0
  49. package/src/lib/traceback.pyj +63 -63
  50. package/src/lib/uuid.pyj +77 -77
  51. package/src/monaco-language-service/analyzer.js +131 -9
  52. package/src/monaco-language-service/builtins.js +17 -2
  53. package/src/monaco-language-service/completions.js +170 -1
  54. package/src/monaco-language-service/diagnostics.js +25 -3
  55. package/src/monaco-language-service/dts.js +550 -550
  56. package/src/monaco-language-service/index.js +17 -0
  57. package/src/monaco-language-service/scope.js +3 -0
  58. package/src/output/classes.pyj +128 -11
  59. package/src/output/codegen.pyj +17 -3
  60. package/src/output/comments.pyj +45 -45
  61. package/src/output/exceptions.pyj +201 -105
  62. package/src/output/functions.pyj +13 -16
  63. package/src/output/jsx.pyj +164 -0
  64. package/src/output/literals.pyj +28 -2
  65. package/src/output/loops.pyj +0 -9
  66. package/src/output/modules.pyj +2 -5
  67. package/src/output/operators.pyj +22 -2
  68. package/src/output/statements.pyj +2 -2
  69. package/src/output/stream.pyj +1 -13
  70. package/src/output/treeshake.pyj +182 -182
  71. package/src/output/utils.pyj +72 -72
  72. package/src/parse.pyj +434 -114
  73. package/src/string_interpolation.pyj +72 -72
  74. package/src/tokenizer.pyj +29 -0
  75. package/src/unicode_aliases.pyj +576 -576
  76. package/src/utils.pyj +192 -192
  77. package/test/_import_one.pyj +37 -37
  78. package/test/_import_two/__init__.pyj +11 -11
  79. package/test/_import_two/level2/deep.pyj +4 -4
  80. package/test/_import_two/other.pyj +6 -6
  81. package/test/_import_two/sub.pyj +13 -13
  82. package/test/aes_vectors.pyj +421 -421
  83. package/test/annotations.pyj +80 -80
  84. package/test/baselib.pyj +4 -4
  85. package/test/classes.pyj +56 -17
  86. package/test/collections.pyj +5 -5
  87. package/test/decorators.pyj +77 -77
  88. package/test/docstrings.pyj +39 -39
  89. package/test/elementmaker_test.pyj +45 -45
  90. package/test/functions.pyj +151 -151
  91. package/test/generators.pyj +41 -41
  92. package/test/generic.pyj +370 -370
  93. package/test/imports.pyj +72 -72
  94. package/test/internationalization.pyj +73 -73
  95. package/test/lint.pyj +164 -164
  96. package/test/loops.pyj +85 -85
  97. package/test/numpy.pyj +734 -734
  98. package/test/omit_function_metadata.pyj +20 -20
  99. package/test/python_compat.pyj +326 -0
  100. package/test/python_features.pyj +129 -29
  101. package/test/regexp.pyj +55 -55
  102. package/test/repl.pyj +121 -121
  103. package/test/scoped_flags.pyj +76 -76
  104. package/test/slice.pyj +105 -0
  105. package/test/str.pyj +25 -0
  106. package/test/unit/fixtures/fibonacci_expected.js +1 -1
  107. package/test/unit/index.js +2296 -71
  108. package/test/unit/language-service-builtins.js +70 -0
  109. package/test/unit/language-service-bundle.js +5 -5
  110. package/test/unit/language-service-completions.js +180 -0
  111. package/test/unit/language-service-dts.js +543 -543
  112. package/test/unit/language-service-hover.js +455 -455
  113. package/test/unit/language-service-index.js +350 -0
  114. package/test/unit/language-service-scope.js +255 -0
  115. package/test/unit/language-service.js +625 -4
  116. package/test/unit/run-language-service.js +1 -0
  117. package/test/unit/web-repl.js +437 -0
  118. package/tools/build-language-service.js +2 -2
  119. package/tools/cli.js +547 -547
  120. package/tools/compile.js +219 -219
  121. package/tools/compiler.js +0 -24
  122. package/tools/completer.js +131 -131
  123. package/tools/embedded_compiler.js +251 -251
  124. package/tools/export.js +3 -37
  125. package/tools/gettext.js +185 -185
  126. package/tools/ini.js +65 -65
  127. package/tools/msgfmt.js +187 -187
  128. package/tools/repl.js +223 -223
  129. package/tools/test.js +118 -118
  130. package/tools/utils.js +128 -128
  131. package/tools/web_repl.js +95 -95
  132. package/try +41 -41
  133. package/web-repl/env.js +196 -74
  134. package/web-repl/index.html +163 -163
  135. package/web-repl/main.js +252 -254
  136. package/web-repl/prism.css +139 -139
  137. package/web-repl/prism.js +113 -113
  138. package/web-repl/rapydscript.js +227 -139
  139. package/web-repl/sha1.js +25 -25
  140. package/hack_demo.pyj +0 -112
  141. package/web-repl/language-service.js +0 -4187
@@ -353,7 +353,7 @@ class Counter:
353
353
 
354
354
  def most_common(self, n=None):
355
355
  items = [[k, self._data[k]] for k in self._data]
356
- items.pysort(key=def(pair): return -pair[1];)
356
+ items.sort(key=def(pair): return -pair[1];)
357
357
  if n is not None:
358
358
  return items[:n]
359
359
  return items
@@ -0,0 +1,120 @@
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD
3
+ # RapydScript implementation of Python's copy standard library.
4
+ #
5
+ # Supported: copy, deepcopy
6
+ # Classes may define __copy__() and __deepcopy__(memo) for custom behaviour.
7
+
8
+
9
+ def _is_primitive(x):
10
+ t = jstype(x)
11
+ return x is None or t is 'number' or t is 'boolean' or t is 'string' or t is 'undefined'
12
+
13
+
14
+ def copy(x):
15
+ """Return a shallow copy of x.
16
+
17
+ For immutable primitives (numbers, strings, booleans, None) the object
18
+ itself is returned unchanged. For containers a new container of the same
19
+ type is created whose top-level items are the same objects as in the
20
+ original.
21
+
22
+ Dispatch order:
23
+ 1. Primitive → return as-is.
24
+ 2. ``__copy__`` method → call and return.
25
+ 3. list → ``list(x)`` (slice).
26
+ 4. set → ``set(x)``.
27
+ 5. frozenset → ``frozenset(x)``.
28
+ 6. dict (ρσ_dict) → ``x.copy()``.
29
+ 7. Plain JS object (constructor is Object or null-proto) → Object.assign.
30
+ 8. Other object (class instance) → Object.create + Object.assign.
31
+ """
32
+ if _is_primitive(x):
33
+ return x
34
+ if jstype(x.__copy__) is 'function':
35
+ return x.__copy__()
36
+ if Array.isArray(x):
37
+ return list(x)
38
+ if isinstance(x, set):
39
+ return set(x)
40
+ if isinstance(x, frozenset):
41
+ return frozenset(x)
42
+ if isinstance(x, dict):
43
+ return x.copy()
44
+ proto = Object.getPrototypeOf(x)
45
+ if x.constructor is Object or proto is None:
46
+ return Object.assign({}, x)
47
+ # Class instance: create a same-prototype object and copy own properties.
48
+ result = Object.create(proto)
49
+ Object.assign(result, x)
50
+ return result
51
+
52
+
53
+ def deepcopy(x, memo=None):
54
+ """Return a deep (recursive) copy of x.
55
+
56
+ Circular references are handled via the *memo* mapping (a JS Map), which
57
+ stores already-copied objects so that they are only copied once.
58
+
59
+ Dispatch order (same structure as ``copy`` but recursive):
60
+ 1. Primitive → return as-is.
61
+ 2. Memo hit → return the previously copied object.
62
+ 3. ``__deepcopy__(memo)`` method → call and return.
63
+ 4. list → recurse into elements.
64
+ 5. set → recurse into elements, build new set.
65
+ 6. frozenset → recurse into elements, build new frozenset.
66
+ 7. dict → recurse into keys and values.
67
+ 8. Plain JS object → recurse into own-enumerable properties.
68
+ 9. Class instance → recurse into own-enumerable properties.
69
+ """
70
+ if memo is None:
71
+ memo = v'new Map()'
72
+ if _is_primitive(x):
73
+ return x
74
+ if memo.has(x):
75
+ return memo.get(x)
76
+ if jstype(x.__deepcopy__) is 'function':
77
+ result = x.__deepcopy__(memo)
78
+ memo.set(x, result)
79
+ return result
80
+ if Array.isArray(x):
81
+ result = []
82
+ memo.set(x, result)
83
+ for i in range(x.length):
84
+ result.push(deepcopy(x[i], memo))
85
+ return result
86
+ if isinstance(x, set):
87
+ result = set()
88
+ memo.set(x, result)
89
+ iterator = x[ρσ_iterator_symbol]()
90
+ r = iterator.next()
91
+ while not r.done:
92
+ result.add(deepcopy(r.value, memo))
93
+ r = iterator.next()
94
+ return result
95
+ if isinstance(x, frozenset):
96
+ items = []
97
+ iterator = x[ρσ_iterator_symbol]()
98
+ r = iterator.next()
99
+ while not r.done:
100
+ items.push(deepcopy(r.value, memo))
101
+ r = iterator.next()
102
+ result = frozenset(items)
103
+ memo.set(x, result)
104
+ return result
105
+ if isinstance(x, dict):
106
+ result = dict()
107
+ memo.set(x, result)
108
+ iterator = x.items()
109
+ r = iterator.next()
110
+ while not r.done:
111
+ result.set(deepcopy(r.value[0], memo), deepcopy(r.value[1], memo))
112
+ r = iterator.next()
113
+ return result
114
+ proto = Object.getPrototypeOf(x)
115
+ result = Object.create(proto)
116
+ memo.set(x, result)
117
+ keys = Object.keys(x)
118
+ for i in range(keys.length):
119
+ result[keys[i]] = deepcopy(x[keys[i]], memo)
120
+ return result
@@ -1,83 +1,83 @@
1
- # vim:fileencoding=utf-8
2
- # License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
3
-
4
- html_elements = {
5
- 'a', 'abbr', 'acronym', 'address', 'area',
6
- 'article', 'aside', 'audio', 'b', 'base', 'big', 'body', 'blockquote', 'br', 'button',
7
- 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
8
- 'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn',
9
- 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset',
10
- 'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1',
11
- 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'head', 'i', 'iframe', 'img', 'input', 'ins',
12
- 'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter',
13
- 'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option',
14
- 'p', 'pre', 'progress', 'q', 's', 'samp', 'script', 'section', 'select',
15
- 'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', 'style',
16
- 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot',
17
- 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video'
18
- }
19
-
20
- mathml_elements = {
21
- 'maction', 'math', 'merror', 'mfrac', 'mi',
22
- 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom',
23
- 'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub',
24
- 'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
25
- 'munderover', 'none'
26
- }
27
-
28
- svg_elements = {
29
- 'a', 'animate', 'animateColor', 'animateMotion',
30
- 'animateTransform', 'clipPath', 'circle', 'defs', 'desc', 'ellipse',
31
- 'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
32
- 'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph',
33
- 'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect',
34
- 'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use'
35
- }
36
-
37
- html5_tags = html_elements.union(mathml_elements).union(svg_elements)
38
-
39
- def _makeelement(tag, *args, **kwargs):
40
- ans = this.createElement(tag)
41
-
42
- for attr in kwargs:
43
- vattr = str.replace(str.rstrip(attr, '_'), '_', '-')
44
- val = kwargs[attr]
45
- if callable(val):
46
- if str.startswith(attr, 'on'):
47
- attr = attr[2:]
48
- ans.addEventListener(attr, val)
49
- elif val is True:
50
- ans.setAttribute(vattr, vattr)
51
- elif jstype(val) is 'string':
52
- ans.setAttribute(vattr, val)
53
-
54
- for arg in args:
55
- if jstype(arg) is 'string':
56
- arg = this.createTextNode(arg)
57
- ans.appendChild(arg)
58
- return ans
59
-
60
- def maker_for_document(document):
61
- # Create an elementmaker to be used with the specified document
62
- E = _makeelement.bind(document)
63
- Object.defineProperties(E, {
64
- tag: {
65
- 'value':_makeelement.bind(document, tag)
66
- } for tag in html5_tags
67
- })
68
- return E
69
-
70
- if jstype(document) is 'undefined':
71
- E = maker_for_document({
72
- 'createTextNode': def(value): return value;,
73
- 'createElement': def(name):
74
- return {
75
- 'name':name,
76
- 'children':[],
77
- 'attributes':{},
78
- 'setAttribute': def(name, val): this.attributes[name] = val;,
79
- 'appendChild': def(child): this.children.push(child);,
80
- }
81
- })
82
- else:
83
- E = maker_for_document(document)
1
+ # vim:fileencoding=utf-8
2
+ # License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
3
+
4
+ html_elements = {
5
+ 'a', 'abbr', 'acronym', 'address', 'area',
6
+ 'article', 'aside', 'audio', 'b', 'base', 'big', 'body', 'blockquote', 'br', 'button',
7
+ 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup',
8
+ 'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn',
9
+ 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset',
10
+ 'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1',
11
+ 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'head', 'i', 'iframe', 'img', 'input', 'ins',
12
+ 'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter',
13
+ 'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option',
14
+ 'p', 'pre', 'progress', 'q', 's', 'samp', 'script', 'section', 'select',
15
+ 'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', 'style',
16
+ 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot',
17
+ 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video'
18
+ }
19
+
20
+ mathml_elements = {
21
+ 'maction', 'math', 'merror', 'mfrac', 'mi',
22
+ 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom',
23
+ 'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub',
24
+ 'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
25
+ 'munderover', 'none'
26
+ }
27
+
28
+ svg_elements = {
29
+ 'a', 'animate', 'animateColor', 'animateMotion',
30
+ 'animateTransform', 'clipPath', 'circle', 'defs', 'desc', 'ellipse',
31
+ 'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
32
+ 'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph',
33
+ 'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect',
34
+ 'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use'
35
+ }
36
+
37
+ html5_tags = html_elements.union(mathml_elements).union(svg_elements)
38
+
39
+ def _makeelement(tag, *args, **kwargs):
40
+ ans = this.createElement(tag)
41
+
42
+ for attr in kwargs:
43
+ vattr = str.replace(str.rstrip(attr, '_'), '_', '-')
44
+ val = kwargs[attr]
45
+ if callable(val):
46
+ if str.startswith(attr, 'on'):
47
+ attr = attr[2:]
48
+ ans.addEventListener(attr, val)
49
+ elif val is True:
50
+ ans.setAttribute(vattr, vattr)
51
+ elif jstype(val) is 'string':
52
+ ans.setAttribute(vattr, val)
53
+
54
+ for arg in args:
55
+ if jstype(arg) is 'string':
56
+ arg = this.createTextNode(arg)
57
+ ans.appendChild(arg)
58
+ return ans
59
+
60
+ def maker_for_document(document):
61
+ # Create an elementmaker to be used with the specified document
62
+ E = _makeelement.bind(document)
63
+ Object.defineProperties(E, {
64
+ tag: {
65
+ 'value':_makeelement.bind(document, tag)
66
+ } for tag in html5_tags
67
+ })
68
+ return E
69
+
70
+ if jstype(document) is 'undefined':
71
+ E = maker_for_document({
72
+ 'createTextNode': def(value): return value;,
73
+ 'createElement': def(name):
74
+ return {
75
+ 'name':name,
76
+ 'children':[],
77
+ 'attributes':{},
78
+ 'setAttribute': def(name, val): this.attributes[name] = val;,
79
+ 'appendChild': def(child): this.children.push(child);,
80
+ }
81
+ })
82
+ else:
83
+ E = maker_for_document(document)
@@ -1,126 +1,126 @@
1
- # vim:fileencoding=utf-8
2
- # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
-
4
- def base64encode(bytes, altchars, pad_char):
5
- # Convert an array of bytes into a base-64 encoded string
6
- l = bytes.length
7
- remainder = l % 3
8
- main_length = l - remainder
9
- encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + (altchars or '+/')
10
- pad_char = '=' if pad_char is undefined else pad_char
11
- ans = v'[]'
12
- for v'var i = 0; i < main_length; i += 3':
13
- chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
14
- ans.push(encodings[(chunk & 16515072) >> 18], encodings[(chunk & 258048) >> 12], encodings[(chunk & 4032) >> 6], encodings[chunk & 63])
15
- if remainder is 1:
16
- chunk = bytes[main_length]
17
- ans.push(encodings[(chunk & 252) >> 2], encodings[(chunk & 3) << 4], pad_char, pad_char)
18
- elif remainder is 2:
19
- chunk = (bytes[main_length] << 8) | bytes[main_length + 1]
20
- ans.push(encodings[(chunk & 64512) >> 10], encodings[(chunk & 1008) >> 4], encodings[(chunk & 15) << 2], pad_char)
21
- return ans.join('')
22
-
23
- def base64decode(string):
24
- # convert the output of base64encode back into an array of bytes
25
- # (Uint8Array) only works with the standard altchars and pad_char
26
- if jstype(window) is not 'undefined':
27
- chars = window.atob(string)
28
- else:
29
- chars = new Buffer(string, 'base64').toString('binary') # noqa: undef
30
- ans = Uint8Array(chars.length)
31
- for i in range(ans.length):
32
- ans[i] = chars.charCodeAt(i)
33
- return ans
34
-
35
- def urlsafe_b64encode(bytes, pad_char):
36
- return base64encode(bytes, '-_', pad_char)
37
-
38
- def urlsafe_b64decode(string):
39
- string = String.prototype.replace.call(string, /[_-]/g, def(m): return '+' if m is '-' else '/';)
40
- return base64decode(string)
41
-
42
- def hexlify(bytes):
43
- ans = v'[]'
44
- for v'var i = 0; i < bytes.length; i++':
45
- x = bytes[i].toString(16)
46
- if x.length is 1:
47
- x = '0' + x
48
- ans.push(x)
49
- return ans.join('')
50
-
51
- def unhexlify(string):
52
- num = string.length // 2
53
- if num * 2 is not string.length:
54
- raise ValueError('string length is not a multiple of two')
55
- ans = Uint8Array(num)
56
- for v'var i = 0; i < num; i++':
57
- x = parseInt(string[i*2:i*2+2], 16)
58
- if isNaN(x):
59
- raise ValueError('string is not hex-encoded')
60
- ans[i] = x
61
- return ans
62
-
63
- utf8_decoder_table = v'''[
64
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
65
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
66
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
67
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
68
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
69
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
70
- 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
71
- 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
72
- 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
73
- 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
74
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
75
- 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
76
- 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
77
- 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
78
- ]'''
79
-
80
- def _from_code_point(x):
81
- if x <= 0xFFFF:
82
- return String.fromCharCode(x)
83
- x -= 0x10000
84
- return String.fromCharCode((x >> 10) + 0xD800, (x % 0x400) + 0xDC00)
85
-
86
- def utf8_decode(bytes, errors, replacement):
87
- # Convert an array of UTF-8 encoded bytes into a string
88
- state = 0
89
- ans = v'[]'
90
-
91
- for v'var i = 0, l = bytes.length; i < l; i++': # noqa
92
- byte = bytes[i]
93
- typ = utf8_decoder_table[byte]
94
- codep = (byte & 0x3f) | (codep << 6) if state is not 0 else (0xff >> typ) & (byte)
95
- state = utf8_decoder_table[256 + state*16 + typ]
96
- if state is 0:
97
- ans.push(_from_code_point(codep))
98
- elif state is 1:
99
- if not errors or errors is 'strict':
100
- raise UnicodeDecodeError(str.format('The byte 0x{:02x} at position {} is not valid UTF-8', byte, i))
101
- elif errors is 'replace':
102
- ans.push(replacement or '?')
103
- return ans.join('')
104
-
105
- def utf8_encode_js(string):
106
- # Encode a string as an array of UTF-8 bytes
107
- escstr = encodeURIComponent(string)
108
- ans = v'[]'
109
- for v'var i = 0; i < escstr.length; i++':
110
- ch = escstr[i]
111
- if ch is '%':
112
- ans.push(parseInt(escstr[i+1:i+3], 16))
113
- i += 2
114
- else:
115
- ans.push(ch.charCodeAt(0))
116
- return Uint8Array(ans)
117
-
118
- if jstype(TextEncoder) is 'function':
119
- _u8enc = TextEncoder('utf-8')
120
- utf8_encode = _u8enc.encode.bind(_u8enc)
121
- _u8enc = undefined
122
- else:
123
- utf8_encode = utf8_encode_js
124
-
125
- def utf8_encode_native(string):
126
- return _u8enc.encode(string)
1
+ # vim:fileencoding=utf-8
2
+ # License: BSD Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3
+
4
+ def base64encode(bytes, altchars, pad_char):
5
+ # Convert an array of bytes into a base-64 encoded string
6
+ l = bytes.length
7
+ remainder = l % 3
8
+ main_length = l - remainder
9
+ encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + (altchars or '+/')
10
+ pad_char = '=' if pad_char is undefined else pad_char
11
+ ans = v'[]'
12
+ for v'var i = 0; i < main_length; i += 3':
13
+ chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
14
+ ans.push(encodings[(chunk & 16515072) >> 18], encodings[(chunk & 258048) >> 12], encodings[(chunk & 4032) >> 6], encodings[chunk & 63])
15
+ if remainder is 1:
16
+ chunk = bytes[main_length]
17
+ ans.push(encodings[(chunk & 252) >> 2], encodings[(chunk & 3) << 4], pad_char, pad_char)
18
+ elif remainder is 2:
19
+ chunk = (bytes[main_length] << 8) | bytes[main_length + 1]
20
+ ans.push(encodings[(chunk & 64512) >> 10], encodings[(chunk & 1008) >> 4], encodings[(chunk & 15) << 2], pad_char)
21
+ return ans.join('')
22
+
23
+ def base64decode(string):
24
+ # convert the output of base64encode back into an array of bytes
25
+ # (Uint8Array) only works with the standard altchars and pad_char
26
+ if jstype(window) is not 'undefined':
27
+ chars = window.atob(string)
28
+ else:
29
+ chars = new Buffer(string, 'base64').toString('binary') # noqa: undef
30
+ ans = Uint8Array(chars.length)
31
+ for i in range(ans.length):
32
+ ans[i] = chars.charCodeAt(i)
33
+ return ans
34
+
35
+ def urlsafe_b64encode(bytes, pad_char):
36
+ return base64encode(bytes, '-_', pad_char)
37
+
38
+ def urlsafe_b64decode(string):
39
+ string = String.prototype.replace.call(string, /[_-]/g, def(m): return '+' if m is '-' else '/';)
40
+ return base64decode(string)
41
+
42
+ def hexlify(bytes):
43
+ ans = v'[]'
44
+ for v'var i = 0; i < bytes.length; i++':
45
+ x = bytes[i].toString(16)
46
+ if x.length is 1:
47
+ x = '0' + x
48
+ ans.push(x)
49
+ return ans.join('')
50
+
51
+ def unhexlify(string):
52
+ num = string.length // 2
53
+ if num * 2 is not string.length:
54
+ raise ValueError('string length is not a multiple of two')
55
+ ans = Uint8Array(num)
56
+ for v'var i = 0; i < num; i++':
57
+ x = parseInt(string[i*2:i*2+2], 16)
58
+ if isNaN(x):
59
+ raise ValueError('string is not hex-encoded')
60
+ ans[i] = x
61
+ return ans
62
+
63
+ utf8_decoder_table = v'''[
64
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
65
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
66
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
67
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
68
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
69
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
70
+ 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
71
+ 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
72
+ 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
73
+ 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
74
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
75
+ 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
76
+ 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
77
+ 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
78
+ ]'''
79
+
80
+ def _from_code_point(x):
81
+ if x <= 0xFFFF:
82
+ return String.fromCharCode(x)
83
+ x -= 0x10000
84
+ return String.fromCharCode((x >> 10) + 0xD800, (x % 0x400) + 0xDC00)
85
+
86
+ def utf8_decode(bytes, errors, replacement):
87
+ # Convert an array of UTF-8 encoded bytes into a string
88
+ state = 0
89
+ ans = v'[]'
90
+
91
+ for v'var i = 0, l = bytes.length; i < l; i++': # noqa
92
+ byte = bytes[i]
93
+ typ = utf8_decoder_table[byte]
94
+ codep = (byte & 0x3f) | (codep << 6) if state is not 0 else (0xff >> typ) & (byte)
95
+ state = utf8_decoder_table[256 + state*16 + typ]
96
+ if state is 0:
97
+ ans.push(_from_code_point(codep))
98
+ elif state is 1:
99
+ if not errors or errors is 'strict':
100
+ raise UnicodeDecodeError(str.format('The byte 0x{:02x} at position {} is not valid UTF-8', byte, i))
101
+ elif errors is 'replace':
102
+ ans.push(replacement or '?')
103
+ return ans.join('')
104
+
105
+ def utf8_encode_js(string):
106
+ # Encode a string as an array of UTF-8 bytes
107
+ escstr = encodeURIComponent(string)
108
+ ans = v'[]'
109
+ for v'var i = 0; i < escstr.length; i++':
110
+ ch = escstr[i]
111
+ if ch is '%':
112
+ ans.push(parseInt(escstr[i+1:i+3], 16))
113
+ i += 2
114
+ else:
115
+ ans.push(ch.charCodeAt(0))
116
+ return Uint8Array(ans)
117
+
118
+ if jstype(TextEncoder) is 'function':
119
+ _u8enc = TextEncoder('utf-8')
120
+ utf8_encode = _u8enc.encode.bind(_u8enc)
121
+ _u8enc = undefined
122
+ else:
123
+ utf8_encode = utf8_encode_js
124
+
125
+ def utf8_encode_native(string):
126
+ return _u8enc.encode(string)