setta 0.0.3.dev3__py3-none-any.whl → 0.0.3.dev5__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- setta/__init__.py +1 -1
- setta/cli/__init__.py +1 -1
- setta/code_gen/create_runnable_scripts.py +44 -7
- setta/routers/interactive.py +39 -20
- setta/static/frontend/assets/{index-73adf0a9.js → index-1f218da9.js} +154 -154
- setta/static/frontend/assets/index-af271c9f.css +32 -0
- setta/static/frontend/index.html +2 -2
- setta/tasks/tasks.py +105 -98
- setta/tasks/utils.py +72 -8
- setta/utils/websocket_manager.py +8 -3
- {setta-0.0.3.dev3.dist-info → setta-0.0.3.dev5.dist-info}/METADATA +1 -1
- {setta-0.0.3.dev3.dist-info → setta-0.0.3.dev5.dist-info}/RECORD +16 -16
- setta/static/frontend/assets/index-1d4b4ecf.css +0 -32
- {setta-0.0.3.dev3.dist-info → setta-0.0.3.dev5.dist-info}/LICENSE +0 -0
- {setta-0.0.3.dev3.dist-info → setta-0.0.3.dev5.dist-info}/WHEEL +0 -0
- {setta-0.0.3.dev3.dist-info → setta-0.0.3.dev5.dist-info}/entry_points.txt +0 -0
- {setta-0.0.3.dev3.dist-info → setta-0.0.3.dev5.dist-info}/top_level.txt +0 -0
setta/static/frontend/index.html
CHANGED
@@ -15,8 +15,8 @@
|
|
15
15
|
|
16
16
|
|
17
17
|
<title>setta.dev</title>
|
18
|
-
<script type="module" crossorigin src="/static/assets/index-
|
19
|
-
<link rel="stylesheet" href="/static/assets/index-
|
18
|
+
<script type="module" crossorigin src="/static/assets/index-1f218da9.js"></script>
|
19
|
+
<link rel="stylesheet" href="/static/assets/index-af271c9f.css">
|
20
20
|
</head>
|
21
21
|
<body>
|
22
22
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
setta/tasks/tasks.py
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
import asyncio
|
2
2
|
import logging
|
3
|
-
import queue
|
4
|
-
import threading
|
5
3
|
from typing import Dict
|
6
4
|
|
7
5
|
from setta.database.utils import create_new_id
|
6
|
+
from setta.utils.constants import C
|
8
7
|
|
9
8
|
from . import fns
|
10
9
|
from .fns.utils import TaskDefinition, TaskMessage
|
@@ -20,75 +19,31 @@ class Tasks:
|
|
20
19
|
self.task_runner = TaskRunner()
|
21
20
|
self.cache = {}
|
22
21
|
self.fns: Dict[str, TaskDefinition] = {}
|
23
|
-
self.
|
24
|
-
self.websockets = []
|
22
|
+
self.in_memory_subprocesses = {}
|
23
|
+
self.websockets = []
|
24
|
+
self.stop_event = asyncio.Event()
|
25
25
|
add_fns_from_module(self.fns, fns)
|
26
26
|
|
27
|
-
# Start stdout listener thread
|
28
|
-
self._stop_event = asyncio.Event()
|
29
|
-
self.stdout_queue = queue.Queue() # regular Queue
|
30
|
-
self._stdout_processor_task = None
|
31
|
-
self.stdout_thread = threading.Thread(target=self._stdout_listener, daemon=True)
|
32
|
-
self.stdout_thread.start()
|
33
|
-
|
34
|
-
# Backend Changes (Tasks class)
|
35
27
|
async def connect(self, websocket):
|
36
28
|
# Accept the new connection
|
37
29
|
await websocket.accept()
|
38
30
|
self.websockets.append(websocket)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
self._stdout_processor_task = asyncio.create_task(
|
43
|
-
self._process_stdout_queue()
|
44
|
-
)
|
31
|
+
for k, v in self.in_memory_subprocesses.items():
|
32
|
+
v["subprocess"].start_stdout_processor_task()
|
33
|
+
logger.debug(f"listening to subprocess {k}")
|
45
34
|
|
46
35
|
async def disconnect(self, websocket):
|
47
36
|
self.websockets.remove(websocket)
|
48
37
|
if len(self.websockets) == 0:
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
def _stdout_listener(self):
|
59
|
-
while not self._stop_event.is_set():
|
60
|
-
try:
|
61
|
-
stdout_data = self.in_memory_subprocess.stdout_parent_conn.recv()
|
62
|
-
self.stdout_queue.put(stdout_data) # simple put, no async needed
|
63
|
-
except Exception as e:
|
64
|
-
if self._stop_event.is_set():
|
65
|
-
break
|
66
|
-
logger.debug(f"Error in stdout listener: {e}")
|
67
|
-
|
68
|
-
async def _process_stdout_queue(self):
|
69
|
-
while not self._stop_event.is_set():
|
70
|
-
try:
|
71
|
-
if self._stop_event.is_set():
|
72
|
-
break
|
73
|
-
if len(self.websockets) > 0:
|
74
|
-
stdout_data = self.stdout_queue.get_nowait()
|
75
|
-
stdout_data = stdout_data.replace("\n", "\r\n")
|
76
|
-
for w in self.websockets:
|
77
|
-
await w.send_text(stdout_data)
|
78
|
-
self.stdout_queue.task_done()
|
79
|
-
except queue.Empty:
|
80
|
-
await asyncio.sleep(0.1) # Check for connection every 100ms
|
81
|
-
except asyncio.CancelledError:
|
82
|
-
break
|
83
|
-
except Exception as e:
|
84
|
-
if self._stop_event.is_set():
|
85
|
-
break
|
86
|
-
logger.debug(f"Error processing stdout: {e}")
|
87
|
-
|
88
|
-
async def __call__(self, fn_name, message: TaskMessage):
|
89
|
-
if fn_name in self.fns:
|
90
|
-
return await self.call_regular_fn(fn_name, message)
|
91
|
-
return await self.call_in_memory_subprocess_fn(fn_name, message)
|
38
|
+
for v in self.in_memory_subprocesses.values():
|
39
|
+
await v["subprocess"].stop_stdout_processor_task()
|
40
|
+
|
41
|
+
async def __call__(
|
42
|
+
self, message_type, message: TaskMessage, websocket_manager=None
|
43
|
+
):
|
44
|
+
if message_type == "inMemoryFn":
|
45
|
+
return await self.call_in_memory_subprocess_fn(message, websocket_manager)
|
46
|
+
return await self.call_regular_fn(message_type, message)
|
92
47
|
|
93
48
|
async def call_regular_fn(self, fn_name, message: TaskMessage):
|
94
49
|
fn = self.fns[fn_name]
|
@@ -101,52 +56,104 @@ class Tasks:
|
|
101
56
|
result["messageType"] = fn.return_message_type
|
102
57
|
return result
|
103
58
|
|
104
|
-
async def call_in_memory_subprocess_fn(
|
105
|
-
self
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
59
|
+
async def call_in_memory_subprocess_fn(
|
60
|
+
self, message: TaskMessage, websocket_manager=None, call_all=False
|
61
|
+
):
|
62
|
+
# Create a list of tasks to run concurrently
|
63
|
+
tasks = []
|
64
|
+
results = []
|
65
|
+
|
66
|
+
for sp_info in self.in_memory_subprocesses.values():
|
67
|
+
for fn_name, dependencies in sp_info["dependencies"].items():
|
68
|
+
if (
|
69
|
+
call_all
|
70
|
+
or None in dependencies
|
71
|
+
or any(k in dependencies for k in message.content.keys())
|
72
|
+
):
|
73
|
+
# Send message to subprocess
|
74
|
+
sp_info["subprocess"].parent_conn.send(
|
75
|
+
{"type": "call", "fn_name": fn_name, "message": message}
|
76
|
+
)
|
77
|
+
|
78
|
+
# Create task for receiving response
|
79
|
+
task = asyncio.create_task(
|
80
|
+
self._handle_subprocess_response(
|
81
|
+
message.id,
|
82
|
+
sp_info["subprocess"].parent_conn.recv,
|
83
|
+
websocket_manager,
|
84
|
+
results,
|
85
|
+
)
|
86
|
+
)
|
87
|
+
tasks.append(task)
|
88
|
+
|
89
|
+
# Wait for all tasks to complete concurrently
|
90
|
+
if tasks:
|
91
|
+
await asyncio.gather(*tasks)
|
92
|
+
|
93
|
+
if websocket_manager:
|
94
|
+
return {}
|
95
|
+
|
96
|
+
content = []
|
97
|
+
for r in results:
|
98
|
+
if r["content"]:
|
99
|
+
content.extend(r["content"])
|
100
|
+
return {"content": content, "messageType": C.WS_IN_MEMORY_FN_RETURN}
|
101
|
+
|
102
|
+
async def _handle_subprocess_response(
|
103
|
+
self, msg_id, recv_fn, websocket_manager, results
|
104
|
+
):
|
105
|
+
# Run the receive function in a thread
|
106
|
+
result = await self.task_runner.run(recv_fn, [], RunType.THREAD)
|
107
|
+
if result["status"] == "success":
|
108
|
+
if websocket_manager is not None and result["content"]:
|
109
|
+
await websocket_manager.send_message_to_requester(
|
110
|
+
msg_id, result["content"], result["messageType"]
|
111
|
+
)
|
112
|
+
else:
|
113
|
+
results.append(result)
|
114
|
+
|
115
|
+
async def add_custom_fns(self, code_graph, to_cache):
|
116
|
+
for c in code_graph:
|
117
|
+
subprocess_key = c["subprocess_key"]
|
118
|
+
module_name = c["module_name"]
|
119
|
+
sp = self.in_memory_subprocesses.get(subprocess_key, {}).get("subprocess")
|
120
|
+
if not sp:
|
121
|
+
logger.debug(f"Creating new subprocess for {module_name}")
|
122
|
+
sp = SettaInMemoryFnSubprocess(self.stop_event, self.websockets)
|
123
|
+
self.in_memory_subprocesses[subprocess_key] = {
|
124
|
+
"subprocess": sp,
|
125
|
+
"dependencies": {},
|
126
|
+
}
|
127
|
+
|
128
|
+
sp.parent_conn.send(
|
126
129
|
{
|
127
130
|
"type": "import",
|
128
131
|
"code": c["code"],
|
129
|
-
"module_name":
|
132
|
+
"module_name": module_name,
|
130
133
|
"to_cache": to_cache,
|
131
134
|
}
|
132
135
|
)
|
133
|
-
result = await self.task_runner.run(
|
134
|
-
|
135
|
-
|
136
|
+
result = await self.task_runner.run(sp.parent_conn.recv, [], RunType.THREAD)
|
137
|
+
sp_info = self.in_memory_subprocesses[subprocess_key]
|
138
|
+
|
136
139
|
if result["status"] == "success":
|
137
|
-
|
140
|
+
sp_info["dependencies"].update(result["content"])
|
138
141
|
else:
|
139
|
-
|
142
|
+
# TODO: store error message and display on frontend?
|
143
|
+
pass
|
140
144
|
|
141
|
-
|
142
|
-
|
143
|
-
|
145
|
+
all_dependencies = set.union(*sp_info["dependencies"].values())
|
146
|
+
initial_result = await self.call_in_memory_subprocess_fn(
|
147
|
+
TaskMessage(id=create_new_id(), content={}), call_all=True
|
148
|
+
)
|
149
|
+
|
150
|
+
logger.debug(
|
151
|
+
f"self.in_memory_subprocesses keys: {self.in_memory_subprocesses.keys()}"
|
152
|
+
)
|
144
153
|
|
145
|
-
return
|
154
|
+
return all_dependencies, initial_result["content"]
|
146
155
|
|
147
156
|
def close(self):
|
148
|
-
self.
|
149
|
-
self.
|
150
|
-
|
151
|
-
if self._stdout_processor_task:
|
152
|
-
self._stdout_processor_task.cancel()
|
157
|
+
self.stop_event.set()
|
158
|
+
for v in self.in_memory_subprocesses.values():
|
159
|
+
v["subprocess"].close()
|
setta/tasks/utils.py
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
+
import asyncio
|
1
2
|
import importlib.util
|
2
3
|
import json
|
4
|
+
import logging
|
3
5
|
import multiprocessing
|
6
|
+
import queue
|
4
7
|
import sys
|
8
|
+
import threading
|
5
9
|
import traceback
|
6
10
|
import uuid
|
7
11
|
|
@@ -9,6 +13,8 @@ from setta.tasks.fns.utils import TaskDefinition
|
|
9
13
|
from setta.utils.constants import CWD
|
10
14
|
from setta.utils.utils import nested_access
|
11
15
|
|
16
|
+
logger = logging.getLogger(__name__)
|
17
|
+
|
12
18
|
|
13
19
|
def import_code_from_string(code_string, module_name=None, add_to_sys_modules=True):
|
14
20
|
# Generate a unique module name if one isn't provided
|
@@ -16,9 +22,8 @@ def import_code_from_string(code_string, module_name=None, add_to_sys_modules=Tr
|
|
16
22
|
module_name = f"setta_dynamic_module_{uuid.uuid4().hex}"
|
17
23
|
|
18
24
|
# Add current directory to sys.path if it's not already there
|
19
|
-
|
20
|
-
|
21
|
-
sys.path.insert(0, current_dir)
|
25
|
+
if CWD not in sys.path:
|
26
|
+
sys.path.insert(0, CWD)
|
22
27
|
|
23
28
|
spec = importlib.util.spec_from_loader(module_name, loader=None)
|
24
29
|
|
@@ -40,13 +45,23 @@ def import_code_from_string(code_string, module_name=None, add_to_sys_modules=Tr
|
|
40
45
|
|
41
46
|
|
42
47
|
class SettaInMemoryFnSubprocess:
|
43
|
-
def __init__(self):
|
48
|
+
def __init__(self, stop_event, websockets):
|
44
49
|
self.parent_conn, self.child_conn = multiprocessing.Pipe()
|
45
50
|
self.process = multiprocessing.Process(target=self._subprocess_main)
|
46
51
|
self.stdout_parent_conn, self.stdout_child_conn = multiprocessing.Pipe()
|
47
52
|
self.process.daemon = True # Ensure process dies with parent
|
48
53
|
self.process.start()
|
49
54
|
|
55
|
+
self.stop_event = stop_event
|
56
|
+
self.websockets = websockets
|
57
|
+
self.stdout_queue = queue.Queue()
|
58
|
+
self.stdout_processor_task = None
|
59
|
+
self.stdout_thread = threading.Thread(target=self.stdout_listener, daemon=True)
|
60
|
+
self.stdout_thread.start()
|
61
|
+
|
62
|
+
if len(self.websockets) > 0:
|
63
|
+
self.start_stdout_processor_task()
|
64
|
+
|
50
65
|
def _subprocess_main(self):
|
51
66
|
"""Main loop in subprocess that handles all requests"""
|
52
67
|
# Initialize store for imported modules
|
@@ -137,6 +152,10 @@ class SettaInMemoryFnSubprocess:
|
|
137
152
|
self.stdout_parent_conn.close()
|
138
153
|
self.stdout_child_conn.close()
|
139
154
|
|
155
|
+
self.stdout_thread.join()
|
156
|
+
if self.stdout_processor_task:
|
157
|
+
self.stdout_processor_task.cancel()
|
158
|
+
|
140
159
|
def process_message(self, fn_name, message, cache):
|
141
160
|
if fn_name in cache:
|
142
161
|
exporter_obj = cache[fn_name]
|
@@ -147,6 +166,51 @@ class SettaInMemoryFnSubprocess:
|
|
147
166
|
message.content = exporter_obj.output
|
148
167
|
return message.content
|
149
168
|
|
169
|
+
def start_stdout_processor_task(self):
|
170
|
+
if self.stdout_processor_task is None or self.stdout_processor_task.done():
|
171
|
+
self.stdout_processor_task = asyncio.create_task(
|
172
|
+
self.process_stdout_queue()
|
173
|
+
)
|
174
|
+
|
175
|
+
async def stop_stdout_processor_task(self):
|
176
|
+
if self.stdout_processor_task and not self.stdout_processor_task.done():
|
177
|
+
self.stdout_processor_task.cancel()
|
178
|
+
try:
|
179
|
+
await self.stdout_processor_task
|
180
|
+
except asyncio.CancelledError:
|
181
|
+
pass
|
182
|
+
self.stdout_processor_task = None
|
183
|
+
|
184
|
+
async def process_stdout_queue(self):
|
185
|
+
while not self.stop_event.is_set():
|
186
|
+
try:
|
187
|
+
if self.stop_event.is_set():
|
188
|
+
break
|
189
|
+
if len(self.websockets) > 0:
|
190
|
+
stdout_data = self.stdout_queue.get_nowait()
|
191
|
+
stdout_data = stdout_data.replace("\n", "\r\n")
|
192
|
+
for w in self.websockets:
|
193
|
+
await w.send_text(stdout_data)
|
194
|
+
self.stdout_queue.task_done()
|
195
|
+
except queue.Empty:
|
196
|
+
await asyncio.sleep(0.1) # Check for connection every 100ms
|
197
|
+
except asyncio.CancelledError:
|
198
|
+
break
|
199
|
+
except Exception as e:
|
200
|
+
if self.stop_event.is_set():
|
201
|
+
break
|
202
|
+
logger.debug(f"Error processing stdout: {e}")
|
203
|
+
|
204
|
+
def stdout_listener(self):
|
205
|
+
while not self.stop_event.is_set():
|
206
|
+
try:
|
207
|
+
stdout_data = self.stdout_parent_conn.recv()
|
208
|
+
self.stdout_queue.put(stdout_data) # simple put, no async needed
|
209
|
+
except Exception as e:
|
210
|
+
if self._stop_event.is_set():
|
211
|
+
break
|
212
|
+
logger.debug(f"Error in stdout listener: {e}")
|
213
|
+
|
150
214
|
|
151
215
|
def add_fns_from_module(fns_dict, module, module_name=None):
|
152
216
|
count = 1
|
@@ -168,11 +232,11 @@ def add_fns_from_module(fns_dict, module, module_name=None):
|
|
168
232
|
def get_task_metadata(in_memory_fn, exporter_obj):
|
169
233
|
# None means run the task on every change
|
170
234
|
if in_memory_fn.dependencies is None:
|
171
|
-
dependencies = None
|
235
|
+
dependencies = set([None])
|
172
236
|
# Empty array means only run when the task imported.
|
173
237
|
# Non-empty array means run when specified dependencies update.
|
174
238
|
else:
|
175
|
-
dependencies =
|
239
|
+
dependencies = set(
|
176
240
|
exporter_obj.var_name_reverse_mapping[d] for d in in_memory_fn.dependencies
|
177
|
-
|
178
|
-
return
|
241
|
+
)
|
242
|
+
return dependencies
|
setta/utils/websocket_manager.py
CHANGED
@@ -43,7 +43,9 @@ class WebsocketManager:
|
|
43
43
|
if wid == self.server_cli_id:
|
44
44
|
# process task and send any results back to requester
|
45
45
|
result = await tasks(
|
46
|
-
message["messageType"],
|
46
|
+
message["messageType"],
|
47
|
+
TaskMessage.parse_obj(message),
|
48
|
+
websocket_manager=self,
|
47
49
|
)
|
48
50
|
if "content" in result:
|
49
51
|
websocket = self.sockets[fromWebsocketId]["websocket"]
|
@@ -64,10 +66,13 @@ class WebsocketManager:
|
|
64
66
|
if "location" in message:
|
65
67
|
self.sockets[fromWebsocketId]["location"] = message["location"]
|
66
68
|
|
67
|
-
async def send_message_to_requester(self, id, content):
|
69
|
+
async def send_message_to_requester(self, id, content, messageType=None):
|
68
70
|
# just send data to target websocket
|
69
71
|
websocket = self.sockets[self.message_id_to_sender_id[id]]["websocket"]
|
70
|
-
|
72
|
+
return_val = {"id": id, "content": content}
|
73
|
+
if messageType:
|
74
|
+
return_val["messageType"] = messageType
|
75
|
+
await websocket.send_text(json.dumps(return_val))
|
71
76
|
|
72
77
|
async def send_message_to_location(self, content, messageType, location):
|
73
78
|
for w in self.sockets.values():
|
@@ -1,11 +1,11 @@
|
|
1
|
-
setta/__init__.py,sha256=
|
1
|
+
setta/__init__.py,sha256=kH8A5OhSz91E7LZXLnQ3CnbIZBoobjt8lmTWUyCqnuw,27
|
2
2
|
setta/server.py,sha256=P78BMFvcCokVhjnVlNIKcmpCSvmzSqt-33bx4bhOe6Y,4626
|
3
3
|
setta/start.py,sha256=jEeSiocLeBitvg48fa6k1CpLnPI63JHkQ8O-WVM6ch8,3078
|
4
|
-
setta/cli/__init__.py,sha256=
|
4
|
+
setta/cli/__init__.py,sha256=UxZG_VOMuF6lEBT3teUgTS9ulsK3wt3Gu3BbAQiAmt8,47
|
5
5
|
setta/cli/connect.py,sha256=Pj2Ten7CQcLQGNnyi5Y-vYslQDN3J8csPcWetlvu_J0,1273
|
6
6
|
setta/cli/logger.py,sha256=M-gGOcYt8Xj7ldNGBAUfA9yL1nX4UpBuQR1lkg_qiSs,6130
|
7
7
|
setta/code_gen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
setta/code_gen/create_runnable_scripts.py,sha256=
|
8
|
+
setta/code_gen/create_runnable_scripts.py,sha256=LXRu8ErO3_e5HCNomnlgfsyxKp2h-Pmm2VFXzBgDDhA,17444
|
9
9
|
setta/code_gen/export_selected.py,sha256=Hpa2uYFxTtxG0R9szY3WQA2Hj6XoejYVT53ET1l7Qmg,26883
|
10
10
|
setta/code_gen/find_placeholders.py,sha256=xWEVVPmyeEhPwoMsCnmMkd-ox3rd50jRur3uxfCqB30,601
|
11
11
|
setta/code_gen/utils.py,sha256=ArBPYA__ekeHjZVUDXanlMEnqCX5-Z_R1rMM-1UbEV0,4088
|
@@ -87,7 +87,7 @@ setta/routers/artifact.py,sha256=9wHdreg5DsLshhET-6gEDw2Apw_-r8bRF1x3-_dD9mU,266
|
|
87
87
|
setta/routers/code_info.py,sha256=rDBLkr5VQOlktap3hWA73ls0VrBi5y4mc_SfWzw9ad0,857
|
88
88
|
setta/routers/dependencies.py,sha256=lQDZFcXw-jUXK1q8yglUg3jY9dKoE-xvVcWckKqmOr4,1126
|
89
89
|
setta/routers/in_memory_fn_stdout_websocket.py,sha256=T2BpLzh6PwYQP0qIkFS4r_VfEKBlwl4gkwIaq6r6Phs,604
|
90
|
-
setta/routers/interactive.py,sha256=
|
90
|
+
setta/routers/interactive.py,sha256=juUtPmCyqHSnIb5k6iOYUtfmukp1Z6x25wISlANgUic,4385
|
91
91
|
setta/routers/lsp.py,sha256=DAZqdiRKDWJ9ikjwQetV4_8s9U-EDC91ToJA3u57qnU,385
|
92
92
|
setta/routers/projects.py,sha256=p3zPD3jobYOxBGJSSIYS1Aqu1w-PrJCcEN6dPJ0DT6E,5255
|
93
93
|
setta/routers/reference_renaming.py,sha256=Ec1hz2Nz_hYqk8GyGmUcWKvXo-lVEDbIIK2YbX-wi00,3598
|
@@ -108,7 +108,7 @@ setta/static/frontend/browserconfig.xml,sha256=w0iw1t89kA7-965LTfyLYrFzewTQnUWE_
|
|
108
108
|
setta/static/frontend/favicon-16x16.png,sha256=q67Crpy8s3wryu7Y3kffPeysN99Lt4XeFygXhPKize8,740
|
109
109
|
setta/static/frontend/favicon-32x32.png,sha256=4NKXYticYdMrRHmVveHjxqnBU1HWgBT5JyJG8lx3BNE,1027
|
110
110
|
setta/static/frontend/favicon.ico,sha256=02qhEBLsvsgBTZX6dcZElMyivlvrR7Yr6wB8ItEZFsc,15086
|
111
|
-
setta/static/frontend/index.html,sha256=
|
111
|
+
setta/static/frontend/index.html,sha256=4d4CugkQWpyw6EozUuo1rnSN81dqwLxqea3sWNSeT4w,1296
|
112
112
|
setta/static/frontend/manifest.json,sha256=ULPYw5A68_eNhxuUVXqxT045yhkurKPSz6hjyGcnmhQ,492
|
113
113
|
setta/static/frontend/mstile-144x144.png,sha256=wQqckmRWre2NCCevevI3rv4j0tcduVMkpYr2tPj73cs,2692
|
114
114
|
setta/static/frontend/mstile-150x150.png,sha256=FUwy6PipTofnhmJB5CdXWYgwy-2inq_sIOdOwdDklcY,2674
|
@@ -184,8 +184,8 @@ setta/static/frontend/assets/cormorant-garamond-latin-700-italic-0bc53e12.woff2,
|
|
184
184
|
setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-525738e0.woff2,sha256=Ulc44CPXdUiI5dY86W76HLk7801Fm9_QywCV-8GRtFU,17240
|
185
185
|
setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-99563037.woff2,sha256=mVYwN54qI0RLXqyrDGPUNpBHWSJDKjgUyBRWa2FJ_ao,5248
|
186
186
|
setta/static/frontend/assets/erase-5e0448ea.svg,sha256=XgRI6pChr392LJ-pGbwqqkN8OWcJMEtRGX-Gv-90qjw,872
|
187
|
-
setta/static/frontend/assets/index-
|
188
|
-
setta/static/frontend/assets/index-
|
187
|
+
setta/static/frontend/assets/index-1f218da9.js,sha256=GEYeMbQIVHiDWM2sapWp1VSxuzoVe9sC2IJtNP5021k,2847446
|
188
|
+
setta/static/frontend/assets/index-af271c9f.css,sha256=ryccn_uul30_aMdIhgzMlq6GcE0D6x8fyfneCdgaY9o,232608
|
189
189
|
setta/static/frontend/assets/inter-all-400-normal-054f12d0.woff,sha256=BU8S0GmcIMyYte4ESEdQJO-WvL2Rb-38m1n0ujdbYxI,128624
|
190
190
|
setta/static/frontend/assets/inter-all-600-normal-c03769e5.woff,sha256=wDdp5VNyQL_IbxcPThD2qI-ETg_QKj7AmCwMCjqDfLE,139072
|
191
191
|
setta/static/frontend/assets/inter-all-800-normal-15dc6e4b.woff,sha256=FdxuS9xuVumB5nbVcCXyt3IWqzS4Z75qiRz_0FV5al0,139120
|
@@ -232,8 +232,8 @@ setta/static/seed/.DS_Store,sha256=ENxJvDQd7Te_U8gExcXtHE-mAeBUYOHELRfDWgN1NmA,6
|
|
232
232
|
setta/static/seed/examples/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
233
233
|
setta/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
234
234
|
setta/tasks/task_runner.py,sha256=gMXpfZWFMQbix2MfrHVCKB7BxQCjO8JH2P8cxUmt1ms,849
|
235
|
-
setta/tasks/tasks.py,sha256=
|
236
|
-
setta/tasks/utils.py,sha256=
|
235
|
+
setta/tasks/tasks.py,sha256=dR02kybZnwiGKt3YhlfWgx0fDUPCoDeslrnm8mJcr74,5956
|
236
|
+
setta/tasks/utils.py,sha256=D_M5rZRu0N4z21mM2jyrKBSUCCFT6LrQgegr3uf1NgM,8545
|
237
237
|
setta/tasks/fns/__init__.py,sha256=JhGzzQGaT9BWtF3pOmguh6pzIF9kdG3jdDNLyYZ2w7g,461
|
238
238
|
setta/tasks/fns/codeAreaAutocomplete.py,sha256=gJ5JbjkWDyTothr-UF-YlOxrbVzj2iyOVK7XD3lfhSQ,6416
|
239
239
|
setta/tasks/fns/codeAreaFindTemplateVars.py,sha256=vD9rY8VNPavv6VKa1bnxRPPRDNvFQy6mPIZRl-_3GnY,3708
|
@@ -253,10 +253,10 @@ setta/utils/generate_memorable_string.py,sha256=ZIn8gQm3cpMuqTCRgAPXAm5VdbWW7O3f
|
|
253
253
|
setta/utils/generate_new_filename.py,sha256=KBLX6paDmTvXR-027TpqQkfijIXc7mCfhen-u1WZARA,3067
|
254
254
|
setta/utils/section_contents.py,sha256=V2HQPik6DfSXw4j7IalbP5AZ3OEGCbtL5ub3xL-Q_Qo,4141
|
255
255
|
setta/utils/utils.py,sha256=KjzcvgM3Ab3IcE8vaWYtgBpwzPLKg0LmblnHLoYZJHM,9164
|
256
|
-
setta/utils/websocket_manager.py,sha256=
|
257
|
-
setta-0.0.3.
|
258
|
-
setta-0.0.3.
|
259
|
-
setta-0.0.3.
|
260
|
-
setta-0.0.3.
|
261
|
-
setta-0.0.3.
|
262
|
-
setta-0.0.3.
|
256
|
+
setta/utils/websocket_manager.py,sha256=S2lEGZsc2OhW0yKLW9VEcH7wi7ppzTfDMQa_hxf3ovc,3772
|
257
|
+
setta-0.0.3.dev5.dist-info/LICENSE,sha256=us9fuCq9wmiZVzayjKxNZ2iJYF6dROe0Qp57ToCO7XU,11361
|
258
|
+
setta-0.0.3.dev5.dist-info/METADATA,sha256=IWvmVuV-CtMykwttA1EMFK8RuFQEbFMBfVS3gvL5SIs,829
|
259
|
+
setta-0.0.3.dev5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
260
|
+
setta-0.0.3.dev5.dist-info/entry_points.txt,sha256=P0qCESy9fWF2q1EQ9JufGldCSnPHplDPn8J6Bgk5hB0,42
|
261
|
+
setta-0.0.3.dev5.dist-info/top_level.txt,sha256=8G4lmRzVOnJ11_DescPVHE6MQZH-o06A0nGsDDV2ngY,6
|
262
|
+
setta-0.0.3.dev5.dist-info/RECORD,,
|