runtimepy 5.13.0__py3-none-any.whl → 5.13.2__py3-none-any.whl

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.
runtimepy/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
4
- # hash=35e5555173fdfd064e5047172de9b6a4
3
+ # version=3.2.3
4
+ # hash=6693eae62108cbcdfbccdb9de6b57fa8
5
5
  # =====================================
6
6
 
7
7
  """
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
10
10
 
11
11
  DESCRIPTION = "A framework for implementing Python services."
12
12
  PKG_NAME = "runtimepy"
13
- VERSION = "5.13.0"
13
+ VERSION = "5.13.2"
14
14
 
15
15
  # runtimepy-specific content.
16
16
  METRICS_NAME = "metrics"
runtimepy/__main__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=b28a8111bcc727e854c1f6474a3c4232
5
5
  # =====================================
6
6
  """
runtimepy/app.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=a4deafb4ebcc179d8d85f9376d22dc92
5
5
  # =====================================
6
6
 
runtimepy/commands/all.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=1814b7f7fae3556a0dbeec37141e4182
5
5
  # =====================================
6
6
 
@@ -0,0 +1,19 @@
1
+ ---
2
+ includes:
3
+ - package://runtimepy/factories.yaml
4
+
5
+ init:
6
+ - runtimepy.net.arbiter.housekeeping.init
7
+
8
+ config:
9
+ # Default redirects.
10
+ http_redirects:
11
+ "/": "/index.html"
12
+ "/index.html": "/app.html"
13
+
14
+ # Serve these applications by default at these paths.
15
+ http_app_paths: ["/app.html"]
16
+
17
+ # Handles config["http_app_prefixes"].
18
+ config_builders:
19
+ - runtimepy.net.html.arbiter.web_app_paths
@@ -52,6 +52,6 @@ body > :first-child {
52
52
  border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-link-hover-color) !important;
53
53
  }
54
54
 
