MProcs 8.8.2__tar.gz → 8.8.4__tar.gz

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 (47) hide show
  1. {mprocs-8.8.2 → mprocs-8.8.4}/PKG-INFO +1 -1
  2. {mprocs-8.8.2 → mprocs-8.8.4}/pyproject.toml +2 -1
  3. mprocs-8.8.4/src/MProcs/scripts/gwf.py +309 -0
  4. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/tui.py +13 -0
  5. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/version_checker.py +1 -1
  6. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/wrappers.py +10 -0
  7. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs.egg-info/PKG-INFO +1 -1
  8. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs.egg-info/SOURCES.txt +1 -0
  9. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs.egg-info/entry_points.txt +1 -0
  10. {mprocs-8.8.2 → mprocs-8.8.4}/README.md +0 -0
  11. {mprocs-8.8.2 → mprocs-8.8.4}/setup.cfg +0 -0
  12. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/__init__.py +0 -0
  13. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/__init__.py +0 -0
  14. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/ai_image.py +0 -0
  15. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/acadlist.json +0 -0
  16. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/bible1.json +0 -0
  17. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/biology1.json +0 -0
  18. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/chemistry1.json +0 -0
  19. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/chi_chars.json +0 -0
  20. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/degrees1.json +0 -0
  21. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/dhammapada1.json +0 -0
  22. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/diction.json +0 -0
  23. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/fcci.json +0 -0
  24. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/hospitals.json +0 -0
  25. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/jamo.json +0 -0
  26. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/katakana.json +0 -0
  27. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/koran1.json +0 -0
  28. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/legal_terms1.json +0 -0
  29. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/medicals1.json +0 -0
  30. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/mims.json +0 -0
  31. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/proverbs.json +0 -0
  32. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/psychology1.json +0 -0
  33. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/science1.json +0 -0
  34. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/strains.json +0 -0
  35. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/tracks.json +0 -0
  36. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data/verses1.json +0 -0
  37. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/data_loader.py +0 -0
  38. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/deepseek_ai.py +0 -0
  39. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/keys.py +0 -0
  40. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/lpro.py +0 -0
  41. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/lpro_s.py +0 -0
  42. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/main.py +0 -0
  43. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/scmpy.py +0 -0
  44. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs/scripts/session.py +0 -0
  45. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs.egg-info/dependency_links.txt +0 -0
  46. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs.egg-info/requires.txt +0 -0
  47. {mprocs-8.8.2 → mprocs-8.8.4}/src/MProcs.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MProcs
3
- Version: 8.8.2
3
+ Version: 8.8.4
4
4
  Summary: MProcs - derived from NeonBunny
5
5
  Author-email: tderk <usvu.tech@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "MProcs"
7
- version = "8.8.2"
7
+ version = "8.8.4"
8
8
  description = "MProcs - derived from NeonBunny"
9
9
  requires-python = ">=3.8"
10
10
  readme = "README.md"
@@ -18,6 +18,7 @@ MProcs = "MProcs.scripts.main:run"
18
18
  mprocs = "MProcs.scripts.main:run"
19
19
  lpro = "MProcs.scripts.lpro:main"
20
20
  lpro-s = "MProcs.scripts.lpro_s:main"
21
+ gwf = "MProcs.scripts.gwf:run"
21
22
 
22
23
  [tool.setuptools]
23
24
  package-dir = {"" = "src"}
