fastled 1.2.33__py3-none-any.whl → 1.4.50__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.
Files changed (58) hide show
  1. fastled/__init__.py +51 -192
  2. fastled/__main__.py +14 -0
  3. fastled/__version__.py +6 -0
  4. fastled/app.py +124 -27
  5. fastled/args.py +124 -0
  6. fastled/assets/localhost-key.pem +28 -0
  7. fastled/assets/localhost.pem +27 -0
  8. fastled/cli.py +10 -2
  9. fastled/cli_test.py +21 -0
  10. fastled/cli_test_interactive.py +21 -0
  11. fastled/client_server.py +334 -55
  12. fastled/compile_server.py +12 -1
  13. fastled/compile_server_impl.py +115 -42
  14. fastled/docker_manager.py +392 -69
  15. fastled/emoji_util.py +27 -0
  16. fastled/filewatcher.py +100 -8
  17. fastled/find_good_connection.py +105 -0
  18. fastled/header_dump.py +63 -0
  19. fastled/install/__init__.py +1 -0
  20. fastled/install/examples_manager.py +62 -0
  21. fastled/install/extension_manager.py +113 -0
  22. fastled/install/main.py +156 -0
  23. fastled/install/project_detection.py +167 -0
  24. fastled/install/test_install.py +373 -0
  25. fastled/install/vscode_config.py +344 -0
  26. fastled/interruptible_http.py +148 -0
  27. fastled/keyboard.py +1 -0
  28. fastled/keyz.py +84 -0
  29. fastled/live_client.py +26 -1
  30. fastled/open_browser.py +133 -89
  31. fastled/parse_args.py +219 -15
  32. fastled/playwright/chrome_extension_downloader.py +207 -0
  33. fastled/playwright/playwright_browser.py +773 -0
  34. fastled/playwright/resize_tracking.py +127 -0
  35. fastled/print_filter.py +52 -0
  36. fastled/project_init.py +20 -13
  37. fastled/select_sketch_directory.py +142 -17
  38. fastled/server_flask.py +487 -0
  39. fastled/server_start.py +21 -0
  40. fastled/settings.py +53 -4
  41. fastled/site/build.py +2 -10
  42. fastled/site/examples.py +10 -0
  43. fastled/sketch.py +129 -7
  44. fastled/string_diff.py +218 -9
  45. fastled/test/examples.py +7 -5
  46. fastled/types.py +22 -2
  47. fastled/util.py +78 -0
  48. fastled/version.py +41 -0
  49. fastled/web_compile.py +401 -218
  50. fastled/zip_files.py +76 -0
  51. {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/METADATA +533 -382
  52. fastled-1.4.50.dist-info/RECORD +60 -0
  53. {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/WHEEL +1 -1
  54. fastled/open_browser2.py +0 -111
  55. fastled-1.2.33.dist-info/RECORD +0 -33
  56. {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/entry_points.txt +0 -0
  57. {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info/licenses}/LICENSE +0 -0
  58. {fastled-1.2.33.dist-info → fastled-1.4.50.dist-info}/top_level.txt +0 -0
fastled/__init__.py CHANGED
@@ -1,22 +1,17 @@
1
1
  """FastLED Wasm Compiler package."""
2
2
 
3
- # context
4
- import shutil
5
- import subprocess
6
3
  from contextlib import contextmanager
7
4
  from multiprocessing import Process
8
5
  from pathlib import Path
9
6
  from typing import Generator
10
7
 
8
+ from .__version__ import __version__
11
9
  from .compile_server import CompileServer
10
+ from .emoji_util import EMO
12
11
  from .live_client import LiveClient
12
+ from .settings import DOCKER_FILE, IMAGE_NAME
13
13
  from .site.build import build
14
- from .types import BuildMode, CompileResult, CompileServerError
15
-
16
- # IMPORTANT! There's a bug in github which will REJECT any version update
17
- # that has any other change in the repo. Please bump the version as the
18
- # ONLY change in a commit, or else the pypi update and the release will fail.
19
- __version__ = "1.2.33"
14
+ from .types import BuildMode, CompileResult, CompileServerError, FileResponse
20
15
 
21
16
 
22
17
  class Api:
@@ -45,15 +40,31 @@ class Api:
45
40
  host: str | CompileServer | None = None,
46
41
  build_mode: BuildMode = BuildMode.QUICK,
47
42
  profile: bool = False, # When true then profile information will be enabled and included in the zip.
43
+ no_platformio: bool = False,
48
44
  ) -> CompileResult:
45
+ from fastled.sketch import looks_like_fastled_repo
49
46
  from fastled.web_compile import web_compile
50
47
 
51
48
  if isinstance(host, CompileServer):
52
49
  host = host.url()
53
50
  if isinstance(directory, str):
54
51
  directory = Path(directory)
52
+
53
+ # Guard: libfastled compilation requires volume source mapping
54
+ # Only allow libcompile if we're in a FastLED repository
55
+ allow_libcompile = looks_like_fastled_repo(Path(".").resolve())
56
+ if not allow_libcompile:
57
+ print(
58
+ f"{EMO('⚠️', 'WARNING:')} libfastled compilation disabled: not running in FastLED repository"
59
+ )
60
+
55
61
  out: CompileResult = web_compile(
56
- directory, host, build_mode=build_mode, profile=profile
62
+ directory,
63
+ host,
64
+ build_mode=build_mode,
65
+ profile=profile,
66
+ no_platformio=no_platformio,
67
+ allow_libcompile=allow_libcompile,
57
68
  )
58
69
  return out
59
70
 
@@ -67,6 +78,11 @@ class Api:
67
78
  keep_running=True,
68
79
  build_mode=BuildMode.QUICK,
69
80
  profile=False,
81
+ http_port: (
82
+ int | None
83
+ ) = None, # None means auto select a free port. -1 means no server.
84
+ no_platformio: bool = False,
85
+ enable_https: bool = True, # Enable HTTPS for the local server
70
86
  ) -> LiveClient:
71
87
  return LiveClient(
72
88
  sketch_directory=sketch_directory,
@@ -77,6 +93,9 @@ class Api:
77
93
  keep_running=keep_running,
78
94
  build_mode=build_mode,
79
95
  profile=profile,
96
+ http_port=http_port,
97
+ no_platformio=no_platformio,
98
+ enable_https=enable_https,
80
99
  )
81
100
 
82
101
  @staticmethod
@@ -87,9 +106,9 @@ class Api:
87
106
  mapped_dir: Path | None = None, # Sketch directory.
88
107
  container_name: str | None = None, # Specific docker container name.
89
108
  remove_previous: bool = False,
109
+ no_platformio: bool = False,
90
110
  ) -> CompileServer:
91
111
  """Uses docker to spawn a compile server from the given name."""
92
- from fastled.compile_server import CompileServer
93
112
 
94
113
  out = CompileServer(
95
114
  container_name=container_name,
@@ -98,6 +117,7 @@ class Api:
98
117
  mapped_dir=mapped_dir,
99
118
  auto_start=auto_start,
100
119
  remove_previous=remove_previous,
120
+ no_platformio=no_platformio,
101
121
  )
102
122
  return out
103
123
 
@@ -110,6 +130,7 @@ class Api:
110
130
  mapped_dir: Path | None = None, # Sketch directory.
111
131
  container_name: str | None = None, # Specific docker container name.
112
132
  remove_previous=False,
133
+ no_platformio: bool = False,
113
134
  ) -> Generator[CompileServer, None, None]:
114
135
  server = Api.spawn_server(
115
136
  interactive=interactive,
@@ -118,6 +139,7 @@ class Api:
118
139
  mapped_dir=mapped_dir,
119
140
  container_name=container_name,
120
141
  remove_previous=remove_previous,
142
+ no_platformio=no_platformio,
121
143
  )
122
144
  try:
123
145
  yield server
@@ -136,7 +158,9 @@ class Docker:
136
158
  def is_running() -> bool:
137
159
  from fastled.docker_manager import DockerManager
138
160
 
139
- return DockerManager.is_running()
161
+ ok: bool
162
+ ok, _ = DockerManager.is_running()
163
+ return ok
140
164
 
141
165
  @staticmethod
142
166
  def is_container_running(container_name: str | None = None) -> bool:
@@ -151,186 +175,10 @@ class Docker:
151
175
  @staticmethod
152
176
  def purge() -> None:
153
177
  from fastled.docker_manager import DockerManager
154
- from fastled.settings import IMAGE_NAME
155
178
 
156
179
  docker_mgr = DockerManager()
157
180
  docker_mgr.purge(image_name=IMAGE_NAME)