55
- canvas:focus {
55
+ :focus {
56
56
  outline: none;
57
57
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  includes:
3
- - package://runtimepy/factories.yaml
3
+ - package://runtimepy/base.yaml
4
4
 
5
5
  ports:
6
6
  - {name: runtimepy_http_server, type: tcp}
@@ -10,22 +10,6 @@ ports:
10
10
  structs:
11
11
  - {name: ui, factory: ui_state}
12
12
 
13
- init:
14
- - runtimepy.net.arbiter.housekeeping.init
15
-
16
- config:
17
- # Default redirects.
18
- http_redirects:
19
- "/": "/index.html"
20
- "/index.html": "/app.html"
21
-
22
- # Serve these applications by default at these paths.
23
- http_app_paths: ["/app.html"]
24
-
25
- # Handles config["http_app_prefixes"].
26
- config_builders:
27
- - runtimepy.net.html.arbiter.web_app_paths
28
-
29
13
  servers:
30
14
  - factory: runtimepy_http
31
15
  kwargs: {port: "$runtimepy_http_server"}
runtimepy/entry.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # =====================================
2
2
  # generator=datazen
3
- # version=3.2.1
3
+ # version=3.2.3
4
4
  # hash=79c31d1280a6e97b5d326aecb758c597
5
5
  # =====================================
6
6
 
@@ -51,9 +51,10 @@ def create_app_shell(
51
51
  # Dark/light theme switch button.
52
52
  bootstrap_button(
53
53
  icon_str("lightbulb"),
54
- tooltip=" Toggle light/dark.",
54
+ tooltip="Toggle light/dark.",
55
55
  id="theme-button",
56
56
  parent=button_column,
57
+ title="change theme button",
57
58
  )
58
59
 
59
60
  return container, button_column
@@ -112,6 +113,7 @@ def full_markdown_page(
112
113
  icon_str("printer"),
113
114
  tooltip="Printer-friendly view.",
114
115
  id="print-button",
116
+ title="print-view button",
115
117
  parent=div(tag="a", href="?print=true", parent=button_column),
116
118
  )
117
119
 
@@ -55,6 +55,12 @@ class RuntimepyServerConnection(HttpConnection):
55
55
  class_paths: list[Pathlike] = [Path(), package_data_dir()]
56
56
  class_redirect_paths: dict[Path, Union[str, Path]] = {}
57
57
 
58
+ # Set these to control meta attributes.
59
+ metadata: dict[str, Optional[str]] = {
60
+ "title": HttpConnection.identity,
61
+ "description": None,
62
+ }
63
+
58
64
  def add_path(self, path: Pathlike, front: bool = False) -> None:
59
65
  """Add a path."""
60
66
 
@@ -145,7 +151,16 @@ class RuntimepyServerConnection(HttpConnection):
145
151
  ) -> bytes:
146
152
  """Return rendered markdown content."""
147
153
 
148
- document = get_html()
154
+ meta: dict[str, str] = type(self).metadata.copy() # type: ignore
155
+
156
+ meta.setdefault("description", "")
157
+ meta["description"] += (
158
+ " This page was rendered from "
159
+ f"Markdown by {HttpConnection.identity}."
160
+ )
161
+
162
+ document = get_html(**meta)
163
+
149
164
  with IndentedFileWriter.string() as writer:
150
165
  writer.write_markdown(content, **kwargs)
151
166
  full_markdown_page(
@@ -156,7 +171,9 @@ class RuntimepyServerConnection(HttpConnection):
156
171
 
157
172
  response["Content-Type"] = f"text/html; charset={DEFAULT_ENCODING}"
158
173
 
159
- return document.encode_str().encode()
174
+ with StringIO() as stream:
175
+ document.render(stream)
176
+ return stream.getvalue().encode()
160
177
 
161
178
  async def render_markdown_file(
162
179
  self,
@@ -179,14 +196,14 @@ class RuntimepyServerConnection(HttpConnection):
179
196
  result: HttpResult = None
180
197
 
181
198
  # Keep track of directories encountered.
182
- directories: list[Path] = []
199
+ directories: list[tuple[Path, Path]] = []
183
200
 
184
201
  # Build a list of all candidate files to check.
185
202
  candidates: list[Path] = []
186
203
  for search in self.paths:
187
204
  candidate = search.joinpath(path[0][1:])
188
205
  if candidate.is_dir():
189
- directories.append(candidate)
206
+ directories.append((candidate, search))
190
207
  candidates.append(candidate.joinpath("index.html"))
191
208
  else:
192
209
  candidates.append(candidate)
@@ -206,6 +223,13 @@ class RuntimepyServerConnection(HttpConnection):
206
223
 
207
224
  # Set MIME type if it can be determined.
208
225
  if mime:
226
+ # webhint suggestion
227
+ if (
228
+ mime.startswith("text")
229
+ and DEFAULT_ENCODING not in mime
230
+ ):
231
+ mime += f"; charset={DEFAULT_ENCODING}"
232
+
209
233
  response["Content-Type"] = mime
210
234
 
211
235
  # We don't handle this yet.
@@ -219,9 +243,10 @@ class RuntimepyServerConnection(HttpConnection):
219
243
 
220
244
  # Handle a directory as a last resort.
221
245
  if not result and directories:
246
+ candidate, search = directories[0]
222
247
  result = self.render_markdown(
223
248
  markdown_for_dir(
224
- directories[0], {"applications": self.apps.keys()}
249
+ candidate, search, {"applications": self.apps.keys()}
225
250
  ),
226
251
  response,
227
252
  path[1],
@@ -326,6 +351,7 @@ class RuntimepyServerConnection(HttpConnection):
326
351
  response,
327
352
  request_data,
328
353
  default_app=type(self).default_app,
354
+ **type(self).metadata,
329
355
  )
330
356
 
331
357
  if populated:
@@ -68,6 +68,8 @@ async def setup(app: AppInfo) -> int:
68
68
  )
69
69
  )
70
70
 
71
+ RuntimepyServerConnection.metadata.update(app.config_param("html", {}))
72
+
71
73
  # Default application (environment tabs).
72
74
  html_app = create_app(app, getattr(_import_module(module), method))
73
75
  target: str
@@ -226,6 +226,7 @@ class ChannelEnvironmentTabHtml(ChannelEnvironmentTabControls):
226
226
  vert_container = flex(
227
227
  parent=container,
228
228
  kind="column",
229
+ tag="form",
229
230
  )
230
231
  vert_container.add_class("channel-column", "collapse", "show")
231
232
 
@@ -110,6 +110,7 @@ def channel_table_header(
110
110
  tooltip="Clear plotted channels.",
111
111
  icon="x-lg",
112
112
  id="clear-plotted-channels",
113
+ title="button for clearing plotted channels",
113
114
  ).add_class("pb-2")
114
115
 
115
116
  input_box(
@@ -124,6 +125,7 @@ def channel_table_header(
124
125
  icon="trash",
125
126
  tooltip="Clear all plot points.",
126
127
  id="clear-plotted-points",
128
+ title="button for clearing plot point data",
127
129
  ).add_class("pb-2")
128
130
 
129
131
  cell = flex(tag="th", parent=ctl_row)
@@ -6,6 +6,7 @@ A module implementing HTML interfaces for web applications.
6
6
  from typing import Awaitable, Callable, Optional, TextIO
7
7
 
8
8
  # third-party
9
+ from svgen.element import Element
9
10
  from svgen.element.html import Html
10
11
  from vcorelib import DEFAULT_ENCODING
11
12
 
@@ -20,10 +21,36 @@ HtmlApp = Callable[
20
21
  HtmlApps = dict[str, HtmlApp]
21
22
 
22
23
 
23
- def get_html() -> Html:
24
+ def get_html(
25
+ title: str = HttpConnection.identity,
26
+ cache_control: str = "public",
27
+ description: str = None,
28
+ **kwargs,
29
+ ) -> Html:
24
30
  """Get a default HTML document."""
25
31
 
26
- return Html(HttpConnection.identity)
32
+ elem = Html(title, **kwargs)
33
+
34
+ elem.head.children.append(
35
+ Element(
36
+ tag="meta",
37
+ attrib={"http-equiv": "Cache-Control", "content": cache_control},
38
+ )
39
+ )
40
+
41
+ elem.head.children.append(
42
+ Element(tag="link", rel="icon", href="/favicon.ico")
43
+ )
44
+
45
+ if description:
46
+ elem.head.children.append(
47
+ Element(
48
+ tag="meta",
49
+ attrib={"name": "description", "content": description},
50
+ )
51
+ )
52
+
53
+ return elem
27
54
 
28
55
 
29
56
  async def html_handler(
@@ -33,6 +60,7 @@ async def html_handler(
33
60
  response: ResponseHeader,
34
61
  request_data: Optional[bytes],
35
62
  default_app: HtmlApp = None,
63
+ **kwargs,
36
64
  ) -> bool:
37
65
  """Render an HTML document in response to an HTTP request."""
38
66
 
@@ -42,6 +70,8 @@ async def html_handler(
42
70
  # Create the application.
43
71
  app = apps.get(request.target.path, default_app)
44
72
  if app is not None:
45
- (await app(get_html(), request, response, request_data)).render(stream)
73
+ (
74
+ await app(get_html(**kwargs), request, response, request_data)
75
+ ).render(stream)
46
76
 
47
77
  return app is not None
@@ -11,14 +11,11 @@ from typing import Iterable, cast
11
11
  from vcorelib.io.file_writer import IndentedFileWriter
12
12
  from vcorelib.paths import rel
13
13
 
14
- LOGO_MARKDOWN = (
15
- "[![logo](https://libre-embedded.com/static/"
16
- "png/chip-circle-bootstrap/128x128.png)](https://libre-embedded.com)"
17
- )
14
+ LOGO_MARKDOWN = "[![logo](/static/png/chip-circle-bootstrap/128x128.png)](/)"
18
15
 
19
16
 
20
17
  def markdown_for_dir(
21
- path: Path, extra_links: dict[str, Iterable[str]] = None
18
+ path: Path, base: Path, extra_links: dict[str, Iterable[str]] = None
22
19
  ) -> str:
23
20
  """Get markdown data for a directory."""
24
21
 
@@ -29,24 +26,28 @@ def markdown_for_dir(
29
26
 
30
27
  if extra_links:
31
28
  for category, apps in extra_links.items():
32
- writer.write(f"## {category}")
33
- with writer.padding():
34
- for app in apps:
35
- writer.write(f"* [{app}]({app})")
36
-
37
- writer.write(f"## `{path}`")
29
+ if apps:
30
+ writer.write(f"## {category}")
31
+ with writer.padding():
32
+ for app in apps:
33
+ writer.write(f"* [{app}]({app})")
34
+
35
+ curr_dir = rel(path, base=base)
36
+ writer.write(f"## `{curr_dir}`")
38
37
  writer.empty()
39
38
 
40
- writer.write("* [..](..)")
39
+ # Link to go up a directory.
40
+ if curr_dir != Path():
41
+ writer.write(f"* [..](/{curr_dir.parent})")
41
42
 
42
43
  for item in path.iterdir():
43
- curr = rel(item, base=path)
44
+ curr = rel(item, base=base)
44
45
 
45
- name = f"`{curr}`"
46
+ name = f"`{curr.name}`"
46
47
  if item.is_dir():
47
48
  name = f"**{name}**"
48
49
 
49
- writer.write(f"* [{name}]({curr})")
50
+ writer.write(f"* [{name}](/{curr})")
50
51
 
51
52
  result: str = cast(StringIO, writer.stream).getvalue()
52
53
 
@@ -52,10 +52,13 @@ def to_json(response: HttpResponse) -> Any:
52
52
  )
53
53
 
54
54
 
55
+ IDENTITY = f"{PKG_NAME}/{VERSION}"
56
+
57
+
55
58
  class HttpConnection(_TcpConnection):
56
59
  """A class implementing a basic HTTP interface."""
57
60
 
58
- identity = f"{PKG_NAME}/{VERSION}"
61
+ identity = IDENTITY
59
62
 
60
63
  expecting_response: bool
61
64
 
@@ -126,7 +129,11 @@ class HttpConnection(_TcpConnection):
126
129
  )
127
130
 
128
131
  # Set boilerplate header data.
129
- response["server"] = self.identity
132
+
133
+ # webhint suggestions
134
+ # response["server"] = self.identity
135
+ response["server"] = PKG_NAME
136
+ response["X-Content-Type-Options"] = "nosniff"
130
137
 
131
138
  return result
132
139
 
@@ -1,6 +1,6 @@
1
1
  aiofiles
2
- vcorelib>=3.5.1
3
- svgen>=0.7.4
2
+ vcorelib>=3.5.8
3
+ svgen>=0.7.12
4
4
  websockets
5
5
  psutil
6
6
  windows-curses; sys_platform == 'win32' and python_version < '3.12'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runtimepy
3
- Version: 5.13.0
3
+ Version: 5.13.2
4
4
  Summary: A framework for implementing Python services.
5
5
  Home-page: https://github.com/libre-embedded/runtimepy
6
6
  Author: Libre Embedded
@@ -17,11 +17,11 @@ Classifier: Development Status :: 5 - Production/Stable
17
17
  Requires-Python: >=3.12
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
- Requires-Dist: svgen>=0.7.4
21
20
  Requires-Dist: aiofiles
21
+ Requires-Dist: vcorelib>=3.5.8
22
22
  Requires-Dist: psutil
23
+ Requires-Dist: svgen>=0.7.12
23
24
  Requires-Dist: websockets
24
- Requires-Dist: vcorelib>=3.5.1
25
25
  Provides-Extra: test
26
26
  Requires-Dist: pylint; extra == "test"
27
27
  Requires-Dist: flake8; extra == "test"
@@ -50,12 +50,12 @@ Dynamic: requires-python
50
50
  <!--
51
51
  =====================================
52
52
  generator=datazen
53
- version=3.2.1
54
- hash=4f0e82dc45d3ea9c4ccf5b262413c206
53
+ version=3.2.3
54
+ hash=f3bcab8765e649f1b80ad504e5debde9
55
55
  =====================================
56
56
  -->
57
57
 
58
- # runtimepy ([5.13.0](https://pypi.org/project/runtimepy/))
58
+ # runtimepy ([5.13.2](https://pypi.org/project/runtimepy/))
59
59
 
60
60
  [![python](https://img.shields.io/pypi/pyversions/runtimepy.svg)](https://pypi.org/project/runtimepy/)
61
61
  ![Build Status](https://github.com/libre-embedded/runtimepy/workflows/Python%20Package/badge.svg)
@@ -1,11 +1,11 @@
1
- runtimepy/__init__.py,sha256=HxjInsMBuhZ8HVgWbkL2C4cBfavqCLORI0hiaUc4Lq0,391
2
- runtimepy/__main__.py,sha256=3IFTvHw-vqPIFy6ZZjzl00oDwFLzcDmV5WHo3ohPKbc,332
3
- runtimepy/app.py,sha256=xhqZOvBcBCawUR2Qd5oyvrmNdOJhdChgddb0GiJOnPc,970
1
+ runtimepy/__init__.py,sha256=SS-yzin_UgsO_Yr3uFKIDgmWSOp6OCzrOj3rb2DZ0Qo,391
2
+ runtimepy/__main__.py,sha256=IKioH2xOtsXwrwb9zABDQEJvuAX--Lnh84TeSz0XSs0,332
3
+ runtimepy/app.py,sha256=Er1ZKKrG9U0FV0gQg_GYF9xDb89HgYnVzS5SjxGa2Tg,970
4
4
  runtimepy/dev_requirements.txt,sha256=VZhW6bJ5YbwaoN4d_XxZFuN5BbDLaG7ngKrGnugVPRw,245
5
- runtimepy/entry.py,sha256=MPY0AfqBzJBUp5d3i64zxjiE3eoRk_zAOZMLieK7wYE,1954
5
+ runtimepy/entry.py,sha256=DGHLv_SmTMImRcWjbVa2dKiWkhvAbxZwuvtvWLbx5U4,1954
6
6
  runtimepy/mapping.py,sha256=VQK1vzmQVvYYKI85_II37-hIEbvgL3PzNy-WI6TTo80,5091
7
7
  runtimepy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- runtimepy/requirements.txt,sha256=PdID4t7w3qsEoNwrMR-SJoH5OQ9oIUcpesKJC4AiU64,124
8
+ runtimepy/requirements.txt,sha256=uc8eW9HzoBsDmspEvyDKIs-xGrWs_UUltwAQCk072PU,125
9
9
  runtimepy/schemas.py,sha256=zTgxPm9DHZ0R_bmmOjNQMTXdtM_Hb1bE-Fog40jDCgg,839
10
10
  runtimepy/util.py,sha256=ZHSucNi-gbrcajoCv2dNjQs48dJPC3mTM_wZHx7AW1U,1719
11
11
  runtimepy/channel/__init__.py,sha256=pf0RJ5g37_FVV8xoUNgzFGuIfbZEYSBA_cQlJSDTPDo,4774
@@ -29,7 +29,7 @@ runtimepy/codec/protocol/base.py,sha256=ezNX-93NBChNpMszkkcx-0X_YzdU2oOFdqAMfKaE
29
29
  runtimepy/codec/protocol/json.py,sha256=qmcoCcTRS-HgVYLPBsCAPhekAgZmHX9JBfGivLl3b0Y,4349
30
30
  runtimepy/codec/system/__init__.py,sha256=fIOUo7QhwI81YAIz9myeSo1oo94De41sK5HKJ-sAdfY,7959
31
31
  runtimepy/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- runtimepy/commands/all.py,sha256=nANQ5v5PlIhY8TZejcckGoZmqjOr7tYA7LstordQUDk,1619
32
+ runtimepy/commands/all.py,sha256=WfKC5W8a5RzgE24QucynDvsOEcWO1e0Akm2etx90uFQ,1619
33
33
  runtimepy/commands/arbiter.py,sha256=CtTMRYpqCAN3vWHkkr9jqWpoF7JGNXafKIBFmkarAfc,1567
34
34
  runtimepy/commands/common.py,sha256=NvZdeIFBHAF52c1n7vqD59DW6ywc-rG5iC5MpuhGf-c,2449
35
35
  runtimepy/commands/mtu.py,sha256=LFFjTU4SsuV3j7Mhx_WuKa5lfdfMm70zJvDWToVrP7E,1357
@@ -42,18 +42,19 @@ runtimepy/control/source.py,sha256=nW3Q2D-LcekII7K5XKbxXCcR-9jYQyvv0UypeNy1Dnw,1
42
42
  runtimepy/control/step.py,sha256=2LdZTpMHLwHLdpPVinpC2qByTs5I5LTDt-xONn_6Fc8,5491
43
43
  runtimepy/control/env/__init__.py,sha256=RHJqysY7Pv4VDs2SGk0X-qc5xp_SrQ_oxb5Deug8HEM,1339
44
44
  runtimepy/data/404.html,sha256=D_nhuj1AfO5EaIVsajknfaeZ5cVDKCNRPtUY4MHg1Xc,5326
45
+ runtimepy/data/base.yaml,sha256=WGy2nPiRZk5_wBU7BlWaFfCnzRprJBp-m8onOPUoLAo,399
45
46
  runtimepy/data/browser.yaml,sha256=oc5KEV1C1uAJ4MkhNo4hyVVfJtZvHelRNqzNvD313Ow,79
46
47
  runtimepy/data/dummy_load.yaml,sha256=PfKRXXgZnENRMSd68eznSMTV8xanVH5JY4FmoZRPFGY,1985
47
48
  runtimepy/data/factories.yaml,sha256=esuoouMre8w7siZfBoZKqC-5myghJ_WwOOCDIq135zg,1899
48
49
  runtimepy/data/favicon.ico,sha256=boxAGaHbUjMFrOO2TZpsO0nIRC-LUgwHVQYOiG1YQnM,362870
49
50
  runtimepy/data/sample_telemetry.yaml,sha256=OpdFurkvtWJGaNl9LMlU2rKo15AaVVr-U_hoZfsbp-Y,695
50
51
  runtimepy/data/server.yaml,sha256=wS_Ceiu2TpkfPurpqoYoPlgzc9DAWtUd24MW7t-S5rU,97
51
- runtimepy/data/server_base.yaml,sha256=R_varVgGPGV4nxWYYwKUnHC9ufINi4V92YVhxCCC5wg,875
52
+ runtimepy/data/server_base.yaml,sha256=Fiqz9C_ikxtYYFO8q17XzgaY5b3H9RuyqJr-QoTk-qg,524
52
53
  runtimepy/data/server_dev.yaml,sha256=nQsPh7LuQig3pzHfdg_aD3yOUiCj1sKKfI-WwW3hXmQ,523
53
54
  runtimepy/data/tftp_server.yaml,sha256=-bFOWJSagI-fEQQcT8k7eDMJVfSPm2XAxLVG3dqUTa4,204
54
55
  runtimepy/data/css/bootstrap_extra.css,sha256=kJLOp8j-vRxnWzQOf_eOz4kL8Mbrwxuwk3YNh90HgWM,1907
55
56
  runtimepy/data/css/font.css,sha256=Pe82E66rNi-cwlQ-_1GHAuhPGu5L4x5KqgV0dbDe51w,977
56
- runtimepy/data/css/main.css,sha256=kdqSsltzP78dgbiAQCTtsvK9p3kpbtQ809PD5tK9LVE,714
57
+ runtimepy/data/css/main.css,sha256=6xYQRA6QLDC8-k_-AUT1mA9bVHGidttfmMbgwg5ck3g,708
57
58
  runtimepy/data/js/DataConnection.js,sha256=DnX8FMehjJXqmI62UMYXSvl_XdfQMzq3XUDFbLu2GgI,98
58
59
  runtimepy/data/js/JsonConnection.js,sha256=rclZrbmWc_zSs6I_JhOgxnVPFIyPMo5WdjAe8alyZ3o,2729
59
60
  runtimepy/data/js/audio.js,sha256=bLkBqbeHMiGGidfL3iXjmVoF9seK-ZeZ3kwgOrcpgk4,1092
@@ -181,7 +182,7 @@ runtimepy/net/arbiter/struct/__init__.py,sha256=Vr38dp2X0PZOrAbjKsZ9xZdQ1j3z92s4
181
182
  runtimepy/net/arbiter/tcp/__init__.py,sha256=djNm8il_9aLNpGsYResJlFmyIqx9XNLqVay-mYnn8vc,1530
182
183
  runtimepy/net/arbiter/tcp/json.py,sha256=W9a_OwBPmIoB2XZf4iuAIWQhMg2qA9xejBhGBdNCPnI,742
183
184
  runtimepy/net/factories/__init__.py,sha256=rPdBVpgzzQYF61w6efQrEre71yMPHd6kanBpMdOX-3c,4672
184
- runtimepy/net/html/__init__.py,sha256=7WkBpwqN5NOHAtw05Rkt9C-mldmeTIdzqIDhJ3_w87U,5037
185
+ runtimepy/net/html/__init__.py,sha256=mlr7J7gBr9EwwKq4iMbq3QYKxie16AQDKa92_sUB2xM,5108
185
186
  runtimepy/net/html/arbiter.py,sha256=SkZZm-CmyCxbAcWZbvCLH-RwFUJPvrvR5yWysVVuvCM,951
186
187
  runtimepy/net/html/bootstrap/__init__.py,sha256=F_gp2_YMTi4tKEwRIPQGwoarKWCwltd9HnvqAqCH2Hc,2429
187
188
  runtimepy/net/html/bootstrap/elements.py,sha256=NBdjg0_1LTxoyJrNQNw-2v8AWaiW2S1poJcDo4P6GWE,5355
@@ -193,11 +194,11 @@ runtimepy/net/http/request_target.py,sha256=EE1aI5VSARw1h93jyZvP56ir5O5fjd6orYK-
193
194
  runtimepy/net/http/response.py,sha256=y33KLUJNE7zx6biUMwTkUfQ1bXiKV6pjrcxuh8U3WCE,3216
194
195
  runtimepy/net/http/state.py,sha256=qCMN8aWfCRfU9XP-cIhSOo2RqfljTjbQRCflfcy2bfY,1626
195
196
  runtimepy/net/http/version.py,sha256=mp6rgIM7-VUVKLCA0Uw96CmBkL0ET860lDVVEewpZ7w,1098
196
- runtimepy/net/server/__init__.py,sha256=R6xV5wUqrCwB0pa0FMjcZ-txkT87H_B9AgWq0RrJQsU,10458
197
- runtimepy/net/server/html.py,sha256=ufg0PQF_iUE7PT0n3Pn3jTcun7mspZUI6_ooblcNnvI,1217
197
+ runtimepy/net/server/__init__.py,sha256=LqN4NSkk_B0sv-i1PMv98kzkMGCCVbAPTxst1Xgjq6Y,11340
198
+ runtimepy/net/server/html.py,sha256=TZ2ZSPTxgA6KAKS26tNrSUpxFUrdk92K5zP2ybcSYqs,1892
198
199
  runtimepy/net/server/json.py,sha256=a7vM5yfq2er4DexzFqEMnxoMGDeuywKkVH4-uNJBAik,2522
199
- runtimepy/net/server/markdown.py,sha256=DFjGbvIST4HXRhtTTvXVQ9ZAwrIfVzPlcU1dW8JYya8,1381
200
- runtimepy/net/server/app/__init__.py,sha256=beU67t7zoKGlO7aldjQMUwYLm9mSlc78eMQazri-otw,3012
200
+ runtimepy/net/server/markdown.py,sha256=3kLQR3fsGFU8dUiDuMbUiLv7XKx9s4zXy9SZsJDDc9Y,1507
201
+ runtimepy/net/server/app/__init__.py,sha256=_Hmbhu2TvO1aUrxfExbOi5qW9LNVTti8-ndwLpYrhjA,3089
201
202
  runtimepy/net/server/app/base.py,sha256=46aOqZwRss_nh_WfEH1cMJ9GUVoLJjERd7cTRFu6mXE,1878
202
203
  runtimepy/net/server/app/create.py,sha256=eRT8qxubht5A7149Xol3Z8rkdYd_pjNLqrlyMnXk-Zg,2660
203
204
  runtimepy/net/server/app/elements.py,sha256=KJt9vWqkfvniJMiLOJN467JjPPrEqJYZXmDuY1JoY1g,455
@@ -210,11 +211,11 @@ runtimepy/net/server/app/tab.py,sha256=gRiaUJdB3V9hIKI5MksW7spNChfMtEMDFWCTP1ERr
210
211
  runtimepy/net/server/app/env/__init__.py,sha256=_FcgefASOwifwT0m5opg8jQbpZAVoedhNxWw0v1VB1k,4147
211
212
  runtimepy/net/server/app/env/modal.py,sha256=HTipCYgQaAUtsmlBjXKfhAM5JyhLqoIIwEwsPnKhrG8,1740
212
213
  runtimepy/net/server/app/env/settings.py,sha256=DboR8vXrdGeB_ehP9USvnyUtzgo4JR5CyYV9AGLYHGI,1720
213
- runtimepy/net/server/app/env/widgets.py,sha256=ccrkJNikL5VEKDaTMd8FSI9VzjYYHcpuIRdDjvpQtug,5306
214
+ runtimepy/net/server/app/env/widgets.py,sha256=XT39-9zJ-5-XhY-PWHmWAU4JMqY8I4syk1fYUYv2OzM,5413
214
215
  runtimepy/net/server/app/env/tab/__init__.py,sha256=stTVKyHljLQWnnhxkWPwa7bLdZtjhiMFbiVFgbiYaFI,647
215
216
  runtimepy/net/server/app/env/tab/base.py,sha256=QBTBBvsdihbzK5MqrJBf6K5N61b3i8Ms0P6Xq_h1mbs,1171
216
217
  runtimepy/net/server/app/env/tab/controls.py,sha256=bifFMvshDNsar3UiqeXOCYi71JGFRlMnyixKXrdLAEI,4728
217
- runtimepy/net/server/app/env/tab/html.py,sha256=IfKCQ_2qupIRtWIuodIBM8XAal1esSXovht1SeGyvb4,7173
218
+ runtimepy/net/server/app/env/tab/html.py,sha256=2Vgd50FubFlm24G5mECFrTi0YWYz3KIpcEq9mKtI5dk,7197
218
219
  runtimepy/net/server/app/env/tab/message.py,sha256=-J8wBo1KH0XoBi9VcUvl9LXZCaoFAmvFyMf_YFJVF6Q,3945
219
220
  runtimepy/net/server/struct/__init__.py,sha256=Zy37r6RLFu-XFr9vsanSq80BJdS6Dxr7zmPzQbb7xdw,1799
220
221
  runtimepy/net/server/websocket/__init__.py,sha256=KISuFUUQwNn6BXo8BOMuMOXyoVqE7Jw94ZQiSCQuRQE,5279
@@ -227,7 +228,7 @@ runtimepy/net/tcp/__init__.py,sha256=OOWohegpoioSTf8M7uDf-4EV1IDungz7-U19L_2yW4I
227
228
  runtimepy/net/tcp/connection.py,sha256=sYWj2aDiAHQf70zfRJM24cHraFd_TuzTD4fRWeSQZXE,8811
228
229
  runtimepy/net/tcp/create.py,sha256=zZsRs5KYpO3bNGh-DwEOEzjUDE4ixj-UBHYgZ0GvC7c,2013
229
230
  runtimepy/net/tcp/protocol.py,sha256=vEnIX3gUX2nrw9ofT_e4KYU4VY2k4WP0WuOi4eE_OOQ,1444
230
- runtimepy/net/tcp/http/__init__.py,sha256=SPvrZvIM1poE_jgCNY6gjgV2bXfMmPH_0zdx8x4JSVI,6080
231
+ runtimepy/net/tcp/http/__init__.py,sha256=nXgUoC7jKlR7Ay7cTkomU2u_TcTsoO38uastZSBGa9k,6228
231
232
  runtimepy/net/tcp/scpi/__init__.py,sha256=aWCWQfdeyfoU9bpOnOtyIQbT1swl4ergXLFn5kXAH28,2105
232
233
  runtimepy/net/tcp/telnet/__init__.py,sha256=96eJFb301I3H2ivDtGMQtDDw09Xm5NRvM9VEC-wjt8c,4768
233
234
  runtimepy/net/tcp/telnet/codes.py,sha256=1-yyRe-Kz_W7d6B0P3iT1AaSNR3_Twmn-MUjKCJJknY,3518
@@ -300,9 +301,9 @@ runtimepy/tui/task.py,sha256=nUZo9fuOC-k1Wpqdzkv9v1tQirCI28fZVgcC13Ijvus,1093
300
301
  runtimepy/tui/channels/__init__.py,sha256=evDaiIn-YS9uGhdo8ZGtP9VK1ek6sr_P1nJ9JuSET0o,4536
301
302
  runtimepy/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
302
303
  runtimepy/ui/controls.py,sha256=yvT7h3thbYaitsakcIAJ90EwKzJ4b-jnc6p3UuVf_XE,1241
303
- runtimepy-5.13.0.dist-info/licenses/LICENSE,sha256=yKBRwbO-cOPBrlpsZmJkkSa33DfY31aE8t7lZ0DwlUo,1071
304
- runtimepy-5.13.0.dist-info/METADATA,sha256=TEucfXpt7dgg0L_P1F-WItb0l7MJuXLyuejhWBc1Uv0,9268
305
- runtimepy-5.13.0.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
306
- runtimepy-5.13.0.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
307
- runtimepy-5.13.0.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
308
- runtimepy-5.13.0.dist-info/RECORD,,
304
+ runtimepy-5.13.2.dist-info/licenses/LICENSE,sha256=yKBRwbO-cOPBrlpsZmJkkSa33DfY31aE8t7lZ0DwlUo,1071
305
+ runtimepy-5.13.2.dist-info/METADATA,sha256=_GkgF9xsxR9UGBpUSeJ0of9xjc783dgtAMH8GltwoRs,9269
306
+ runtimepy-5.13.2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
307
+ runtimepy-5.13.2.dist-info/entry_points.txt,sha256=-btVBkYv7ybcopqZ_pRky-bEzu3vhbaG3W3Z7ERBiFE,51
308
+ runtimepy-5.13.2.dist-info/top_level.txt,sha256=0jPmh6yqHyyJJDwEID-LpQly-9kQ3WRMjH7Lix8peLg,10
309
+ runtimepy-5.13.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5