@@ -0,0 +1,309 @@
1
+ import random
2
+ import string
3
+ import sys
4
+ import threading
5
+ import time
6
+
7
+ PACKAGE_NAME = "GWF"
8
+ PACKAGE_VERSION = "6.0.0"
9
+ GWF_TITLE = "Granular WireFrame"
10
+
11
+ _TAG_CHARS = 'ABCDEFGHJKLMNPQRSTUVWXYZ0123456789'
12
+ _MATRIX_CHARS = ('アイウエオカキクケコサシスセソタチツテトナニヌネノ'
13
+ '0123456789ABCDEFabcdef+-*/=<>#$%&@')
14
+
15
+ _GREEN = '\x1b[32m'
16
+ _GREEN_HI = '\x1b[1;32m'
17
+ _GREEN_DIM = '\x1b[2;32m'
18
+ _CYAN = '\x1b[1;36m'
19
+ _YELLOW = '\x1b[1;33m'
20
+ _MAGENTA = '\x1b[1;35m'
21
+ _RED = '\x1b[1;31m'
22
+ _WHITE = '\x1b[1;37m'
23
+ _RESET = '\x1b[0m'
24
+
25
+ _BLIP_COLORS = [_CYAN, _YELLOW, _MAGENTA, _RED, _WHITE]
26
+
27
+
28
+ class Blip:
29
+ def __init__(self, w, h):
30
+ self.x = random.uniform(2, max(5, w - 4))
31
+ self.y = random.uniform(1, max(3, h - 2))
32
+ self.w = w
33
+ self.h = h
34
+ self.tag = ''.join(random.sample(_TAG_CHARS, 2))
35
+ self.value = random.choice([
36
+ str(random.randint(0, 99)),
37
+ '0x%02X' % random.randint(0, 255),
38
+ '%d%%' % random.randint(0, 100),
39
+ '%.1f' % random.uniform(0, 9.9),
40
+ 'sig%02d' % random.randint(0, 99),
41
+ ])
42
+ self.color = random.choice(_BLIP_COLORS)
43
+ self.kind = random.choice(['persistent', 'flicker', 'transient', 'transient'])
44
+ self.vx = random.uniform(-0.5, 0.5)
45
+ self.vy = random.uniform(-0.3, 0.3)
46
+ self.life = random.uniform(1.5, 4.0)
47
+ self.age = 0.0
48
+ self.visible = True
49
+ self.blink = random.uniform(0.2, 0.8)
50
+
51
+ def update(self, dt):
52
+ self.age += dt
53
+ if self.kind == 'persistent':
54
+ self.x += self.vx * dt
55
+ self.y += self.vy * dt
56
+ self.visible = True
57
+ elif self.kind == 'flicker':
58
+ self.x += self.vx * dt
59
+ self.y += self.vy * dt
60
+ if int(self.age / self.blink) % 2 == 0:
61
+ self.visible = not self.visible
62
+ elif self.kind == 'transient':
63
+ self.visible = self.age < self.life
64
+ if self.visible:
65
+ if self.x < 2 or self.x >= self.w - 2:
66
+ self.vx *= -1
67
+ if self.y < 1 or self.y >= self.h - 1:
68
+ self.vy *= -1
69
+
70
+
71
+ class Matrix:
72
+ def __init__(self, w, h):
73
+ self.w = w
74
+ self.h = h
75
+ self.cells = None
76
+ self.blips = []
77
+ self.new_instance()
78
+
79
+ def _make_blip(self):
80
+ b = Blip(self.w, self.h)
81
+ while any(b.tag == o.tag for o in self.blips):
82
+ b.tag = ''.join(random.sample(_TAG_CHARS, 2))
83
+ return b
84
+
85
+ def new_instance(self):
86
+ self.cells = [[(0, ' ') for _ in range(self.w)] for _ in range(self.h)]
87
+ self.blips = []
88
+ for _ in range(random.randint(8, 16)):
89
+ self.blips.append(self._make_blip())
90
+ self.pulse = 0.0
91
+ self._next_blip_change = 0.0
92
+ self._rain_acc = 0.0
93
+
94
+ def update_rain(self, dt):
95
+ self.pulse += dt
96
+ self._rain_acc += dt
97
+ step = 0.016
98
+ while self._rain_acc >= step:
99
+ self._rain_acc -= step
100
+ for c in range(self.w):
101
+ for r in range(self.h):
102
+ if self.cells[r][c][0] > 0:
103
+ self.cells[r][c] = (self.cells[r][c][0] - 1, self.cells[r][c][1])
104
+ if random.random() < 0.55:
105
+ head = 0
106
+ while head < self.h and self.cells[head][c][0] > 0:
107
+ head += 1
108
+ if head < self.h:
109
+ self.cells[head][c] = (5, random.choice(_MATRIX_CHARS))
110
+
111
+ def update_blips(self, dt):
112
+ for b in self.blips:
113
+ b.update(dt)
114
+ for b in self.blips:
115
+ if b.kind == 'transient' and not b.visible and random.random() < 0.3:
116
+ b.x = random.uniform(2, max(5, self.w - 4))
117
+ b.y = random.uniform(1, max(3, self.h - 2))
118
+ b.age = 0.0
119
+ if self.pulse >= self._next_blip_change:
120
+ self._next_blip_change = self.pulse + random.uniform(1.0, 3.0)
121
+ if self.blips and random.random() < 0.4:
122
+ self.blips.pop(random.randrange(len(self.blips)))
123
+ else:
124
+ self.blips.append(self._make_blip())
125
+
126
+ def update(self, dt):
127
+ self.update_rain(dt)
128
+ self.update_blips(dt)
129
+
130
+
131
+ class GWF:
132
+ def __init__(self, tui=None):
133
+ self.tui = tui
134
+ self.running = True
135
+ self._paused = False
136
+ self._green_paused = False
137
+ self._speed = 1.0
138
+ self.matrix = None
139
+ self.new_instance()
140
+
141
+ def _vwidth(self, ch):
142
+ o = ord(ch)
143
+ if o < 0x1100:
144
+ return 1
145
+ if 0x2E80 <= o <= 0xA4CF or 0xAC00 <= o <= 0xD7A3 or \
146
+ 0xF900 <= o <= 0xFAFF or 0xFF00 <= o <= 0xFF60 or \
147
+ 0x3000 <= o <= 0x303F:
148
+ return 2
149
+ return 1
150
+
151
+ def _dims(self):
152
+ if self.tui is not None:
153
+ width = max(20, getattr(self.tui, 'width', 80) - 2)
154
+ height = max(6, getattr(self.tui, 'height', 24))
155
+ else:
156
+ try:
157
+ import shutil
158
+ width, height = shutil.get_terminal_size((80, 24))
159
+ except Exception:
160
+ width, height = 80, 24
161
+ height = max(6, height - 3)
162
+ return width, height
163
+
164
+ def new_instance(self):
165
+ width, height = self._dims()
166
+ self.matrix = Matrix(width, height)
167
+
168
+ def _frame_rows(self, width, height):
169
+ m = self.matrix
170
+ grid = [[None for _ in range(width)] for _ in range(height)]
171
+ for r in range(min(m.h, height)):
172
+ c = 0
173
+ for cc in range(min(m.w, width * 2)):
174
+ if c >= width:
175
+ break
176
+ power, ch = m.cells[r][cc]
177
+ if power >= 4:
178
+ grid[r][c] = (ch, _GREEN_HI)
179
+ elif power >= 2:
180
+ grid[r][c] = (ch, _GREEN)
181
+ elif power >= 1:
182
+ grid[r][c] = (ch, _GREEN_DIM)
183
+ c += 1
184
+ for b in m.blips:
185
+ if not b.visible:
186
+ continue
187
+ x = int(b.x)
188
+ y = int(b.y)
189
+ if 0 <= y < height and 0 <= x < width - 2:
190
+ grid[y][x] = (b.tag[0], b.color)
191
+ if x + 1 < width:
192
+ grid[y][x + 1] = (b.tag[1], b.color)
193
+ for i, ch in enumerate(b.value):
194
+ if x + 3 + i < width:
195
+ grid[y][x + 3 + i] = (ch, b.color)
196
+ rows = []
197
+ for r in range(height):
198
+ cells = []
199
+ for c in range(width):
200
+ if grid[r][c] is None:
201
+ cells.append((' ', ''))
202
+ else:
203
+ cells.append(grid[r][c])
204
+ # collapse to visual width <= width
205
+ line = ''
206
+ prev = ''
207
+ vw = 0
208
+ for ch, color in cells:
209
+ cw = self._vwidth(ch)
210
+ if vw + cw > width:
211
+ break
212
+ if color != prev:
213
+ line += color
214
+ prev = color
215
+ line += ch
216
+ vw += cw
217
+ rows.append(line + _RESET)
218
+ return rows
219
+
220
+ def _status_line(self, width):
221
+ green = 'green ON' if not self._green_paused else 'green OFF'
222
+ state = 'paused' if self._paused else 'running'
223
+ blips = len(self.matrix.blips)
224
+ return _YELLOW + (' %s %s blips:%d speed:x%.1f'
225
+ % (green, state, blips, self._speed)).ljust(width) + _RESET
226
+
227
+ def _draw_info(self, width, height):
228
+ count = max(4, height - 4)
229
+ rows = self._frame_rows(width, count)
230
+ title = _CYAN + (' %s - %s ' % (PACKAGE_NAME, GWF_TITLE)).ljust(width) + _RESET
231
+ keys = _YELLOW + (' [g] pause green [n] new instance [p] pause all [+/-] speed [q] quit ').ljust(width) + _RESET
232
+ status = self._status_line(width)
233
+ body = '\n'.join(rows[:max(1, count - 3)])
234
+ print('\x1b[2J' + title + '\n' + body + '\n' + status + '\n' + keys + '\n', end='', flush=True)
235
+
236
+ def _animate(self, stop):
237
+ try:
238
+ last = time.monotonic()
239
+ while not stop['v']:
240
+ now = time.monotonic()
241
+ dt = min(0.1, now - last)
242
+ last = now
243
+ if not self._paused:
244
+ if not self._green_paused:
245
+ self.matrix.update_rain(dt * self._speed)
246
+ self.matrix.update_blips(dt * self._speed)
247
+ width, height = self._dims()
248
+ if width != self.matrix.w or height != self.matrix.h:
249
+ self.matrix.w = width
250
+ self.matrix.h = height
251
+ self._draw_info(width, height)
252
+ time.sleep(0.05)
253
+ except BaseException:
254
+ pass
255
+
256
+ def _on_key(self, key):
257
+ if isinstance(key, str):
258
+ k = key.lower()
259
+ if k == 'g':
260
+ self._green_paused = not self._green_paused
261
+ return True
262
+ if k == 'n':
263
+ self.new_instance()
264
+ return True
265
+ if k == 'p':
266
+ self._paused = not self._paused
267
+ return True
268
+ if k == '+':
269
+ self._speed = min(8.0, self._speed * 1.5)
270
+ return True
271
+ if k == '-':
272
+ self._speed = max(0.05, self._speed / 1.5)
273
+ return True
274
+ if k == 'q':
275
+ self.running = False
276
+ return True
277
+ return False
278
+
279
+ def run_wrapper(self, tui, lpro, lpro_s, session_usr='zeta', active='s', first=True):
280
+ self.tui = tui
281
+ try:
282
+ from . import tui as tui_mod
283
+ return_to_menu = tui_mod._ReturnToMenu
284
+ except ImportError:
285
+ return_to_menu = None
286
+ tui.set_app_key_handler(self._on_key)
287
+ width, height = self._dims()
288
+ self._draw_info(width, height)
289
+ stop = {'v': False}
290
+ thread = threading.Thread(target=self._animate, args=(stop,), daemon=True)
291
+ thread.start()
292
+ try:
293
+ while not tui.exit_requested and self.running:
294
+ time.sleep(0.1)
295
+ finally:
296
+ stop['v'] = True
297
+ thread.join(timeout=0.5)
298
+ tui.set_app_key_handler(None)
299
+ if return_to_menu is not None:
300
+ raise return_to_menu()
301
+
302
+
303
+ def run():
304
+ app = GWF()
305
+ app.run_wrapper(None, None, None)
306
+
307
+
308
+ if __name__ == '__main__':
309
+ run()
@@ -288,6 +288,10 @@ class MProcsTUI:
288
288
  self._stdscr = None