158
181
 
159
- @staticmethod
160
- def build_from_github(
161
- url: str = "https://github.com/fastled/fastled",
162
- output_dir: Path | str = Path(".cache/fastled"),
163
- ) -> str:
164
- """Build the FastLED WASM compiler Docker image from a GitHub repository.
165
-
166
- Args:
167
- url: GitHub repository URL (default: https://github.com/fastled/fastled)
168
- output_dir: Directory to clone the repo into (default: .cache/fastled)
169
-
170
- Returns:
171
- Container name.
172
- """
173
-
174
- from fastled.docker_manager import DockerManager
175
- from fastled.settings import CONTAINER_NAME, IMAGE_NAME
176
-
177
- if isinstance(output_dir, str):
178
- output_dir = Path(output_dir)
179
-
180
- # Create output directory if it doesn't exist
181
- output_dir.mkdir(parents=True, exist_ok=True)
182
-
183
- git_dir = output_dir / ".git"
184
- library_properties = output_dir / "library.properties"
185
-
186
- git_dir_exists = git_dir.exists()
187
- library_properties_exists = library_properties.exists()
188
- library_properties_text = (
189
- library_properties.read_text().strip() if library_properties_exists else ""
190
- )
191
-
192
- already_exists = (
193
- git_dir_exists
194
- and library_properties_exists
195
- and "FastLED" in library_properties_text
196
- )
197
- if git_dir_exists and not already_exists:
198
- if ".cache/fastled" in str(output_dir.as_posix()):
199
- shutil.rmtree(output_dir)
200
- already_exists = False
201
- else:
202
- raise ValueError(
203
- f"Output directory {output_dir} already exists but does not appear to be a FastLED repository."
204
- )
205
-
206
- # Clone or update the repository
207
- if already_exists:
208
- print(f"Updating existing repository in {output_dir}")
209
- # Reset local changes and move HEAD back to handle force pushes
210
- subprocess.run(
211
- ["git", "reset", "--hard", "HEAD~10"],
212
- cwd=output_dir,
213
- check=False,
214
- capture_output=True, # Suppress output of reset
215
- )
216
- subprocess.run(
217
- ["git", "pull", "origin", "master"], cwd=output_dir, check=True
218
- )
219
- else:
220
- print(f"Cloning {url} into {output_dir}")
221
- subprocess.run(
222
- ["git", "clone", "--depth", "1", url, str(output_dir)], check=True
223
- )
224
-
225
- dockerfile_path = (
226
- output_dir / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
227
- )
228
-
229
- if not dockerfile_path.exists():
230
- raise FileNotFoundError(
231
- f"Dockerfile not found at {dockerfile_path}. "
232
- "This may not be a valid FastLED repository."
233
- )
234
-
235
- docker_mgr = DockerManager()
236
-
237
- platform_tag = ""
238
- # if "arm" in docker_mgr.architecture():
239
- if (
240
- "arm"
241
- in subprocess.run(["uname", "-m"], capture_output=True).stdout.decode()
242
- ):
243
- platform_tag = "-arm64"
244
-
245
- # Build the image
246
- docker_mgr.build_image(
247
- image_name=IMAGE_NAME,
248
- tag="main",
249
- dockerfile_path=dockerfile_path,
250
- build_context=output_dir,
251
- build_args={"NO_PREWARM": "1"},
252
- platform_tag=platform_tag,
253
- )
254
-
255
- # Run the container and return it
256
- container = docker_mgr.run_container_detached(
257
- image_name=IMAGE_NAME,
258
- tag="main",
259
- container_name=CONTAINER_NAME,
260
- command=None, # Use default command from Dockerfile
261
- volumes=None, # No volumes needed for build
262
- ports=None, # No ports needed for build
263
- remove_previous=True, # Remove any existing container
264
- )
265
-
266
- return container.name # Todo, create an external docker container api.
267
-
268
- @staticmethod
269
- def build_from_fastled_repo(
270
- project_root: Path | str = Path("."),
271
- interactive: bool = False,
272
- sketch_folder: Path | None = None,
273
- ) -> CompileServer:
274
- """Build the FastLED WASM compiler Docker image, which will be tagged as "main".
275
-
276
- Args:
277
- project_root: Path to the FastLED project root directory
278
- platform_tag: Optional platform tag (e.g. "-arm64" for ARM builds)
279
-
280
- Returns:
281
- The string name of the docker container.
282
- """
283
- from fastled.docker_manager import DockerManager
284
- from fastled.settings import CONTAINER_NAME, IMAGE_NAME
285
-
286
- project_root = Path(project_root)
287
- if interactive:
288
- if sketch_folder is None:
289
- sketch_folder = project_root / "examples" / "wasm"
290
- else:
291
- if sketch_folder is not None:
292
- raise ValueError(
293
- "Cannot specify sketch_folder when not in interactive mode."
294
- )
295
- if isinstance(project_root, str):
296
- project_root = Path(project_root)
297
-
298
- dockerfile_path = (
299
- project_root / "src" / "platforms" / "wasm" / "compiler" / "Dockerfile"
300
- )
301
- docker_mgr = DockerManager()
302
- platform_tag = ""
303
- # if "arm" in docker_mgr.architecture():
304
- if (
305
- "arm"
306
- in subprocess.run(["uname", "-m"], capture_output=True).stdout.decode()
307
- ):
308
- platform_tag = "-arm64"
309
-
310
- # if image exists, remove it
311
- docker_mgr.purge(image_name=IMAGE_NAME)
312
-
313
- # Build the image
314
- docker_mgr.build_image(
315
- image_name=IMAGE_NAME,
316
- tag="main",
317
- dockerfile_path=dockerfile_path,
318
- build_context=project_root,
319
- build_args={"NO_PREWARM": "1"},
320
- platform_tag=platform_tag,
321
- )
322
-
323
- out: CompileServer = CompileServer(
324
- container_name=CONTAINER_NAME,
325
- interactive=interactive,
326
- auto_updates=False,
327
- mapped_dir=sketch_folder,
328
- auto_start=True,
329
- remove_previous=True,
330
- )
331
-
332
- return out
333
-
334
182
 
