rapydscript-ns 0.8.3 → 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 (116) 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 +8 -0
  5. package/HACKING.md +103 -103
  6. package/LICENSE +24 -24
  7. package/PYTHON_DIFFERENCES_REPORT.md +2 -2
  8. package/PYTHON_FEATURE_COVERAGE.md +13 -13
  9. package/README.md +670 -6
  10. package/TODO.md +5 -6
  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 +155 -6
  17. package/package.json +1 -1
  18. package/publish.py +37 -37
  19. package/release/baselib-plain-pretty.js +2006 -229
  20. package/release/baselib-plain-ugly.js +70 -3
  21. package/release/compiler.js +11554 -3870
  22. package/release/signatures.json +31 -29
  23. package/session.vim +4 -4
  24. package/setup.cfg +2 -2
  25. package/src/ast.pyj +93 -1
  26. package/src/baselib-builtins.pyj +22 -1
  27. package/src/baselib-containers.pyj +99 -0
  28. package/src/baselib-errors.pyj +44 -0
  29. package/src/baselib-internal.pyj +94 -4
  30. package/src/baselib-itertools.pyj +97 -97
  31. package/src/baselib-str.pyj +24 -0
  32. package/src/compiler.pyj +36 -36
  33. package/src/errors.pyj +30 -30
  34. package/src/lib/aes.pyj +646 -646
  35. package/src/lib/copy.pyj +120 -0
  36. package/src/lib/elementmaker.pyj +83 -83
  37. package/src/lib/encodings.pyj +126 -126
  38. package/src/lib/gettext.pyj +569 -569
  39. package/src/lib/itertools.pyj +580 -580
  40. package/src/lib/math.pyj +193 -193
  41. package/src/lib/operator.pyj +11 -11
  42. package/src/lib/pythonize.pyj +20 -20
  43. package/src/lib/random.pyj +118 -118
  44. package/src/lib/re.pyj +470 -470
  45. package/src/lib/react.pyj +74 -0
  46. package/src/lib/traceback.pyj +63 -63
  47. package/src/lib/uuid.pyj +77 -77
  48. package/src/monaco-language-service/builtins.js +5 -0
  49. package/src/monaco-language-service/diagnostics.js +25 -3
  50. package/src/monaco-language-service/dts.js +550 -550
  51. package/src/output/classes.pyj +108 -8
  52. package/src/output/codegen.pyj +16 -2
  53. package/src/output/comments.pyj +45 -45
  54. package/src/output/exceptions.pyj +201 -105
  55. package/src/output/functions.pyj +9 -0
  56. package/src/output/jsx.pyj +164 -0
  57. package/src/output/literals.pyj +28 -2
  58. package/src/output/modules.pyj +1 -1
  59. package/src/output/operators.pyj +8 -2
  60. package/src/output/statements.pyj +2 -2
  61. package/src/output/stream.pyj +1 -0
  62. package/src/output/treeshake.pyj +182 -182
  63. package/src/output/utils.pyj +72 -72
  64. package/src/parse.pyj +417 -113
  65. package/src/string_interpolation.pyj +72 -72
  66. package/src/tokenizer.pyj +29 -0
  67. package/src/unicode_aliases.pyj +576 -576
  68. package/src/utils.pyj +192 -192
  69. package/test/_import_one.pyj +37 -37
  70. package/test/_import_two/__init__.pyj +11 -11
  71. package/test/_import_two/level2/deep.pyj +4 -4
  72. package/test/_import_two/other.pyj +6 -6
  73. package/test/_import_two/sub.pyj +13 -13
  74. package/test/aes_vectors.pyj +421 -421
  75. package/test/annotations.pyj +80 -80
  76. package/test/decorators.pyj +77 -77
  77. package/test/docstrings.pyj +39 -39
  78. package/test/elementmaker_test.pyj +45 -45
  79. package/test/functions.pyj +151 -151
  80. package/test/generators.pyj +41 -41
  81. package/test/generic.pyj +370 -370
  82. package/test/imports.pyj +72 -72
  83. package/test/internationalization.pyj +73 -73
  84. package/test/lint.pyj +164 -164
  85. package/test/loops.pyj +85 -85
  86. package/test/numpy.pyj +734 -734
  87. package/test/omit_function_metadata.pyj +20 -20
  88. package/test/python_features.pyj +19 -6
  89. package/test/regexp.pyj +55 -55
  90. package/test/repl.pyj +121 -121
  91. package/test/scoped_flags.pyj +76 -76
  92. package/test/unit/index.js +2177 -64
  93. package/test/unit/language-service-dts.js +543 -543
  94. package/test/unit/language-service-hover.js +455 -455
  95. package/test/unit/language-service.js +590 -4
  96. package/test/unit/web-repl.js +303 -0
  97. package/tools/cli.js +547 -547
  98. package/tools/compile.js +219 -219
  99. package/tools/completer.js +131 -131
  100. package/tools/embedded_compiler.js +251 -251
  101. package/tools/gettext.js +185 -185
  102. package/tools/ini.js +65 -65
  103. package/tools/msgfmt.js +187 -187
  104. package/tools/repl.js +223 -223
  105. package/tools/test.js +118 -118
  106. package/tools/utils.js +128 -128
  107. package/tools/web_repl.js +95 -95
  108. package/try +41 -41
  109. package/web-repl/env.js +196 -74
  110. package/web-repl/index.html +163 -163
  111. package/web-repl/main.js +252 -254
  112. package/web-repl/prism.css +139 -139
  113. package/web-repl/prism.js +113 -113
  114. package/web-repl/rapydscript.js +224 -102
  115. package/web-repl/sha1.js +25 -25
  116. package/hack_demo.pyj +0 -112
@@ -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)