289
289
  self._dirty = True
290
290
  self._last_clock = None
291
+ self.app_key_handler = None
292
+
293
+ def set_app_key_handler(self, handler):
294
+ self.app_key_handler = handler
291
295
 
292
296
  def _emit(self, text):
293
297
  self._out_q.put(text)
@@ -514,6 +518,13 @@ class MProcsTUI:
514
518
  if self.menu_mode:
515
519
  self._handle_menu_key(key)
516
520
  return
521
+ if not self.input_active and self.app_key_handler is not None:
522
+ try:
523
+ if self.app_key_handler(key):
524
+ self._dirty = True
525
+ return
526
+ except Exception:
527
+ pass
517
528
  if key in (curses.KEY_PPAGE, curses.KEY_NPAGE):
518
529
  page = max(3, self.height - 4)
519
530
  self._scroll_by(-page if key == curses.KEY_PPAGE else page)
@@ -614,6 +625,8 @@ class MProcsTUI:
614
625
  self.selected_app = self.apps[idx]
615
626
  self.menu_mode = False
616
627
  self.app_done = False
628
+ self.input_active = False
629
+ self.input_locked = False
617
630
  self.set_app(self.selected_app)
618
631
  self._selection_q.put(idx)
619
632
  if self.session_started:
@@ -13,7 +13,7 @@ try:
13
13
  import importlib.metadata