335
183
  class Tools:
336
184
  @staticmethod
@@ -370,14 +218,23 @@ class Test:
370
218
  def spawn_http_server(
371
219
  directory: Path | str = Path("."),
372
220
  port: int | None = None,
221
+ compile_server_port: int | None = None,
373
222
  open_browser: bool = True,
223
+ app: bool = False,
224
+ enable_https: bool = False, # Default to HTTP for tests (tests use http:// URLs)
374
225
  ) -> Process:
375
- from fastled.open_browser import open_browser_process
226
+ from fastled.open_browser import spawn_http_server
376
227
 
228
+ compile_server_port = compile_server_port or -1
377
229
  if isinstance(directory, str):
378
230
  directory = Path(directory)
379
- proc: Process = open_browser_process(
380
- directory, port=port, open_browser=open_browser
231
+ proc: Process = spawn_http_server(
232
+ directory,
233
+ port=port,
234
+ compile_server_port=compile_server_port,
235
+ open_browser=open_browser,
236
+ app=app,
237
+ enable_https=enable_https,
381
238
  )
382
239
  return proc
383
240
 
@@ -385,9 +242,11 @@ class Test:
385
242
  __all__ = [
386
243
  "Api",
387
244
  "Test",
388
- "Build",
389
245
  "CompileServer",
390
246
  "CompileResult",
391
247
  "CompileServerError",
392
248
  "BuildMode",
249
+ "FileResponse",
250
+ "DOCKER_FILE",
251
+ "__version__",
393
252
  ]
fastled/__main__.py ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ FastLED Package Main Entry Point
4
+ Enables running the package as: python -m fastled
5
+ """
6
+
7
+ import sys
8
+
9
+ from fastled.cli import main
10
+
11
+ if __name__ == "__main__":
12
+ # Pass execution to the main function from cli.py
13
+ # This enables 'python -m fastled' to work the same as 'fastled' command
14
+ sys.exit(main())
fastled/__version__.py ADDED
@@ -0,0 +1,6 @@
1
+ # IMPORTANT! There's a bug in github which will REJECT any version update
2
+ # that has any other change in the repo. Please bump the version as the
3
+ # ONLY change in a commit, or else the pypi update and the release will fail.
4
+ __version__ = "1.4.50"
5
+
6
+ __version_url_latest__ = "https://raw.githubusercontent.com/zackees/fastled-wasm/refs/heads/main/src/fastled/__version__.py"
fastled/app.py CHANGED
@@ -2,18 +2,21 @@
2
2
  Uses the latest wasm compiler image to compile the FastLED sketch.
3
3
  """
4
4
 
5
- import argparse
5
+ import os
6
6
  import sys
7
7
  import time
8
8
  from pathlib import Path
9
9
 
10
10
  from fastled.client_server import run_client_server
11
11
  from fastled.compile_server import CompileServer
12
+ from fastled.emoji_util import EMO
12
13
  from fastled.filewatcher import file_watcher_set
13
- from fastled.parse_args import parse_args
14
+ from fastled.parse_args import Args, parse_args
15
+ from fastled.settings import DEFAULT_URL
16
+ from fastled.sketch import find_sketch_directories, looks_like_fastled_repo
14
17
 
15
18
 
16
- def run_server(args: argparse.Namespace) -> int:
19
+ def run_server(args: Args) -> int:
17
20
  interactive = args.interactive
18
21
  auto_update = args.auto_update
19
22
  mapped_dir = Path(args.directory).absolute() if args.directory else None
@@ -25,6 +28,8 @@ def run_server(args: argparse.Namespace) -> int:
25
28
  auto_updates=auto_update,
26
29
  mapped_dir=mapped_dir,
27
30
  auto_start=True,
31
+ remove_previous=args.clear,
32
+ no_platformio=args.no_platformio,
28
33
  )