14
14
  PACKAGE_VERSION = importlib.metadata.version(PACKAGE_NAME)
15
15
  except Exception:
16
- PACKAGE_VERSION = "8.8.2"
16
+ PACKAGE_VERSION = "8.8.4"
17
17
 
18
18
  _latest_version = None
19
19
  _update_available = False
@@ -122,6 +122,15 @@ class VanillaWrapper(AppWrapper):
122
122
  package = 'MProcs'
123
123
 
124
124
 
125
+ class GwfWrapper(AppWrapper):
126
+ name = 'GWF'
127
+ package = 'MProcs'
128
+
129
+ def _run_app(self, tui, lpro, lpro_s, first=True):
130
+ import gwf
131
+ gwf.GWF(tui).run_wrapper(tui, None, None)
132
+
133
+
125
134
  ALL_APPS = [
126
135
  MdcciWrapper(),
127
136
  NeonBunnyWrapper(),
@@ -132,4 +141,5 @@ ALL_APPS = [
132
141
  MornWrapper(),
133
142
  DestinyWrapper(),
134
143
  VanillaWrapper(),
144
+ GwfWrapper(),
135
145
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: MProcs
3
- Version: 8.8.2
3
+ Version: 8.8.4
4
4
  Summary: MProcs - derived from NeonBunny
5
5
  Author-email: tderk <usvu.tech@gmail.com>
6
6
  License: MIT
@@ -11,6 +11,7 @@ src/MProcs/scripts/__init__.py
11
11
  src/MProcs/scripts/ai_image.py
12
12
  src/MProcs/scripts/data_loader.py
13
13
  src/MProcs/scripts/deepseek_ai.py
14
+ src/MProcs/scripts/gwf.py
14
15
  src/MProcs/scripts/keys.py
15
16
  src/MProcs/scripts/lpro.py
16
17
  src/MProcs/scripts/lpro_s.py
@@ -1,5 +1,6 @@
1
1
  [console_scripts]
2
2
  MProcs = MProcs.scripts.main:run
3
+ gwf = MProcs.scripts.gwf:run
3
4
  lpro = MProcs.scripts.lpro:main
4
5
  lpro-s = MProcs.scripts.lpro_s:main
5
6
  mprocs = MProcs.scripts.main:run
File without changes
File without changes
File without changes