29
34
 
30
35
  if not interactive:
@@ -44,41 +49,129 @@ def run_server(args: argparse.Namespace) -> int:
44
49
 
45
50
 
46
51
  def main() -> int:
52
+ from fastled import __version__
53
+ from fastled.select_sketch_directory import select_sketch_directory
54
+
47
55
  args = parse_args()
56
+
57
+ if args.emsdk_headers:
58
+ import httpx
59
+
60
+ out_path = args.emsdk_headers
61
+ base_url = args.web if isinstance(args.web, str) else DEFAULT_URL
62
+ try:
63
+ response = httpx.get(f"{base_url}/headers/emsdk")
64
+ if response.status_code == 200:
65
+ Path(out_path).parent.mkdir(parents=True, exist_ok=True)
66
+ with open(out_path, "wb") as f:
67
+ f.write(response.content)
68
+ print(f"{EMO('✅','SUCCESS:')} EMSDK headers exported to {out_path}")
69
+ return 0
70
+ else:
71
+ print(
72
+ f"{EMO('❌','ERROR:')} Failed to export EMSDK headers: HTTP {response.status_code}"
73
+ )
74
+ return 1
75
+ except KeyboardInterrupt:
76
+ print("\nExiting from main...")
77
+ return 1
78
+ except Exception as e:
79
+ print(f"{EMO('❌','ERROR:')} Exception: {e}")
80
+ return 1
81
+
82
+ # Handle --install command early
83
+ if args.install:
84
+ from fastled.install.main import fastled_install
85
+
86
+ result = fastled_install(
87
+ dry_run=args.dry_run, no_interactive=args.no_interactive
88
+ )
89
+ return 0 if result else 1
90
+
48
91
  interactive: bool = args.interactive
49
- server: str | CompileServer | None = args.server
92
+ has_server = args.server
50
93
  update: bool = args.update
51
94
  build: bool = args.build
52
95
  just_compile: bool = args.just_compile
53
96
  # directory: Path | None = Path(args.directory).absolute() if args.directory else None
54
97
  directory: Path | None = Path(args.directory) if args.directory else None
55
-
56
- # broken for now
57
- if directory is None and interactive:
58
- # if examples/wasm exists
59
- if Path("examples/wasm").exists():
60
- print(f"Using {Path('examples/wasm')} as the sketch directory")
61
- directory = Path("examples/wasm").absolute()
98
+ cwd_looks_like_fastled_repo = looks_like_fastled_repo()
99
+
100
+ # now it is safe to print out the version
101
+ print(f"FastLED version: {__version__}")
102
+
103
+ # Print current working directory
104
+ print(f"Current working directory: {os.getcwd()}")
105
+
106
+ # Check if Playwright browsers are installed
107
+ playwright_dir = Path.home() / ".fastled" / "playwright"
108
+ if playwright_dir.exists() and any(playwright_dir.iterdir()):
109
+ print(f"{EMO('🎭', '*')} Playwright browsers available at: {playwright_dir}")
110
+
111
+ # Resolve some of the last interactive arguments
112
+ # 1. If interactive is set and the sketch directory is not given,
113
+ # then prompt the user for a sketch directory.
114
+ # 2. Tell the user they can use --server --interactive to
115
+ # skip this prompt.
116
+ if interactive and cwd_looks_like_fastled_repo and directory is None:
117
+ answer = input(
118
+ "No sketch directory selected, would you like to select one? (y/n): "
119
+ )
120
+ if answer.lower()[:1] == "y" or answer.lower() == "":
121
+ sketch_list: list[Path] = find_sketch_directories()
122
+ if sketch_list:
123
+ maybe_dir: str | None = select_sketch_directory(
124
+ sketch_list, cwd_looks_like_fastled_repo, is_followup=True
125
+ )
126
+ if maybe_dir is not None:
127
+ directory = Path(maybe_dir)
128
+ if not directory.exists():
129
+ print(
130
+ f"Directory {directory} does not exist, entering interactive mode without project mapped in."
131
+ )
132
+ directory = None
62
133
 
63
134
  if update:
64
135
  # Force auto_update to ensure update check happens
65
- compile_server = CompileServer(interactive=False, auto_updates=True)
136
+ compile_server = CompileServer(
137
+ interactive=False, auto_updates=True, no_platformio=args.no_platformio
138
+ )
66
139
  compile_server.stop()
67
140
  print("Finished updating.")
68
141
  return 0
69
142
 
70
143
  if build:
71
- try:
72
- file_watcher_set(False)
73
- project_root = Path(".").absolute()
74
- print(f"Building Docker image at {project_root}")
75
- from fastled import Api, Docker
144
+ print("Building is disabled")
145
+ build = False
146
+
147
+ if interactive:
148
+ # raise NotImplementedError("Building is not yet supported.")
149
+ file_watcher_set(False)
150
+ # project_root = Path(".").absolute()
151
+ # print(f"Building Docker image at {project_root}")
152
+ from fastled import Api
153
+
154
+ server: CompileServer = CompileServer(
155
+ interactive=interactive,
156
+ auto_updates=False,
157
+ mapped_dir=directory,
158
+ auto_start=False,
159
+ remove_previous=args.clear,
160
+ no_platformio=args.no_platformio,
161
+ )
162
+
163
+ server.start(wait_for_startup=False)
76
164
 
77
- server = Docker.build_from_fastled_repo(
78
- project_root=project_root, interactive=interactive
79
- )
80
- assert isinstance(server, CompileServer)
165
+ try:
166
+ while server.process_running():
167
+ # wait for ctrl-c
168
+ time.sleep(0.1)
169
+ except KeyboardInterrupt:
170
+ print("\nExiting from server...")
171
+ server.stop()
172
+ return 0
81
173
 
174
+ try:
82
175
  if interactive:
83
176
  server.stop()
84
177
  return 0
@@ -90,20 +183,22 @@ def main() -> int:
90
183
  return 0
91
184
 
92
185
  print("Running server")
186
+
93
187
  with Api.live_client(
94
188
  auto_updates=False,
95
189
  sketch_directory=directory,
96
190
  host=server,
97
191
  auto_start=True,
98
192
  keep_running=not just_compile,
99
- ) as client:
100
- print(f"Exited client {client.url()}")
101
- print(f"Exiting {server.name}")
193
+ ) as _:
194
+ while True:
195
+ time.sleep(0.2) # wait for user to exit
102
196
  except KeyboardInterrupt:
103
197
  print("\nExiting from client...")
198
+ server.stop()
104
199
  return 1
105
200
 
106
- if server:
201
+ if has_server:
107
202
  print("Running in server only mode.")
108
203
  return run_server(args)
109
204
  else:
@@ -114,12 +209,14 @@ def main() -> int:
114
209
  if __name__ == "__main__":
115
210
  # Note that the entry point for the exe is in cli.py
116
211
  try:
117
- sys.argv.append("-b")
118
- sys.argv.append("examples/wasm")
212
+ # sys.argv.append("-i")
213
+ # sys.argv.append("-b")
214
+ # sys.argv.append("examples/wasm")
119
215
  # sys.argv.append()
120
216
  import os
121
217
 
122
218
  os.chdir("../fastled")
219
+ sys.argv.append("examples/FxWave2d")
123
220
  sys.exit(main())
124
221
  except KeyboardInterrupt:
125
222
  print("\nExiting from main...")