diff --git a/.fleet/receipt.json b/.fleet/receipt.json deleted file mode 100644 index 68e96b8..0000000 --- a/.fleet/receipt.json +++ /dev/null @@ -1,29 +0,0 @@ -// Project generated by Kotlin Multiplatform Wizard -{ - "spec": { - "template_id": "kmt", - "targets": { - "android": { - "ui": [ - "compose" - ] - }, - "ios": { - "ui": [ - "compose" - ] - }, - "desktop": { - "ui": [ - "compose" - ] - }, - "web": { - "ui": [ - "compose" - ] - } - } - }, - "timestamp": "2025-02-08T16:29:50.359091746Z" -} \ No newline at end of file diff --git a/.github/scripts/pypi/build_wheel.py b/.github/scripts/pypi/build_wheel.py new file mode 100644 index 0000000..b59f0a1 --- /dev/null +++ b/.github/scripts/pypi/build_wheel.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +"""Assemble the platform wheel that carries the native `tcl` binary (publish-pypi.yml). + + python3 .github/scripts/pypi/build_wheel.py --binary toolchain/build/native/nativeCompile/tcl --out dist + +Adapted from pypackpack's .github/scripts/pypi/build_wheel.py (pypackpack #53). The wheel holds: + toolchain_lite/__init__.py, __main__.py toolchain/src/cliMain/python/ (`python -m toolchain_lite`) + toolchain_lite-.data/scripts/tcl the native binary (tcl.exe on Windows) + dist-info: METADATA from pyproject.toml's [project], LICENSE, WHEEL, RECORD + +The platform tag is read from the binary, never assumed: the highest GLIBC_x.y symbol it needs on +Linux (manylinux_x_y_), its LC_BUILD_VERSION minos on macOS (macosx___), +win_amd64 / win_arm64 on Windows. On Linux every NEEDED library must be in ALLOWED_LINUX_LIBS. +""" +from __future__ import annotations + +import argparse +import base64 +import hashlib +import platform +import re +import subprocess +import sys +import tomllib +import zipfile +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[3] +PACKAGE_SRC = ROOT / "toolchain/src/cliMain/python" +IMPORT_NAME = "toolchain_lite" +BINARY = "tcl" +# glibc's own libraries plus libz, which every glibc distribution ships and Native Image links. +ALLOWED_LINUX_LIBS = { + "libc.so.6", "libm.so.6", "libdl.so.2", "libpthread.so.0", "librt.so.1", "libz.so.1", + "ld-linux-x86-64.so.2", "ld-linux-aarch64.so.1", +} +FIXED_DATE = (1980, 1, 1, 0, 0, 0) + + +def run(*cmd: str) -> str: + return subprocess.run(cmd, check=True, capture_output=True, text=True).stdout + + +def linux_tag(binary: Path) -> str: + needed = set(re.findall(r"\(NEEDED\)\s+Shared library: \[([^\]]+)\]", run("readelf", "-d", str(binary)))) + extra = needed - ALLOWED_LINUX_LIBS + if extra: + sys.exit(f"{binary} needs libraries a manylinux wheel may not assume: {sorted(extra)}") + versions = {tuple(map(int, v)) for v in re.findall(r"GLIBC_(\d+)\.(\d+)", run("objdump", "-T", str(binary)))} + major, minor = max(versions) if versions else (2, 17) + machine = platform.machine().lower() + arch = {"amd64": "x86_64", "arm64": "aarch64"}.get(machine, machine) + return f"manylinux_{major}_{minor}_{arch}" + + +def macos_tag(binary: Path) -> str: + match = re.search(r"cmd LC_BUILD_VERSION.*?minos (\d+)\.(\d+)", run("otool", "-l", str(binary)), re.S) + if not match: + sys.exit(f"{binary} has no LC_BUILD_VERSION; cannot tell its minimum macOS") + major, minor = int(match[1]), int(match[2]) + if major >= 11: + minor = 0 # pip matches macosx_11+ tags on the major version only + arch = "arm64" if platform.machine() == "arm64" else "x86_64" + return f"macosx_{major}_{minor}_{arch}" + + +def windows_tag() -> str: + return "win_arm64" if platform.machine().lower() in ("arm64", "aarch64") else "win_amd64" + + +def platform_tag(binary: Path) -> str: + if sys.platform.startswith("linux"): + return linux_tag(binary) + if sys.platform == "darwin": + return macos_tag(binary) + if sys.platform == "win32": + return windows_tag() + sys.exit(f"no wheel platform tag for {sys.platform}") + + +def metadata(project: dict) -> str: + lines = [ + "Metadata-Version: 2.4", + f"Name: {project['name']}", + f"Version: {project['version']}", + f"Summary: {project['description']}", + ] + for author in project.get("authors", []): + lines.append(f"Author-email: {author['name']} <{author['email']}>") + lines.append(f"License-Expression: {project['license']}") + lines += [f"License-File: {f}" for f in project.get("license-files", [])] + lines += [f"Classifier: {c}" for c in project.get("classifiers", [])] + if project.get("keywords"): + lines.append(f"Keywords: {','.join(project['keywords'])}") + lines.append(f"Requires-Python: {project['requires-python']}") + lines += [f"Project-URL: {label}, {url}" for label, url in project.get("urls", {}).items()] + lines.append("Description-Content-Type: text/markdown") + readme = (ROOT / project["readme"]).read_text(encoding="utf-8") + return "\n".join(lines) + "\n\n" + readme + + +def record_line(arcname: str, data: bytes) -> str: + digest = base64.urlsafe_b64encode(hashlib.sha256(data).digest()).rstrip(b"=").decode() + return f"{arcname},sha256={digest},{len(data)}" + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--binary", type=Path, required=True) + parser.add_argument("--out", type=Path, required=True) + args = parser.parse_args() + + project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["project"] + name, version = project["name"], project["version"] + dist = re.sub(r"[-_.]+", "_", name).lower() # wheel and dist-info names use the normalized form + tag = f"py3-none-{platform_tag(args.binary)}" + dist_info = f"{dist}-{version}.dist-info" + exe = f"{BINARY}.exe" if sys.platform == "win32" else BINARY + + files: list[tuple[str, bytes, int]] = [] # (arcname, data, unix mode) + for source in sorted(PACKAGE_SRC.glob("*.py")): + files.append((f"{IMPORT_NAME}/{source.name}", source.read_bytes(), 0o644)) + files.append((f"{dist}-{version}.data/scripts/{exe}", args.binary.read_bytes(), 0o755)) + files.append((f"{dist_info}/METADATA", metadata(project).encode(), 0o644)) + for license_file in project.get("license-files", []): + files.append((f"{dist_info}/licenses/{license_file}", (ROOT / license_file).read_bytes(), 0o644)) + scripts = "".join(f"{k} = {v}\n" for k, v in project.get("scripts", {}).items()) + if scripts: + files.append((f"{dist_info}/entry_points.txt", f"[console_scripts]\n{scripts}".encode(), 0o644)) + wheel = f"Wheel-Version: 1.0\nGenerator: toolchain build_wheel.py\nRoot-Is-Purelib: false\nTag: {tag}\n" + files.append((f"{dist_info}/WHEEL", wheel.encode(), 0o644)) + record = "\n".join(record_line(a, d) for a, d, _ in files) + f"\n{dist_info}/RECORD,,\n" + files.append((f"{dist_info}/RECORD", record.encode(), 0o644)) + + args.out.mkdir(parents=True, exist_ok=True) + path = args.out / f"{dist}-{version}-{tag}.whl" + with zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED) as archive: + for arcname, data, mode in files: + info = zipfile.ZipInfo(arcname, FIXED_DATE) + info.external_attr = (0o100000 | mode) << 16 + info.compress_type = zipfile.ZIP_DEFLATED + archive.writestr(info, data) + print(path) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/scripts/pypi/smoke_wheel.py b/.github/scripts/pypi/smoke_wheel.py new file mode 100644 index 0000000..92971bf --- /dev/null +++ b/.github/scripts/pypi/smoke_wheel.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +"""Install a built wheel into a fresh venv and check that what a PyPI user runs works. + + python3 .github/scripts/pypi/smoke_wheel.py dist/toolchain_lite--.whl + +Adapted from pypackpack's smoke_wheel.py (pypackpack #53). Fails (exit 1) unless, from that venv: + 1. `tcl --help` exits 0 and prints the usage line; + 2. `tcl --version` and `python -m toolchain_lite --version` print "tcl "; + 3. `tcl install six` in an empty directory creates a pyproject.toml that depends on six (a real + install, which needs uv: tcl finds it on PATH or pypackpack downloads it into ~/.pypackpack/uv). +""" +from __future__ import annotations + +import os +import subprocess +import sys +import tempfile +import tomllib +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[3] + + +def check(cmd: list[str], expect: str | None, cwd: Path | None = None) -> None: + result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True) + shown = " ".join(Path(c).name if i == 0 else c for i, c in enumerate(cmd)) + if result.returncode != 0 or (expect and expect not in result.stdout): + print(f"FAIL {shown}: exit {result.returncode}\n{result.stdout}{result.stderr}") + sys.exit(1) + print(f"ok {shown}") + + +def main() -> int: + wheel = Path(sys.argv[1]).resolve() + version = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["project"]["version"] + with tempfile.TemporaryDirectory() as tmp: + venv = Path(tmp) / "venv" + subprocess.run([sys.executable, "-m", "venv", str(venv)], check=True) + bin_dir = venv / ("Scripts" if os.name == "nt" else "bin") + exe = ".exe" if os.name == "nt" else "" + python = bin_dir / f"python{exe}" + subprocess.run([str(python), "-m", "pip", "install", "--quiet", "--no-index", str(wheel)], check=True) + + tcl = str(bin_dir / f"tcl{exe}") + check([tcl, "--help"], "Usage: tcl install ") + expected = f"tcl {version}" + check([tcl, "--version"], expected) + check([str(python), "-m", "toolchain_lite", "--version"], expected) + + work = Path(tmp) / "work" + work.mkdir() + check([tcl, "install", "six"], None, cwd=work) + pyproject = work / "pyproject.toml" + if not pyproject.is_file() or "six" not in pyproject.read_text(encoding="utf-8"): + print("FAIL tcl install six: no pyproject.toml that depends on six") + return 1 + print("ok tcl install six wrote pyproject.toml") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/release/README.md b/.github/scripts/release/README.md similarity index 53% rename from tools/release/README.md rename to .github/scripts/release/README.md index ed135b6..697c383 100644 --- a/tools/release/README.md +++ b/.github/scripts/release/README.md @@ -7,20 +7,18 @@ between runs, and any existing `release` (e.g. a stale one from an older workflo ignored and overwritten. 1. Every push to `develop` triggers `.github/workflows/release-sync.yml`, which runs - `tools/release/sync-release.sh --push`. It rebuilds `release` from scratch as exactly + `.github/scripts/release/sync-release.sh --push`. It rebuilds `release` from scratch as exactly one commit (`Release: sync from develop `) whose parent is that develop commit and whose tree is the develop tree minus the files below. This happens even when nothing is dropped. It is a no-op only if `release` already has that tree and that parent. The push uses `--force-with-lease` pinned to the remote sha the run observed. 2. The workflow opens (or updates) a pull request `release` -> `main` with the default `GITHUB_TOKEN`. This needs the repository setting *Actions -> General -> Allow GitHub - Actions to create and approve pull requests*. A PR opened with `GITHUB_TOKEN` - triggers no workflows, so `main-source-guard` would never run on it; the workflow - therefore sets the `only-release-into-main` commit status on the release commit - itself, which satisfies the required check. No PAT is needed; an optional + Actions to create and approve pull requests*. No PAT is needed; an optional `RELEASE_PR_TOKEN` secret is used for the PR step when present. -3. Merging that PR is the only way to change `main`. `main-source-guard.yml` fails - any PR into `main` whose head is not `release`. +3. Merging that PR is the only way to change `main`. The maintainer protects `main` in the + repository settings (locked) and merges the `release` PR after checking that its head is + `release` (maintainer decision 2026-10-03: settings only, no scripts or workflows for it). 4. On push to `main`, `pages.yml` deploys `docs/guide/` to GitHub Pages. ## What is dropped on release @@ -33,19 +31,15 @@ Only Markdown is ever dropped. ## Local use - tools/release/sync-release.sh --dry-run # list paths that would be dropped - tools/release/sync-release.sh # regenerate local release branch - tools/release/sync-release.sh --push # also push to origin - tools/release/test-sync-release.sh # tests (throwaway repo in .tmp/) + .github/scripts/release/sync-release.sh --dry-run # list paths that would be dropped + .github/scripts/release/sync-release.sh # regenerate local release branch + .github/scripts/release/sync-release.sh --push # also push to origin + .github/scripts/release/test-sync-release.sh # tests (throwaway repo in .tmp/) The script uses plumbing and a private index, so your working tree, index and HEAD are untouched. It refuses to run while `release` is checked out. ## Protecting main - tools/release/protect-main.sh # print what would be applied - tools/release/protect-main.sh --apply # apply via gh api (needs admin) - -This requires a pull request, blocks force-push and deletion. Classic protection cannot -restrict a PR's source branch, so add the check `only-release-into-main` as required -(the script does; the workflow must have run once first). +`main`'s protection is set by the maintainer in the repository settings (the branch is locked; +the maintainer merges the `release` pull request). Agents do not script or change it. diff --git a/tools/release/sync-release.sh b/.github/scripts/release/sync-release.sh similarity index 100% rename from tools/release/sync-release.sh rename to .github/scripts/release/sync-release.sh diff --git a/tools/release/test-sync-release.sh b/.github/scripts/release/test-sync-release.sh similarity index 98% rename from tools/release/test-sync-release.sh rename to .github/scripts/release/test-sync-release.sh index cba1d31..cb7e18d 100755 --- a/tools/release/test-sync-release.sh +++ b/.github/scripts/release/test-sync-release.sh @@ -2,7 +2,7 @@ # Tests for sync-release.sh. Builds a throwaway repo under /.tmp/. set -u HERE="$(cd "$(dirname "$0")" && pwd)" -ROOT="$(cd "$HERE/../.." && pwd)" +ROOT="$(cd "$HERE/../../.." && pwd)" # .github/scripts/release -> repository root SYNC="$HERE/sync-release.sh" SCRATCH="$ROOT/.tmp/release-sync-test.$$" FAILS=0; PASSES=0 diff --git a/.github/workflows/main-source-guard.yml b/.github/workflows/main-source-guard.yml deleted file mode 100644 index 4eb5d20..0000000 --- a/.github/workflows/main-source-guard.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Main source guard - -# Make the job "only-release-into-main" a required status check on main. -on: - pull_request: - branches: [main] - types: [opened, reopened, synchronize, edited] - -permissions: - contents: read - -jobs: - only-release-into-main: - runs-on: ubuntu-latest - steps: - - name: Require head branch "release" - env: - HEAD_REF: ${{ github.head_ref }} - HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} - run: | - if [ "$HEAD_REF" != "release" ] || [ "$HEAD_REPO" != "${{ github.repository }}" ]; then - echo "::error::PRs into main must come from the release branch of this repository (got '$HEAD_REPO:$HEAD_REF')." - exit 1 - fi diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml new file mode 100644 index 0000000..3c3973e --- /dev/null +++ b/.github/workflows/publish-pypi.yml @@ -0,0 +1,139 @@ +name: Publish to PyPI + +# toolchain-lite (the PyPI distribution of tcl). Adapted from pypackpack's publish-pypi.yml +# (pypackpack #53), with the same gates. Publishing a GitHub Release `toolchain-lite-v` +# (#71: bare `v*` tags belong to the Gradle plugin, which this repository also releases) builds the native +# tcl on each platform, wraps each binary in a wheel (.github/scripts/pypi/build_wheel.py), installs +# and smoke-tests every wheel (smoke_wheel.py), and only then uploads them all through trusted +# publishing (environment `pypi`, no token). A pull request that touches the publishing files, or a +# manual run, does everything except the upload. +# +# A published Release, not a pushed `v*` tag: a PyPI version can never be uploaded twice, so the +# trigger is a deliberate act. No sdist: building needs a JDK and GraalVM, so an sdist would install +# the launcher without the binary. +# +# tcl links pypackpack's packpack library from mavenLocal, so each wheel job first publishes it +# from pypackpack's develop branch, as test.yml does. +on: + release: + types: [published] + pull_request: + paths: + - .github/workflows/publish-pypi.yml + - .github/scripts/pypi/** + - pyproject.toml + - docs/pypi/** + - toolchain/src/cliMain/** + - toolchain/build.gradle.kts + workflow_dispatch: + +permissions: + contents: read + +# A newer push supersedes a dry run; a release run is never cancelled. +concurrency: + group: publish-pypi-${{ github.ref }} + cancel-in-progress: ${{ github.event_name != 'release' }} + +jobs: + version: + # Another product's Release (the Gradle plugin's `v*`) skips this workflow; skipped jobs skip their dependants. + if: github.event_name != 'release' || startsWith(github.event.release.tag_name, 'toolchain-lite-v') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Tag, pyproject.toml and tcl agree; the version is new on PyPI + env: + TAG: ${{ github.event.release.tag_name }} + IS_RELEASE: ${{ github.event_name == 'release' }} + run: | + py=$(python3 -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])') + cli=$(sed -n 's/^val tclVersion = "\(.*\)"$/\1/p' toolchain/build.gradle.kts) + echo "pyproject.toml: $py toolchain/build.gradle.kts tclVersion: $cli tag: ${TAG:-none (dry run)}" + if [ -z "$cli" ] || [ "$py" != "$cli" ]; then + echo "::error::pyproject.toml ($py) and toolchain/build.gradle.kts tclVersion ($cli) must carry the same version"; exit 1 + fi + if [ "$IS_RELEASE" = true ] && [ "$TAG" != "toolchain-lite-v$py" ]; then + echo "::error::release tag '$TAG' is not 'toolchain-lite-v$py'"; exit 1 + fi + if curl -fsS -o /dev/null "https://pypi.org/pypi/toolchain-lite/$py/json"; then + if [ "$IS_RELEASE" = true ]; then echo "::error::toolchain-lite $py is already on PyPI"; exit 1; fi + echo "::warning::toolchain-lite $py is already on PyPI; bump the version before releasing" + fi + + wheel: + needs: version + name: wheel (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + # ubuntu-22.04: the oldest glibc (2.35) a hosted runner offers, so the widest manylinux tag. + os: [ubuntu-22.04, ubuntu-22.04-arm, macos-latest, windows-latest] + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v4 + + - uses: graalvm/setup-graalvm@v1 + with: + java-version: "21" + distribution: graalvm-community + github-token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - uses: gradle/actions/setup-gradle@v4 + + - uses: actions/checkout@v4 + with: + repository: thisisthepy/pypackpack + ref: develop + path: .ci/pypackpack + + - name: packpack into mavenLocal + working-directory: .ci/pypackpack + run: ./gradlew --no-daemon :packpack:publishToMavenLocal + + - name: Native image + run: ./gradlew --no-daemon :toolchain:nativeCompile + + - name: Wheel + run: | + exe=toolchain/build/native/nativeCompile/tcl + [ "$RUNNER_OS" = Windows ] && exe="$exe.exe" + python .github/scripts/pypi/build_wheel.py --binary "$exe" --out dist + + - name: Install and smoke-test the wheel + run: python .github/scripts/pypi/smoke_wheel.py dist/*.whl + + - uses: actions/upload-artifact@v4 + with: + name: wheel-${{ matrix.os }} + path: dist/*.whl + if-no-files-found: error + + publish: + if: github.event_name == 'release' + needs: wheel + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/project/toolchain-lite/ + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + pattern: wheel-* + merge-multiple: true + path: dist + - name: One wheel per platform + run: | + ls -la dist + test "$(ls dist/*.whl | wc -l)" -eq 4 + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.github/workflows/release-sync.yml b/.github/workflows/release-sync.yml index d411bb2..8914610 100644 --- a/.github/workflows/release-sync.yml +++ b/.github/workflows/release-sync.yml @@ -10,7 +10,6 @@ on: permissions: contents: write pull-requests: write - statuses: write concurrency: group: release-sync @@ -30,7 +29,7 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" # Not used as a base (release is regenerated); the script reads the # remote sha itself for --force-with-lease. - bash tools/release/sync-release.sh --source "${GITHUB_SHA}" --push + bash .github/scripts/release/sync-release.sh --source "${GITHUB_SHA}" --push - name: Open or update PR release -> main env: @@ -44,24 +43,10 @@ jobs: echo "release already equals main; nothing to PR"; exit 0 fi title="Release: merge release into main" - body="Automated sync of \`develop\` (${GITHUB_SHA::7}) into \`release\`. Markdown outside README.md and docs/ subfolders is removed by tools/release/sync-release.sh." + body="Automated sync of \`develop\` (${GITHUB_SHA::7}) into \`release\`. Markdown outside README.md and docs/ subfolders is removed by .github/scripts/release/sync-release.sh." existing="$(gh pr list --head release --base main --state open --json number --jq '.[0].number // empty')" if [ -n "$existing" ]; then gh pr edit "$existing" --title "$title" --body "$body" else gh pr create --head release --base main --title "$title" --body "$body" fi - - # A PR opened with GITHUB_TOKEN triggers no workflows, so main-source-guard - # never runs on it. Report the guard's verdict for the release commit here: - # this job just generated it from develop, which is exactly what the guard - # requires. A status set with GITHUB_TOKEN satisfies a required check. - - name: Mark release as passing the main source guard - env: - GH_TOKEN: ${{ github.token }} - run: | - set -eu - if ! git rev-parse -q --verify refs/heads/release >/dev/null; then exit 0; fi - gh api "repos/${GITHUB_REPOSITORY}/statuses/$(git rev-parse release)" \ - -f state=success -f context=only-release-into-main \ - -f description="generated from develop ${GITHUB_SHA::7} by release-sync" diff --git a/.github/workflows/ios-e2e.yml b/.github/workflows/test-ios.yml similarity index 91% rename from .github/workflows/ios-e2e.yml rename to .github/workflows/test-ios.yml index 4414f24..82a9ca6 100644 --- a/.github/workflows/ios-e2e.yml +++ b/.github/workflows/test-ios.yml @@ -1,6 +1,6 @@ name: iOS e2e -# toolchain#22, iOS: usage-example's app on an arm64 iOS simulator runs Python with the stdlib and +# toolchain#22, iOS: sample's app on an arm64 iOS simulator runs Python with the stdlib and # Python.framework python-multiplatform puts into the .app, plus this plugin's python/ payload. # macOS minutes cost ~10x, so this runs only for iOS wiring changes, on develop and by hand, and is # informational (not a required check). Lead decision, 2026-10-03. @@ -9,12 +9,11 @@ on: branches: [develop] pull_request: paths: - - "usage-example/src/iosMain/**" - - "usage-example/build.gradle.kts" - - "usage-example/gradle/**" - - "tools/xcode/**" + - "sample/src/iosMain/**" + - "sample/build.gradle.kts" + - "sample/gradle/**" - "toolchain/src/main/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/**" - - ".github/workflows/ios-e2e.yml" + - ".github/workflows/test-ios.yml" workflow_dispatch: permissions: @@ -49,7 +48,7 @@ jobs: - uses: actions/cache@v4 with: path: ~/.konan - key: konan-${{ runner.os }}-${{ hashFiles('usage-example/gradle/libs.versions.toml') }} + key: konan-${{ runner.os }}-${{ hashFiles('sample/gradle/libs.versions.toml') }} - name: Publish packpack, the toolchain plugin and python-multiplatform (iOS simulator) run: | @@ -69,7 +68,7 @@ jobs: slice="$pmd/python-multiplatform/build/python-standalone/extracted/3.14.7/ios/Python.xcframework/ios-arm64_x86_64-simulator" # TODO(python-multiplatform#90): PYTHON_MULTIPLATFORM_DIR and the -framework Python link flags # are interim; the published plugin will stage Python.xcframework and its link options. - xcodebuild -project usage-example/src/iosMain/app.xcodeproj -target iosApp \ + xcodebuild -project sample/src/iosMain/app.xcodeproj -target iosApp \ -sdk iphonesimulator -configuration Debug \ ARCHS=arm64 ONLY_ACTIVE_ARCH=YES CODE_SIGNING_ALLOWED=NO \ SYMROOT="$GITHUB_WORKSPACE/build-ios" \ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e339413..33cd036 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,13 +1,13 @@ name: Test -# Every pull request and every push to develop runs the plugin's and tcl's tests, +# Every pull request and every push to develop runs the plugin's and the CLI's tests, # each in its own job (AGENTS.md section 8). Results are counted from the JUnit # XML, not from the log. # # Both modules depend on org.thisisthepy.python.multiplatform:packpack:0.1.0 from # mavenLocal, so each job first publishes it from pypackpack's develop branch. -# usage-example is its own build (toolchain#22, python-multiplatform's Kotlin), run -# by the consumer and desktop-e2e jobs with its own wrapper. +# sample/ is its own build (toolchain#22, #62; python-multiplatform's Kotlin), run by the +# consumer and e2e jobs with this repository's wrapper (../gradlew from sample/ = ./gradlew -p sample). on: pull_request: push: @@ -22,13 +22,17 @@ concurrency: jobs: test: - name: ${{ matrix.module }} + name: ${{ matrix.name }} runs-on: ubuntu-latest timeout-minutes: 40 strategy: fail-fast: false matrix: - module: [toolchain, tcl] + # Both live in :toolchain (#78): the plugin's `test` and tcl's `cliTest`, run as separate + # invocations (AGENTS.md section 8). + include: + - { name: toolchain, task: test } + - { name: tcl, task: cliTest } steps: - uses: actions/checkout@v4 @@ -55,8 +59,19 @@ jobs: working-directory: .ci/pypackpack run: ./gradlew :packpack:publishToMavenLocal --console=plain - - name: Test ${{ matrix.module }} - run: ./gradlew :${{ matrix.module }}:test --rerun --console=plain + - name: Test ${{ matrix.name }} + run: ./gradlew :toolchain:${{ matrix.task }} --rerun --console=plain + + - name: The plugin's publication carries no tcl + if: matrix.task == 'test' + run: | + ./gradlew :toolchain:jar :toolchain:generatePomFileForPluginMavenPublication --console=plain + jar=$(ls toolchain/build/libs/toolchain-*.jar | grep -v -- '-sources\|-javadoc' | head -1) + pom=toolchain/build/publications/pluginMaven/pom-default.xml + ls -la "$jar" "$pom" + if unzip -l "$jar" | grep -n "multiplatform/tcl/\|toolchain_lite"; then echo "::error::tcl classes are in the plugin jar (#78)"; exit 1; fi + if grep -n "tcl\|toolchain-lite\|clikt" "$pom"; then echo "::error::the plugin POM depends on tcl (#78)"; exit 1; fi + echo "plugin jar and POM carry no tcl" - name: Count results if: always() @@ -64,7 +79,7 @@ jobs: python3 - <<'PY' import glob, re t = f = e = s = 0 - for x in glob.glob("${{ matrix.module }}/build/test-results/test/*.xml"): + for x in glob.glob("toolchain/build/test-results/${{ matrix.task }}/*.xml"): m = re.search(r'tests="(\d+)" skipped="(\d+)" failures="(\d+)" errors="(\d+)"', open(x).read(4000)) t += int(m[1]); s += int(m[2]); f += int(m[3]); e += int(m[4]) print(f"tests={t} skipped={s} failures={f} errors={e}") @@ -74,12 +89,12 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: ${{ matrix.module }}-test-reports - path: ${{ matrix.module }}/build/reports/tests/test/ + name: ${{ matrix.name }}-test-reports + path: toolchain/build/reports/tests/${{ matrix.task }}/ # Unit tests run on Kotlin 2.x's stdlib, but a consumer runs the plugin on the kotlin-stdlib Gradle # embeds. pypackpack#31 broke every suspend call that way and no unit test could see it. This job is - # a real consumer: usage-example (its own build) with a real pip dependency installs, bundles, zips. + # a real consumer: sample (its own build) with a real pip dependency installs, bundles, zips. consumer: runs-on: ubuntu-latest timeout-minutes: 60 @@ -105,9 +120,9 @@ jobs: python-version: "3.14" - uses: astral-sh/setup-uv@v6 - # usage-example applies three things from mavenLocal: packpack (through the plugin), the + # sample applies three things from mavenLocal: packpack (through the plugin), the # toolchain plugin, and python-multiplatform's library and bindings plugin. Versions pinned in - # usage-example/gradle/libs.versions.toml (library 3.14.7-alpha01, plugin 3.13.0 until + # sample/gradle/libs.versions.toml (library 3.14.7-alpha01, plugin 3.13.0 until # python-multiplatform#70). - name: Publish packpack, the toolchain plugin and python-multiplatform to mavenLocal run: | @@ -122,9 +137,9 @@ jobs: (cd .ci/python-multiplatform && ./gradlew -p python-multiplatform-gradle-plugin publishToMavenLocal --console=plain) - name: Install, bundle and zip as a consumer - working-directory: usage-example + working-directory: sample run: | - ./gradlew installPythonDependencies buildPython packagePython \ + ../gradlew installPythonDependencies buildPython packagePython \ --console=plain > consumer.log 2>&1 || { cat consumer.log; exit 1; } cat consumer.log grep -q "iniconfig" consumer.log || { echo "the dependency was not installed"; exit 1; } @@ -179,11 +194,11 @@ jobs: (cd .ci/python-multiplatform && ./gradlew -p python-multiplatform-gradle-plugin publishToMavenLocal --console=plain) - name: Package the desktop app - working-directory: usage-example - run: ./gradlew createDistributable --console=plain + working-directory: sample + run: ../gradlew createDistributable --console=plain - name: Run the packaged app's Python, headless and without PYTHONHOME - working-directory: usage-example + working-directory: sample run: | set -euo pipefail app=$(find build/compose/binaries/main/app -maxdepth 3 -type f -path '*/bin/*' | head -n 1) @@ -238,8 +253,8 @@ jobs: (cd .ci/python-multiplatform && ./gradlew -p python-multiplatform-gradle-plugin publishToMavenLocal --console=plain) - name: Build the debug APK - working-directory: usage-example - run: ./gradlew assembleDebug --console=plain + working-directory: sample + run: ../gradlew assembleDebug --console=plain - name: Enable KVM for the emulator run: | @@ -255,7 +270,7 @@ jobs: target: google_apis disable-animations: true script: | - set -eu; apk=$(find usage-example/build/outputs/apk/debug -name '*.apk' | head -n 1); [ -n "$apk" ]; adb install -r "$apk"; adb logcat -c; adb shell am start -W -n org.thisisthepy.python.multiplatform.toolchain.example/.MainActivity --ez python-smoke true; sleep 20; adb logcat -d -s PythonSmoke:V > smoke.log; cat smoke.log; grep -q 'PYTHON_SMOKE_OK ' smoke.log; grep 'PYTHON_SMOKE_OK ' smoke.log | grep -q '/data/' + set -eu; apk=$(find sample/build/outputs/apk/debug -name '*.apk' | head -n 1); [ -n "$apk" ]; adb install -r "$apk"; adb logcat -c; adb shell am start -W -n org.thisisthepy.python.multiplatform.toolchain.example/.MainActivity --ez python-smoke true; sleep 20; adb logcat -d -s PythonSmoke:V > smoke.log; cat smoke.log; grep -q 'PYTHON_SMOKE_OK ' smoke.log; grep 'PYTHON_SMOKE_OK ' smoke.log | grep -q '/data/' guide: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index e26908b..d6829ba 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ captures # Agent working areas (AGENTS.md §2) .worktrees/ .tmp/ + +# IDE (JetBrains Fleet) +.fleet/ diff --git a/LICENSE b/LICENSE index bfa9e81..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,201 @@ -MIT License - -Copyright (c) 2024 thisisthepy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index dafec36..72139f8 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -English | [한국어](docs/locale/README_ko.md) +English | [한국어](https://github.com/thisisthepy/toolchain/blob/develop/docs/locale/README_ko.md)
# toolchain -**Declare the Python half of your Kotlin Multiplatform app in Gradle — and ship it.** +**Declare the Python half of your Kotlin Multiplatform app in Gradle, and ship it.** -[![License: MIT](https://img.shields.io/badge/license-MIT-0f9d76.svg)](LICENSE) +[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-0f9d76.svg)](https://github.com/thisisthepy/toolchain/blob/develop/LICENSE) ![Kotlin](https://img.shields.io/badge/Kotlin-2.1-7f52ff.svg?logo=kotlin&logoColor=white) ![Gradle](https://img.shields.io/badge/Gradle-8.9-02303a.svg?logo=gradle&logoColor=white) ![Targets](https://img.shields.io/badge/targets-Android%20%7C%20iOS%20%7C%20Desktop-0f9d76.svg) ![Status](https://img.shields.io/badge/status-alpha-orange.svg) -[Guide](docs/guide/index.html) · [Getting started](docs/guide/getting-started.html) · [Status](docs/guide/status.html) · [Ecosystem](docs/guide/ecosystem.html) +[Guide](https://thisisthepy.github.io/toolchain/index.html) · [Getting started](https://thisisthepy.github.io/toolchain/getting-started.html) · [Status](https://thisisthepy.github.io/toolchain/status.html) · [Ecosystem](https://thisisthepy.github.io/toolchain/ecosystem.html)
@@ -21,8 +21,8 @@ English | [한국어](docs/locale/README_ko.md) ## 💡 Why A Kotlin Multiplatform app that embeds Python has two builds to keep in step: the Kotlin one Gradle -already understands, and a Python one — interpreter version, packages, per-platform bundles, -assets — that it does not. `toolchain` is the Gradle plugin that closes the gap. You write one +already understands, and a Python one (interpreter version, packages, per-platform bundles, +assets) that it does not. `toolchain` is the Gradle plugin that closes the gap. You write one `python { }` block next to your `kotlin { }` block; the build installs your Python dependencies, bundles your code per target, and puts the payload where each platform's packaging step picks it up. @@ -33,18 +33,18 @@ owns the Gradle vocabulary in between. ## ✨ Features -- 🧩 **One DSL block** — `compileSdk`, platforms, `buildTypes`, `sourceSets` and `packaging`, all +- 🧩 **One DSL block**: `compileSdk`, platforms, `buildTypes`, `sourceSets` and `packaging`, all inside `python { }`. -- 📦 **Real dependency installs** — `implementation("pkg")` and `integration("pkg")` become a real +- 📦 **Real dependency installs**: `implementation("pkg")` and `integration("pkg")` become a real `uv add` through `pypackpack`. -- 🚀 **A task per variant** — every platform variant × build type gets its own +- 🚀 **A task per variant**: every platform variant × build type gets its own `buildPython` / `packagePython`, and an unsupported one fails alone. -- 🔌 **Lands in the artifact** — the bundle is staged into the desktop jar's resources and the +- 🔌 **Lands in the artifact**: the bundle is staged into the desktop jar's resources and the APK's `assets/`. -- 🧪 **Loud, not silent** — an unknown version string, an unmapped platform or an unsupported +- 🧪 **Loud, not silent**: an unknown version string, an unmapped platform or an unsupported compile level is rejected with a message saying why, instead of compiling and doing nothing. -- 🐍 **`tcl` for Python users** — `tcl install `, no Gradle project needed. +- 🐍 **`tcl` for Python users**: `tcl install `, no Gradle project needed. ## 🚀 Quick start @@ -56,8 +56,14 @@ owns the Gradle vocabulary in between. ./gradlew :toolchain:publishToMavenLocal ``` +| Coordinates | What | +|---|---| +| plugin id `org.thisisthepy.python.multiplatform` | the Gradle plugin; apply it by id (unchanged) | +| `org.thisisthepy.python.multiplatform:toolchain` | the plugin's implementation artifact | +| PyPI `toolchain-lite` | `tcl`, the command line for Python users (`uv tool install toolchain-lite`) | + Apply the plugin next to Kotlin Multiplatform and point it at a `pypackpack` package. This is -`usage-example/build.gradle.kts`, trimmed: +`sample/build.gradle.kts`, trimmed: ```kotlin plugins { @@ -68,20 +74,19 @@ plugins { python { compileSdk = "3.13" - localLibraryPath = "python" // a pypackpack package: pyproject.toml + src/main/ + localLibraryPath = "src/commonMain/python" // a pypackpack package: pyproject.toml + src/main/ packaging { - fileName = "usage-example" + fileName = "sample" } } ``` ```shell -cd usage-example # its own build, on python-multiplatform's Kotlin -./gradlew packagePython # install → bundle → zip -./gradlew stagePythonBundle # stage python/ for android, ios and desktop +./gradlew -p sample packagePython # install → bundle → zip (sample/ is its own build) +./gradlew -p sample stagePythonBundle # stage python/ for android, ios and desktop ``` -> **iOS, interim:** usage-example's Xcode phase (`usage-example/src/iosMain/install-python-phase.sh`) needs +> **iOS, interim:** sample's Xcode phase (`sample/src/iosMain/install-python-phase.sh`) needs > `PYTHON_MULTIPLATFORM_DIR` pointing at a python-multiplatform checkout for `Python.xcframework` and the > stdlib, until python-multiplatform#90 ships that wiring in its published plugin. @@ -103,7 +108,7 @@ python { Python only? Skip Gradle builds entirely: ```shell -./gradlew :tcl:run --args="install pythonx-compose" +./gradlew :toolchain:runTcl --args="install pythonx-compose" ``` ## 🧭 Architecture at a glance @@ -123,8 +128,8 @@ flowchart LR ## 📊 Status -An honest summary — the full contract, item by item, is on the guide's -[Status page](docs/guide/status.html). +An honest summary: the full contract, item by item, is on the guide's +[Status page](https://thisisthepy.github.io/toolchain/status.html). | Area | State | |---|---| @@ -134,25 +139,25 @@ An honest summary — the full contract, item by item, is on the guide's | `implementation` / `integration` dependencies via `uv`, per source set, installed for each variant's own triple into its bundle | ✅ implemented | | Bundling via `pypackpack` at the `instant` level | ✅ implemented | | `bytecode` compile level (`.pyc`; needs a `.venv` matching `compileSdk`) | ✅ implemented | -| `native` / `mixed` compile levels | ⏳ planned — rejected loudly today | -| Staging into the desktop jar and the APK | 🟡 partial — iOS is staged but not attached | -| Hot reload | 🟡 partial — Android only, over `adb` | -| Code push | 🟡 partial — validation only, no upload | -| `buildFeatures { metaclass, compose }` | ✅ implemented — compose locations come from two Gradle properties | +| `native` / `mixed` compile levels | ⏳ planned: rejected loudly today | +| Staging into the desktop jar and the APK | 🟡 partial: iOS is staged but not attached | +| Hot reload | 🟡 partial: Android only, over `adb` | +| Code push | 🟡 partial: validation only, no upload | +| `buildFeatures { metaclass, compose }` | ✅ implemented: compose locations come from two Gradle properties | | `embedLevel`, `projectFlavors`, `pip { }` | ⏳ planned | | `tcl install` | ✅ implemented | ## 📖 Documentation -- **[Guide](docs/guide/index.html)** — concepts, task guides, status, in English and 한국어. -- **[한국어 README](docs/locale/README_ko.md)** +- **[Guide](https://thisisthepy.github.io/toolchain/index.html)**: concepts, task guides, status, in English and 한국어. +- **[한국어 README](https://github.com/thisisthepy/toolchain/blob/develop/docs/locale/README_ko.md)** ## 🤝 Contributing Work here runs intent → spec → test → code: a behaviour change starts as a spec change, and its test is written and seen failing before the implementation. The guide's -[contributing notes](docs/guide/status.html#contributing) say how to run the tests. +[contributing notes](https://thisisthepy.github.io/toolchain/status.html#contributing) say how to run the tests. ## 📄 License -[MIT](LICENSE) © 2024 thisisthepy +[Apache-2.0](https://github.com/thisisthepy/toolchain/blob/develop/LICENSE) © 2024 thisisthepy diff --git a/docs/guide/assets/site.js b/docs/guide/assets/site.js index 286f19b..8c19455 100644 --- a/docs/guide/assets/site.js +++ b/docs/guide/assets/site.js @@ -1,4 +1,4 @@ -// toolchain guide — language and theme. Loaded synchronously in so the first paint is +// toolchain guide: language and theme. Loaded synchronously in so the first paint is // already in the right language and theme. (function () { var LANG_KEY = "thisisthepy.guide.lang"; diff --git a/docs/guide/assets/style.css b/docs/guide/assets/style.css index 66f1286..60c6610 100644 --- a/docs/guide/assets/style.css +++ b/docs/guide/assets/style.css @@ -1,4 +1,4 @@ -/* toolchain guide — shared thisisthepy family tokens, toolchain accent. */ +/* toolchain guide: shared thisisthepy family tokens, toolchain accent. */ :root { --bg: #fbfbfa; --fg: #16181d; --muted: #5b6270; --line: #e6e6e3; --code-bg: #f3f3f1; --radius: 10px; --maxw: 72rem; diff --git a/docs/guide/concepts.html b/docs/guide/concepts.html index 1eb7c47..05a55e0 100644 --- a/docs/guide/concepts.html +++ b/docs/guide/concepts.html @@ -62,13 +62,13 @@

Variants변형

How it fails실패하는 방식

-
Mistake실수When언제Scope범위
Malformed compileSdk형식이 틀린 compileSdkconfiguration구성 시점whole build빌드 전체
Platform with no pypackpack triple (androidArm32, androidX86)pypackpack 트리플이 없는 플랫폼 (androidArm32, androidX86)configuration구성 시점whole build — no valid task exists빌드 전체 — 유효한 태스크가 없음
Kotlin target not enabled for a declared platform선언된 플랫폼의 Kotlin 타깃이 꺼져 있음configuration구성 시점warning only경고만
compileLevel = native / mixed, or bytecode without a matching .venvcompileLevel = native / mixed, 또는 맞는 .venv 가 없는 bytecodetask execution태스크 실행 시점that variant only — --continue builds the rest그 변형만 — --continue 로 나머지는 빌드
compileSdk differs from python-multiplatform's pythonVersion at embedLevel = 2embedLevel = 2 에서 compileSdk 가 python-multiplatform 의 pythonVersion 과 다름task execution태스크 실행 시점that variant only — --continue builds the rest그 변형만 — --continue 로 나머지는 빌드
Unknown build type in -Ppython.buildType-Ppython.buildType 의 알 수 없는 빌드 타입configuration구성 시점whole build빌드 전체
+
Mistake실수When언제Scope범위
Malformed compileSdk형식이 틀린 compileSdkconfiguration구성 시점whole build빌드 전체
Platform with no pypackpack triple (androidArm32, androidX86)pypackpack 트리플이 없는 플랫폼 (androidArm32, androidX86)configuration구성 시점whole build: no valid task exists빌드 전체: 유효한 태스크가 없음
Kotlin target not enabled for a declared platform선언된 플랫폼의 Kotlin 타깃이 꺼져 있음configuration구성 시점warning only경고만
compileLevel = native / mixed, or bytecode without a matching .venvcompileLevel = native / mixed, 또는 맞는 .venv 가 없는 bytecodetask execution태스크 실행 시점that variant only: --continue builds the rest그 변형만: --continue 로 나머지는 빌드
compileSdk differs from python-multiplatform's pythonVersion at embedLevel = 2embedLevel = 2 에서 compileSdk 가 python-multiplatform 의 pythonVersion 과 다름task execution태스크 실행 시점that variant only: --continue builds the rest그 변형만: --continue 로 나머지는 빌드
Unknown build type in -Ppython.buildType-Ppython.buildType 의 알 수 없는 빌드 타입configuration구성 시점whole build빌드 전체
diff --git a/docs/guide/ecosystem.html b/docs/guide/ecosystem.html index b6f67f9..5e9bbd7 100644 --- a/docs/guide/ecosystem.html +++ b/docs/guide/ecosystem.html @@ -27,7 +27,7 @@

Ecosystem생태계toolchain is one part of thisisthepy: Python and Kotlin Multiplatform, in one app.

toolchain 은 thisisthepy 의 한 부분입니다. 하나의 앱 안의 Python 과 Kotlin Multiplatform.

-

toolchain — you are here — 현재 위치

The Gradle plugin and tcl: the vocabulary for building the Python half of an app.

Gradle 플러그인과 tcl: 앱의 Python 절반을 빌드하는 어휘.

+

toolchain: you are here: 현재 위치

The Gradle plugin and tcl: the vocabulary for building the Python half of an app.

Gradle 플러그인과 tcl: 앱의 Python 절반을 빌드하는 어휘.

pypackpack

The work: Python acquisition, dependency resolution with uv, cross-compilation, bundling.

작업: Python 획득, uv 의존성 해석, 크로스 컴파일, 번들링.

python-multiplatform

The runtime: CPython embedded in Kotlin Multiplatform, and the language boundary.

런타임: Kotlin Multiplatform 에 내장된 CPython 과 언어 경계.

pythonx-compose

Compose Multiplatform, usable from Python.

Python 에서 쓰는 Compose Multiplatform.

@@ -37,13 +37,13 @@

Ecosystem생태계

Where toolchain stopstoolchain 의 경계

-

If a feature acquires Python, resolves a dependency or builds a bundle, it belongs in pypackpack. If it runs at app start-up, it belongs in python-multiplatform. toolchain's job is the Gradle side in between — and saying clearly when the other side is not there yet.

Python 을 얻거나, 의존성을 해석하거나, 번들을 만드는 기능은 pypackpack 의 것입니다. 앱 시작 시점에 도는 것은 python-multiplatform 의 것입니다. toolchain 의 일은 그 사이의 Gradle 쪽 — 그리고 반대편이 아직 없을 때 그렇다고 분명히 말하는 것입니다.

+

If a feature acquires Python, resolves a dependency or builds a bundle, it belongs in pypackpack. If it runs at app start-up, it belongs in python-multiplatform. toolchain's job is the Gradle side in between: and saying clearly when the other side is not there yet.

Python 을 얻거나, 의존성을 해석하거나, 번들을 만드는 기능은 pypackpack 의 것입니다. 앱 시작 시점에 도는 것은 python-multiplatform 의 것입니다. toolchain 의 일은 그 사이의 Gradle 쪽: 그리고 반대편이 아직 없을 때 그렇다고 분명히 말하는 것입니다.

diff --git a/docs/guide/getting-started.html b/docs/guide/getting-started.html index ef8d704..fcd9817 100644 --- a/docs/guide/getting-started.html +++ b/docs/guide/getting-started.html @@ -40,7 +40,7 @@

1. Prerequisites1. 준비

2. A Python package2. Python 패키지

The plugin bundles a pypackpack package: a directory with a pyproject.toml and its code under src/main/. Platform-specific code can sit in src/android, src/ios and so on; the bundler overlays it.

플러그인이 번들링하는 것은 pypackpack 패키지입니다. pyproject.toml 이 있고 코드가 src/main/ 아래에 있는 디렉터리입니다. 플랫폼 전용 코드는 src/android, src/ios 등에 두면 번들러가 덮어씌웁니다.

-
usage-example/python/
+
sample/src/commonMain/python/
 ├── pyproject.toml
 └── src/main/example_py/
     ├── __init__.py
@@ -57,20 +57,19 @@ 

3. Apply the plugin3. 플 python { compileSdk = "3.13" - localLibraryPath = "python" + localLibraryPath = "src/commonMain/python" packaging { - fileName = "usage-example" + fileName = "sample" } }

-

This is the repository's own usage-example/build.gradle.kts. Instead of localLibraryPath you can point sourceSets { commonMain { srcDirs(...) } } at the package.

이 저장소의 usage-example/build.gradle.kts 그대로입니다. localLibraryPath 대신 sourceSets { commonMain { srcDirs(...) } } 로 패키지를 가리켜도 됩니다.

+

This is the repository's own sample/build.gradle.kts. Instead of localLibraryPath you can point sourceSets { commonMain { srcDirs(...) } } at the package.

이 저장소의 sample/build.gradle.kts 그대로입니다. localLibraryPath 대신 sourceSets { commonMain { srcDirs(...) } } 로 패키지를 가리켜도 됩니다.

4. Run it4. 실행

-
cd usage-example                             # its own build / 별도 빌드
-./gradlew packagePython                      # installPythonDependencies → buildPython → zip
-./gradlew stagePythonBundle                  # copy python/ where each platform packages from
-./gradlew tasks --group python               # everything the plugin registered
+
./gradlew -p sample packagePython            # installPythonDependencies → buildPython → zip
+./gradlew -p sample stagePythonBundle        # copy python/ where each platform packages from
+./gradlew -p sample tasks --group python     # everything the plugin registered
@@ -82,7 +81,7 @@

5. What you get5. 결과물 diff --git a/docs/guide/guide-dependencies.html b/docs/guide/guide-dependencies.html index aaf7ca4..3f478d8 100644 --- a/docs/guide/guide-dependencies.html +++ b/docs/guide/guide-dependencies.html @@ -95,7 +95,7 @@

ComposeCompose

diff --git a/docs/guide/guide-staging.html b/docs/guide/guide-staging.html index fb11e73..c9203e7 100644 --- a/docs/guide/guide-staging.html +++ b/docs/guide/guide-staging.html @@ -30,7 +30,7 @@

Into the app앱 안으로What staging does스테이징이 하는 일

stagePythonBundleAndroid, …Ios and …Desktop each copy a bundle's python/ directory into build/pythonStaging/<platform>/python/. stagePythonBundle runs all three.

stagePythonBundleAndroid, …Ios, …Desktop 은 각각 번들의 python/ 디렉터리를 build/pythonStaging/<platform>/python/ 로 복사합니다. stagePythonBundle 은 셋을 모두 실행합니다.

    -
  • Only python/ travels — the manifest is build metadata.python/ 만 옮깁니다 — 매니페스트는 빌드 메타데이터입니다.
  • +
  • Only python/ travels: the manifest is build metadata.python/ 만 옮깁니다: 매니페스트는 빌드 메타데이터입니다.
  • The previous payload is deleted first, so a module you removed stops shipping.이전 페이로드를 먼저 지우므로, 지운 모듈은 더 이상 실리지 않습니다.
  • The payload is a declared input: change your Python and the next build re-stages.페이로드가 선언된 입력이라, Python 을 바꾸면 다음 빌드가 다시 스테이징합니다.
  • Everything stays under build/; nothing is generated into src/.모든 것이 build/ 아래에 있고, src/ 에는 아무것도 생성하지 않습니다.
  • @@ -39,32 +39,32 @@

    What staging does스테이

    Which bundle goes where어느 번들이 어디로

    -

    A packaging step takes one directory, so one variant is chosen per destination — only from variants of the active build type:

    패키징 단계는 디렉터리 하나를 받으므로 목적지마다 변형 하나를 고릅니다 — 활성 빌드 타입의 변형 중에서만.

    +

    A packaging step takes one directory, so one variant is chosen per destination: only from variants of the active build type:

    패키징 단계는 디렉터리 하나를 받으므로 목적지마다 변형 하나를 고릅니다; 활성 빌드 타입의 변형 중에서만.

    Destination목적지Chosen variant고르는 변형Handed to넘겨받는 곳
    Desktop데스크톱the one whose triple is the host's, else the first declared호스트와 트리플이 같은 것, 없으면 처음 선언된 것the JVM target's processResources → jarJVM 타깃의 processResources → jarpartial부분
    AndroidAndroidthe first declared처음 선언된 것android.sourceSets.main.assets → APKandroid.sourceSets.main.assets → APKpartial부분
    iOSiOSthe first declared처음 선언된 것stagePythonBundleIosForXcode prints the path; an Xcode build phase copies itstagePythonBundleIosForXcode 가 경로를 출력하고 Xcode 빌드 단계가 복사합니다partial부분

    Without a declared platform variant, every destination gets the single host bundle and the build logs that it did so. A destination with no matching variant stages nothing rather than a bundle built for another platform.

    선언된 플랫폼 변형이 없으면 모든 목적지가 호스트 번들 하나를 받고, 빌드가 그 사실을 기록합니다. 맞는 변형이 없는 목적지는 다른 플랫폼용 번들 대신 아무것도 스테이징하지 않습니다.

    iOS: the Xcode build phaseiOS: Xcode 빌드 단계

    -

    stagePythonBundleIosForXcode runs stagePythonBundleIos and prints exactly one line, PYTHON_PAYLOAD_DIR=<absolute path>, even under --quiet. It fails, naming why, when no iOS variant of the active build type exists or the staged directory is empty (no package configured). It never copies into the .app. The phase that does is owned by python-multiplatform (its #59); this plugin only stages and exposes the path. The script it uses is tools/xcode/stage-python-payload.sh:

    stagePythonBundleIosForXcode 는 stagePythonBundleIos 를 실행한 뒤 --quiet 에서도 정확히 한 줄, PYTHON_PAYLOAD_DIR=<절대 경로> 를 출력합니다. 활성 빌드 타입의 iOS 변형이 없거나 스테이징 디렉터리가 비어 있으면(패키지 미설정) 이유를 밝히며 실패합니다. .app 안으로는 절대 복사하지 않습니다. 복사하는 단계는 python-multiplatform(#59)이 소유하며, 이 플러그인은 스테이징과 경로 노출만 합니다. 사용하는 스크립트는 tools/xcode/stage-python-payload.sh 입니다:

    +

    stagePythonBundleIosForXcode runs stagePythonBundleIos and prints exactly one line, PYTHON_PAYLOAD_DIR=<absolute path>, even under --quiet. It fails, naming why, when no iOS variant of the active build type exists or the staged directory is empty (no package configured). It never copies into the .app. The phase that does is owned by python-multiplatform (its #59); this plugin only stages and exposes the path. Wiring the phase by hand, without python-multiplatform, it is:

    stagePythonBundleIosForXcode 는 stagePythonBundleIos 를 실행한 뒤 --quiet 에서도 정확히 한 줄, PYTHON_PAYLOAD_DIR=<절대 경로> 를 출력합니다. 활성 빌드 타입의 iOS 변형이 없거나 스테이징 디렉터리가 비어 있으면(패키지 미설정) 이유를 밝히며 실패합니다. .app 안으로는 절대 복사하지 않습니다. 복사하는 단계는 python-multiplatform(#59)이 소유하며, 이 플러그인은 스테이징과 경로 노출만 합니다. 사용하는 python-multiplatform 없이 손으로 배선한다면 단계는 다음과 같습니다:

    set -euo pipefail
     out=$(./gradlew -q :app:stagePythonBundleIosForXcode)
     dir=$(printf '%s\n' "$out" | sed -n 's/^PYTHON_PAYLOAD_DIR=//p')
     [ -n "$dir" ] && [ -d "$dir" ] || { echo "error: no Python payload dir from Gradle" >&2; exit 1; }
     rsync -a --delete "$dir/" "$TARGET_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/python/"
    -

    This script is for apps without python-multiplatform. With python-multiplatform, its tools/xcode/install-python.sh is the one phase that copies python/ (and the stdlib): set PYTHON_PAYLOAD_TASK=:app:stagePythonBundleIosForXcode there and do not add this script as well. Only one Xcode phase may copy python/, because each rsync --deletes the same directory.

    이 스크립트는 python-multiplatform 을 쓰지 않는 앱용입니다. python-multiplatform 을 쓰면 그쪽 tools/xcode/install-python.sh 가 python/(와 stdlib)을 복사하는 유일한 단계입니다. 거기에 PYTHON_PAYLOAD_TASK=:app:stagePythonBundleIosForXcode 를 주고, 이 스크립트를 함께 넣지 마세요. 둘 다 같은 디렉터리를 rsync --delete 하므로 python/ 을 복사하는 Xcode 단계는 하나여야 합니다.

    +

    With python-multiplatform, its tools/xcode/install-python.sh is the one phase that copies python/ (and the stdlib): give it the directory this task prints as PYTHON_PAYLOAD_DIR, as the sample's sample/src/iosMain/install-python-phase.sh does, and do not add the snippet above as well. Only one Xcode phase may copy python/, because each rsync --deletes the same directory. The snippet above is for wiring by hand without python-multiplatform.

    python-multiplatform 을 쓰면 그쪽 tools/xcode/install-python.sh 가 python/(와 stdlib)을 복사하는 유일한 단계입니다. 이 태스크가 출력한 디렉터리를 PYTHON_PAYLOAD_DIR 로 넘기세요(샘플의 sample/src/iosMain/install-python-phase.sh 처럼). 위 스니펫을 함께 넣지 마세요. 둘 다 같은 디렉터리를 rsync --delete 하므로 python/ 을 복사하는 Xcode 단계는 하나여야 합니다. 위 스니펫은 python-multiplatform 없이 손으로 배선할 때를 위한 것입니다.

    Do not shorten it to dir=$(./gradlew … | sed …) && rsync …: the pipeline's status is sed's, so a failed Gradle leaves dir empty and rsync --delete "/" runs.

    dir=$(./gradlew … | sed …) && rsync … 처럼 줄이면 안 됩니다. 파이프라인의 종료 상태는 sed 의 것이라, Gradle 이 실패하면 dir 이 비어 rsync --delete "/" 가 실행됩니다.

    After staging스테이징 이후

    -

    Putting the staged python/ on sys.path when the app starts is the runtime's job — python-multiplatform's side of the boundary, not this plugin's.

    앱이 시작할 때 스테이징된 python/ 을 sys.path 에 올리는 것은 런타임의 일입니다 — 이 플러그인이 아니라 python-multiplatform 쪽 경계입니다.

    +

    Putting the staged python/ on sys.path when the app starts is the runtime's job: python-multiplatform's side of the boundary, not this plugin's.

    앱이 시작할 때 스테이징된 python/ 을 sys.path 에 올리는 것은 런타임의 일입니다: 이 플러그인이 아니라 python-multiplatform 쪽 경계입니다.

    diff --git a/docs/guide/guide-tcl.html b/docs/guide/guide-tcl.html index 0962b9a..ba9df2f 100644 --- a/docs/guide/guide-tcl.html +++ b/docs/guide/guide-tcl.html @@ -28,7 +28,11 @@

    tcl for Python usersPython

    Install a package패키지 설치

    -
    ./gradlew :tcl:run --args="install pythonx-compose"
    +
    uv tool install toolchain-lite    # once 0.1.0 is on PyPI
    +tcl install pythonx-compose
    +tcl --version
    +
    +./gradlew :toolchain:runTcl --args="install pythonx-compose"    # from a checkout

    tcl install <package> looks for a pyproject.toml in the current directory and its parents. If there is none it runs uv init --bare first; then it adds the package with uv add, through the same pypackpack backend the Gradle plugin uses.

    tcl install <package> 는 현재 디렉터리와 그 상위에서 pyproject.toml 을 찾습니다. 없으면 먼저 uv init --bare 를 실행하고, Gradle 플러그인과 같은 pypackpack 백엔드로 uv add 를 해서 패키지를 추가합니다.

    Invocation호출Result결과
    tcl install pkgexit 0, uv output on stdout종료 코드 0, stdout 에 uv 출력
    tclexit 1, Usage: tcl install <package>종료 코드 1, Usage: tcl install <package>
    tcl installexit 1, missing argument종료 코드 1, 인자 누락
    tcl otherexit 1, unknown command종료 코드 1, 알 수 없는 명령

    install is the only command, matching issue #1. tcl needs uv on PATH and network access to PyPI.

    명령은 이슈 #1 그대로 install 하나뿐입니다. tcl 은 PATH 의 uv 와 PyPI 네트워크 접근이 필요합니다.

    @@ -37,7 +41,7 @@

    Install a package패키지 diff --git a/docs/guide/guide-variants.html b/docs/guide/guide-variants.html index 1f9074a..0a84b83 100644 --- a/docs/guide/guide-variants.html +++ b/docs/guide/guide-variants.html @@ -56,7 +56,7 @@

    Build types빌드 타입

    Only debug and release exist. useCodeMinifier, excludeMetaclass and enableCodePush are release-only: setting them on debug throws.

    debug 와 release 만 있습니다. useCodeMinifier, excludeMetaclass, enableCodePush 는 release 전용이며 debug 에 설정하면 예외가 납니다.

    -
    compileLevelcompileLevelMeaning의미Today지금
    instant (or blank)(또는 빈 값).py only.py 만implemented구현됨
    bytecodedebug: .py + .pyc; release: .pyc onlydebug: .py + .pyc, release: .pyc 만implemented구현됨
    nativenative code only네이티브 코드만planned (pypackpack#19)계획 (pypackpack#19)
    mixedyour code as bytecode, libraries native내 코드는 바이트코드, 라이브러리는 네이티브planned (pypackpack#19)계획 (pypackpack#19)
    +
    compileLevelcompileLevelMeaning의미Today지금
    instant (or blank)(또는 빈 값).py only.py 만implemented구현
    bytecodedebug: .py + .pyc; release: .pyc onlydebug: .py + .pyc, release: .pyc 만implemented구현
    nativenative code only네이티브 코드만planned (pypackpack#19)계획 (pypackpack#19)
    mixedyour code as bytecode, libraries native내 코드는 바이트코드, 라이브러리는 네이티브planned (pypackpack#19)계획 (pypackpack#19)

    bytecode compiles with the Python in a .venv at or above your package directory. installPythonDependencies leaves one there (uv add creates <package>/.venv) once you declare a dependency; otherwise run uv venv --python 3.14 in the package directory. Its minor version must match compileSdk, because a .pyc only loads on the CPython minor version that wrote it; a mismatch fails the variant. Without a declared compileSdk, or a pyvenv.cfg to read, the versions are not compared.

    bytecode 는 패키지 디렉터리나 그 위의 .venv 에 있는 Python 으로 컴파일합니다. 의존성을 하나라도 선언하면 installPythonDependencies 가 그것을 만들어 둡니다(uv add 가 <package>/.venv 를 만듭니다). 그렇지 않으면 패키지 디렉터리에서 uv venv --python 3.14 를 실행하세요. 그 마이너 버전은 compileSdk 와 같아야 합니다. .pyc 는 그것을 쓴 CPython 마이너 버전에서만 로드되기 때문이며, 다르면 그 변형이 실패합니다. compileSdk 를 선언하지 않았거나 읽을 pyvenv.cfg 가 없으면 버전을 비교하지 않습니다.

    A planned level fails only its own variant's buildPython… task, so ./gradlew packagePython --continue still builds every other variant.

    계획 단계의 레벨은 그 변형의 buildPython… 태스크만 실패시키므로, ./gradlew packagePython --continue 는 나머지 변형을 모두 빌드합니다.

    @@ -78,13 +78,13 @@

    Project flavors프로젝트

    Choosing the active build type활성 빌드 타입 고르기

    Without platforms there are no per-variant task names to ask for, so a project property picks the build type. It defaults to debug; a name you did not declare fails the build.

    플랫폼이 없으면 고를 변형 태스크 이름이 없으므로 프로젝트 속성으로 빌드 타입을 정합니다. 기본값은 debug 이고, 선언하지 않은 이름은 빌드를 실패시킵니다.

    ./gradlew packagePython -Ppython.buildType=release
    -

    The same property decides which variant's bundle is staged into your app — see Into the app.

    같은 속성이 앱에 스테이징될 변형도 정합니다 — 앱 안으로를 보세요.

    +

    The same property decides which variant's bundle is staged into your app: see Into the app.

    같은 속성이 앱에 스테이징될 변형도 정합니다: 앱 안으로를 보세요.

diff --git a/docs/guide/index.html b/docs/guide/index.html index 133041c..fb9fa0b 100644 --- a/docs/guide/index.html +++ b/docs/guide/index.html @@ -27,12 +27,12 @@

Gradle plugin · Kotlin Multiplatform · Python

Gradle 플러그인 · Kotlin Multiplatform · Python

Declare the Python half of your app in Gradle.앱의 Python 절반을 Gradle 에 선언하세요.

-

toolchain turns one python { } block into installed dependencies, a bundle per target, and a payload inside your jar and APK — by delegating the work, not redoing it.

toolchain 은 python { } 블록 하나를 설치된 의존성, 타깃별 번들, 그리고 jar 와 APK 안의 페이로드로 바꿉니다. 작업을 다시 만들지 않고 위임해서요.

+

toolchain turns one python { } block into installed dependencies, a bundle per target, and a payload inside your jar and APK: by delegating the work, not redoing it.

toolchain 은 python { } 블록 하나를 설치된 의존성, 타깃별 번들, 그리고 jar 와 APK 안의 페이로드로 바꿉니다. 작업을 다시 만들지 않고 위임해서요.

-
python { }you declare선언한다toolchaintranslates번역한다pypackpackuv · bundleruv · 번들러pythonStagingper platform플랫폼별your app내 앱jar · APK · iOSjar · APK · iOSruntime런타임python-multiplatformpython-multiplatformbuild time — this repository + pypackpack빌드 시점 — 이 저장소 + pypackpackrun time실행 시점one python { } block → an app that carries its Pythonpython { } 블록 하나 → Python 을 품은 앱 +
python { }you declare선언한다toolchaintranslates번역한다pypackpackuv · bundleruv · 번들러pythonStagingper platform플랫폼별your app내 앱jar · APK · iOSjar · APK · iOSruntime런타임python-multiplatformpython-multiplatformbuild time: this repository + pypackpack빌드 시점: 이 저장소 + pypackpackrun time실행 시점one python { } block → an app that carries its Pythonpython { } 블록 하나 → Python 을 품은 앱
toolchain owns the Gradle vocabulary. pypackpack owns the work. python-multiplatform owns the runtime.toolchain 은 Gradle 어휘를, pypackpack 은 작업을, python-multiplatform 은 런타임을 맡습니다.
@@ -44,13 +44,13 @@

Three ideas the plugin is built on02

Delegate the work작업은 위임한다

Installing a package is a real uv add through pypackpack. Bundling is pypackpack's resource bundler. The plugin translates Gradle into those calls and nothing more.

패키지 설치는 pypackpack 을 거친 실제 uv add 이고, 번들링은 pypackpack 의 리소스 번들러입니다. 플러그인은 Gradle 을 그 호출로 번역할 뿐입니다.

03

Loud, never silent조용히 넘기지 않는다

-

Every DSL value is either read by a task or rejected with a reason. An unmapped platform or an unsupported compile level fails — and only the variant that asked for it.

모든 DSL 값은 태스크가 읽거나, 이유와 함께 거부됩니다. 매핑되지 않는 플랫폼이나 지원되지 않는 컴파일 레벨은 실패합니다 — 그것을 요청한 변형만.

+

Every DSL value is either read by a task or rejected with a reason. An unmapped platform or an unsupported compile level fails: and only the variant that asked for it.

모든 DSL 값은 태스크가 읽거나, 이유와 함께 거부됩니다. 매핑되지 않는 플랫폼이나 지원되지 않는 컴파일 레벨은 실패합니다: 그것을 요청한 변형만.

Where it is going가고 있는 곳

-

This is the shape of the DSL the maintainer wrote by hand — the target the plugin grows toward. Part of it is live today; the status page says exactly which part.

아래는 메인테이너가 직접 쓴 DSL 의 모습, 즉 플러그인이 향하는 목표입니다. 일부는 지금 동작하고, 정확히 어느 부분인지는 상태 페이지에 있습니다.

+

This is the shape of the DSL the maintainer wrote by hand: the target the plugin grows toward. Part of it is live today; the status page says exactly which part.

아래는 메인테이너가 직접 쓴 DSL 의 모습, 즉 플러그인이 향하는 목표입니다. 일부는 지금 동작하고, 정확히 어느 부분인지는 상태 페이지에 있습니다.

python {
     compileSdk = "3.11.9-alpha"
 
@@ -85,7 +85,7 @@ 

Where it is going가고 있 diff --git a/docs/guide/status.html b/docs/guide/status.html index 46c44c1..b6223cc 100644 --- a/docs/guide/status.html +++ b/docs/guide/status.html @@ -24,12 +24,12 @@

Status & FAQ상태와 FAQ

-

What works today, measured against the maintainer's example build file. “Implemented” means a test in this repository exercises it.

지금 되는 것을 메인테이너의 예시 빌드 파일에 대어 본 것입니다. “구현됨” 은 이 저장소의 테스트가 그것을 실행한다는 뜻입니다.

+

What works today, measured against the maintainer's example build file. “Implemented” means a test in this repository exercises it.

지금 되는 것을 메인테이너의 예시 빌드 파일에 대어 본 것입니다. “구현” 은 이 저장소의 테스트가 그것을 실행한다는 뜻입니다.

Feature status기능 상태

-
-
Feature기능Status상태Evidence근거
Applying the plugin: python extension and tasks플러그인 적용: python 확장과 태스크implemented구현됨PythonPluginApplyTest
compileSdk parsing: alpha · rc · normalcompileSdk 파싱: alpha · rc · normalimplemented구현됨PythonVersionTest
Platform → triple mapping, Kotlin target check, min SDK플랫폼 → 트리플 매핑, Kotlin 타깃 확인, 최소 SDKimplemented구현됨PythonExtensionPlatformDslTest, PlatformTargetMappingTest, PythonPluginPlatformsTest
debug / release, -Ppython.buildTypedebug / release, -Ppython.buildTypeimplemented구현됨PythonPluginBuildTypeTest
Per-variant task graph변형별 태스크 그래프implemented구현됨PythonPluginVariantGraphTest
compileLevel = instant · bytecode (.venv and compileSdk minor checked); others rejected per variantcompileLevel = instant · bytecode (.venv 와 compileSdk 마이너 버전 확인); 나머지는 변형별 거부implemented구현됨PythonPluginBuildLevelTest, BytecodeLevelTest
srcDirs / metaDirs / libDirssrcDirs / metaDirs / libDirsimplemented구현됨PythonPluginSourceSetTest
implementation / integration → uv addimplementation / integration → uv addimplemented구현됨PythonPluginDependencyTest, InstallDependenciesTaskTest
Bundling via pypackpack's resource bundlerpypackpack 리소스 번들러로 번들링implemented구현됨BuildPythonArtifactTaskTest
packagePython zippackagePython zipimplemented구현됨AssemblePythonPackageTaskTest
Staging copy rule and variant selection스테이징 복사 규칙과 변형 선택implemented구현됨StagePythonBundleTaskTest, PythonPluginStagingTest
tcl installtcl installimplemented구현됨CliArgsTest, InstallerTest
Staging into the desktop jar데스크톱 jar 로의 스테이징implemented구현됨PythonPluginAttachmentTest
Staging into the APKAPK 로의 스테이징partial부분asset root tested (PythonPluginAttachmentTest); task dependency untested에셋 루트는 테스트됨 (PythonPluginAttachmentTest), 태스크 의존성은 테스트 없음
Hot reload핫 리로드partial부분Android, adb only; serverHost unusedAndroid, adb 만; serverHost 미사용
Code push코드 푸시partial부분validation only검증만
Dependencies per source set, installed for each variant's own triple into its bundle소스셋별 의존성을 변형마다 그 트리플용으로 설치해 번들에 포함implemented구현됨TargetDependenciesTest, PythonPluginTargetDependenciesTest, InstallTargetDependenciesTaskTest
integration(): warn when the wheel has no KLIBDEPENSintegration(): 휠에 KLIBDEPENS 가 없으면 경고implemented구현됨KlibDepensTest, PythonPluginIntegrationListTest
native / mixednative / mixedplanned계획needs pypackpack#19pypackpack#19 선행 필요
iOS: attaching the staged payload (stagePythonBundleIosForXcode prints the path; the Xcode phase is python-multiplatform's, #59)iOS: 스테이징된 페이로드 연결 (stagePythonBundleIosForXcode 가 경로 출력, Xcode 단계는 python-multiplatform #59 소유)partial부분StagePythonBundleIosForXcodeTaskTest, StagePythonPayloadScriptTest
buildFeatures { metaclass } and excludeMetaclass: metaDirs forwarded or droppedbuildFeatures { metaclass } 와 excludeMetaclass: metaDirs 전달 또는 제외implemented구현됨BuildFeaturesTest, PythonPluginBuildFeaturesTest
buildFeatures { compose }: installs pythonx-compose, adds python-multiplatform-compose to commonMainbuildFeatures { compose }: pythonx-compose 설치, commonMain 에 python-multiplatform-compose 추가implemented구현됨BuildFeaturesTest, PythonPluginBuildFeaturesTest; locations from two Gradle propertiesBuildFeaturesTest, PythonPluginBuildFeaturesTest; 위치는 Gradle 속성 두 개로 지정
embedLevel: 0/1/2 resolved per platform (Android and iOS raise to 2 with a warning), -Ppython.embedLevel override, recorded in embed.json with the expected interpreter version; level 2 means python-multiplatform embeds the interpreter, and the bundle stays python/ onlyembedLevel: 플랫폼별 0/1/2 결정 (Android, iOS 는 경고와 함께 2 로 상향), -Ppython.embedLevel 재정의, 기대 인터프리터 버전과 함께 embed.json 에 기록; 레벨 2 는 python-multiplatform 이 인터프리터를 내장한다는 뜻이고, 번들은 python/ 만 담음implemented구현됨EmbedLevelTest, PythonPluginEmbedLevelTest, PythonPluginPythonOnlyTest
useCodeMinifieruseCodeMinifierplanned계획declared, unread선언만, 읽히지 않음
defaultConfig { pip }: central · local · autoUpdatedefaultConfig { pip }: central · local · autoUpdateimplemented구현됨PipRepositoriesTest
pip { jit }pip { jit }planned계획—
compileSdk constants (PY3_14_7); unprovided versions refused per taskcompileSdk 상수(PY3_14_7); 제공되지 않는 버전은 태스크에서 거부implemented구현됨PythonSdkTest, BuildPythonSdkRejectionTest
projectFlavors in the variant graph; -Ppython.flavor변형 그래프의 projectFlavors; -Ppython.flavorimplemented구현됨PythonPluginFlavorsTest
defaultConfig { versionCode, versionName } → bundle manifestdefaultConfig { versionCode, versionName } → 번들 manifestimplemented구현됨PythonPluginPayloadVersionTest, BuildPythonArtifactTaskTest
toolchain ships only python/: compileSdk selects the wheels' Python version and fetches no interpreter; the interpreter and stdlib come from python-multiplatformtoolchain 은 python/ 만 실음: compileSdk 는 wheel 의 Python 버전을 고를 뿐 인터프리터를 받지 않음; 인터프리터와 stdlib 는 python-multiplatform 이 제공implemented구현됨PythonPluginTargetDependenciesTest, PythonPluginPythonOnlyTest
compileSdk checked against python-multiplatform's pythonVersion at level 2 (a mismatch fails only that variant's buildPython…); read from -Ppython.multiplatform.pythonVersion, the :python-multiplatform project's extension, or the published dependency's metadata or jar레벨 2 에서 compileSdk 를 python-multiplatform 의 pythonVersion 과 대조 (다르면 그 변형의 buildPython… 만 실패); -Ppython.multiplatform.pythonVersion, :python-multiplatform 프로젝트의 확장, 또는 배포된 의존의 메타데이터나 jar 에서 읽음implemented구현됨PythonVersionAgreementTest, PythonPluginPythonOnlyTest, PublishedPythonVersionTest
+
+
Feature기능Status상태Evidence근거
Applying the plugin: python extension and tasks플러그인 적용: python 확장과 태스크implemented구현PythonPluginApplyTest
compileSdk parsing: alpha · rc · normalcompileSdk 파싱: alpha · rc · normalimplemented구현PythonVersionTest
Platform → triple mapping, Kotlin target check, min SDK플랫폼 → 트리플 매핑, Kotlin 타깃 확인, 최소 SDKimplemented구현PythonExtensionPlatformDslTest, PlatformTargetMappingTest, PythonPluginPlatformsTest
debug / release, -Ppython.buildTypedebug / release, -Ppython.buildTypeimplemented구현PythonPluginBuildTypeTest
Per-variant task graph변형별 태스크 그래프implemented구현PythonPluginVariantGraphTest
compileLevel = instant · bytecode (.venv and compileSdk minor checked); others rejected per variantcompileLevel = instant · bytecode (.venv 와 compileSdk 마이너 버전 확인); 나머지는 변형별 거부implemented구현PythonPluginBuildLevelTest, BytecodeLevelTest
srcDirs / metaDirs / libDirssrcDirs / metaDirs / libDirsimplemented구현PythonPluginSourceSetTest
implementation / integration → uv addimplementation / integration → uv addimplemented구현PythonPluginDependencyTest, InstallDependenciesTaskTest
Bundling via pypackpack's resource bundlerpypackpack 리소스 번들러로 번들링implemented구현BuildPythonArtifactTaskTest
packagePython zippackagePython zipimplemented구현AssemblePythonPackageTaskTest
Staging copy rule and variant selection스테이징 복사 규칙과 변형 선택implemented구현StagePythonBundleTaskTest, PythonPluginStagingTest
tcl installtcl installimplemented구현CliArgsTest, InstallerTest
tcl --help, tcl --versiontcl --help, tcl --versionimplemented구현CliArgsTest
toolchain-lite on PyPI (uv tool install toolchain-lite)PyPI 의 toolchain-lite (uv tool install toolchain-lite)partial부분CI builds and smoke-tests the wheels; not uploaded yetCI 가 휠을 빌드하고 스모크 테스트함. 아직 업로드 안 됨
Staging into the desktop jar데스크톱 jar 로의 스테이징implemented구현PythonPluginAttachmentTest
Staging into the APKAPK 로의 스테이징partial부분asset root tested (PythonPluginAttachmentTest); task dependency untested에셋 루트는 테스트됨 (PythonPluginAttachmentTest), 태스크 의존성은 테스트 없음
Hot reload핫 리로드partial부분Android, adb only; serverHost unusedAndroid, adb 만; serverHost 미사용
Code push코드 푸시partial부분validation only검증만
Dependencies per source set, installed for each variant's own triple into its bundle소스셋별 의존성을 변형마다 그 트리플용으로 설치해 번들에 포함implemented구현TargetDependenciesTest, PythonPluginTargetDependenciesTest, InstallTargetDependenciesTaskTest
integration(): warn when the wheel has no KLIBDEPENSintegration(): 휠에 KLIBDEPENS 가 없으면 경고implemented구현KlibDepensTest, PythonPluginIntegrationListTest
native / mixednative / mixedplanned계획needs pypackpack#19pypackpack#19 선행 필요
iOS: attaching the staged payload (stagePythonBundleIosForXcode prints the path; the Xcode phase is python-multiplatform's, #59)iOS: 스테이징된 페이로드 연결 (stagePythonBundleIosForXcode 가 경로 출력, Xcode 단계는 python-multiplatform #59 소유)partial부분StagePythonBundleIosForXcodeTaskTest, StagePythonPayloadScriptTest
buildFeatures { metaclass } and excludeMetaclass: metaDirs forwarded or droppedbuildFeatures { metaclass } 와 excludeMetaclass: metaDirs 전달 또는 제외implemented구현BuildFeaturesTest, PythonPluginBuildFeaturesTest
buildFeatures { compose }: installs pythonx-compose, adds python-multiplatform-compose to commonMainbuildFeatures { compose }: pythonx-compose 설치, commonMain 에 python-multiplatform-compose 추가implemented구현BuildFeaturesTest, PythonPluginBuildFeaturesTest; locations from two Gradle propertiesBuildFeaturesTest, PythonPluginBuildFeaturesTest; 위치는 Gradle 속성 두 개로 지정
embedLevel: 0/1/2 resolved per platform (Android and iOS raise to 2 with a warning), -Ppython.embedLevel override, recorded in embed.json with the expected interpreter version; level 2 means python-multiplatform embeds the interpreter, and the bundle stays python/ onlyembedLevel: 플랫폼별 0/1/2 결정 (Android, iOS 는 경고와 함께 2 로 상향), -Ppython.embedLevel 재정의, 기대 인터프리터 버전과 함께 embed.json 에 기록; 레벨 2 는 python-multiplatform 이 인터프리터를 내장한다는 뜻이고, 번들은 python/ 만 담음implemented구현EmbedLevelTest, PythonPluginEmbedLevelTest, PythonPluginPythonOnlyTest
useCodeMinifieruseCodeMinifierplanned계획declared, unread선언만, 읽히지 않음
defaultConfig { pip }: central · local · autoUpdatedefaultConfig { pip }: central · local · autoUpdateimplemented구현PipRepositoriesTest
pip { jit }pip { jit }planned계획-
compileSdk constants (PY3_14_7); unprovided versions refused per taskcompileSdk 상수(PY3_14_7); 제공되지 않는 버전은 태스크에서 거부implemented구현PythonSdkTest, BuildPythonSdkRejectionTest
projectFlavors in the variant graph; -Ppython.flavor변형 그래프의 projectFlavors; -Ppython.flavorimplemented구현PythonPluginFlavorsTest
defaultConfig { versionCode, versionName } → bundle manifestdefaultConfig { versionCode, versionName } → 번들 manifestimplemented구현PythonPluginPayloadVersionTest, BuildPythonArtifactTaskTest
toolchain ships only python/: compileSdk selects the wheels' Python version and fetches no interpreter; the interpreter and stdlib come from python-multiplatformtoolchain 은 python/ 만 실음: compileSdk 는 wheel 의 Python 버전을 고를 뿐 인터프리터를 받지 않음; 인터프리터와 stdlib 는 python-multiplatform 이 제공implemented구현PythonPluginTargetDependenciesTest, PythonPluginPythonOnlyTest
compileSdk checked against python-multiplatform's pythonVersion at level 2 (a mismatch fails only that variant's buildPython…); read from -Ppython.multiplatform.pythonVersion, the :python-multiplatform project's extension, or the published dependency's metadata or jar레벨 2 에서 compileSdk 를 python-multiplatform 의 pythonVersion 과 대조 (다르면 그 변형의 buildPython… 만 실패); -Ppython.multiplatform.pythonVersion, :python-multiplatform 프로젝트의 확장, 또는 배포된 의존의 메타데이터나 jar 에서 읽음implemented구현PythonVersionAgreementTest, PythonPluginPythonOnlyTest, PublishedPythonVersionTest
@@ -46,9 +46,9 @@

Is the DSL final?DSL 은

Contributing기여하기

-

Changes go intent → spec → test → code. A behaviour change begins as a change to the specification; its test is written first and seen failing; then the code makes it pass. A DSL value is never accepted silently — it is wired to a task, or rejected with a reason.

변경은 의도 → 스펙 → 테스트 → 코드 순서로 갑니다. 동작 변경은 스펙 변경에서 시작하고, 테스트를 먼저 써서 실패를 확인한 뒤, 코드로 통과시킵니다. DSL 값은 조용히 받아들이지 않습니다 — 태스크에 연결하거나, 이유와 함께 거부합니다.

+

Changes go intent → spec → test → code. A behaviour change begins as a change to the specification; its test is written first and seen failing; then the code makes it pass. A DSL value is never accepted silently: it is wired to a task, or rejected with a reason.

변경은 의도 → 스펙 → 테스트 → 코드 순서로 갑니다. 동작 변경은 스펙 변경에서 시작하고, 테스트를 먼저 써서 실패를 확인한 뒤, 코드로 통과시킵니다. DSL 값은 조용히 받아들이지 않습니다: 태스크에 연결하거나, 이유와 함께 거부합니다.

./gradlew :toolchain:test --rerun     # plugin; needs packpack in Maven Local, uv and network
-./gradlew :tcl:test --rerun           # tcl; needs uv and network
+./gradlew :toolchain:cliTest --rerun  # tcl; needs uv and network
 python3 docs/guide/check_guide.py     # this site

Run each module on its own, and count results from build/test-results/ rather than from the console.

모듈은 따로따로 실행하고, 결과는 콘솔이 아니라 build/test-results/ 에서 세세요.

@@ -56,7 +56,7 @@

Contributing diff --git a/docs/locale/README_ko.md b/docs/locale/README_ko.md index 54a3970..8086994 100644 --- a/docs/locale/README_ko.md +++ b/docs/locale/README_ko.md @@ -1,4 +1,4 @@ -[English](../../README.md) | 한국어 +[English](https://github.com/thisisthepy/toolchain/blob/develop/README.md) | 한국어
@@ -6,13 +6,13 @@ **Kotlin Multiplatform 앱의 Python 절반을 Gradle 에 선언하고, 그대로 배포하세요.** -[![License: MIT](https://img.shields.io/badge/license-MIT-0f9d76.svg)](../../LICENSE) +[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-0f9d76.svg)](https://github.com/thisisthepy/toolchain/blob/develop/LICENSE) ![Kotlin](https://img.shields.io/badge/Kotlin-2.1-7f52ff.svg?logo=kotlin&logoColor=white) ![Gradle](https://img.shields.io/badge/Gradle-8.9-02303a.svg?logo=gradle&logoColor=white) ![Targets](https://img.shields.io/badge/targets-Android%20%7C%20iOS%20%7C%20Desktop-0f9d76.svg) ![Status](https://img.shields.io/badge/status-alpha-orange.svg) -[가이드](../guide/index.html) · [시작하기](../guide/getting-started.html) · [상태](../guide/status.html) · [생태계](../guide/ecosystem.html) +[가이드](https://thisisthepy.github.io/toolchain/index.html) · [시작하기](https://thisisthepy.github.io/toolchain/getting-started.html) · [상태](https://thisisthepy.github.io/toolchain/status.html) · [생태계](https://thisisthepy.github.io/toolchain/ecosystem.html)
@@ -21,8 +21,8 @@ ## 💡 왜 필요한가 Python 을 내장한 Kotlin Multiplatform 앱에는 맞물려 돌아가야 하는 빌드가 둘 있습니다. Gradle 이 -이미 아는 Kotlin 빌드, 그리고 Gradle 이 모르는 Python 빌드 — 인터프리터 버전, 패키지, 플랫폼별 -번들, 에셋 — 입니다. `toolchain` 은 그 간극을 메우는 Gradle 플러그인입니다. `kotlin { }` 블록 옆에 +이미 아는 Kotlin 빌드, 그리고 Gradle 이 모르는 Python 빌드(인터프리터 버전, 패키지, 플랫폼별 +번들, 에셋)입니다. `toolchain` 은 그 간극을 메우는 Gradle 플러그인입니다. `kotlin { }` 블록 옆에 `python { }` 블록 하나를 쓰면, 빌드가 Python 의존성을 설치하고, 타깃마다 코드를 번들링하고, 각 플랫폼의 패키징 단계가 가져갈 자리에 페이로드를 놓습니다. @@ -33,17 +33,17 @@ Python 을 내장한 Kotlin Multiplatform 앱에는 맞물려 돌아가야 하 ## ✨ 기능 -- 🧩 **DSL 블록 하나** — `compileSdk`, 플랫폼, `buildTypes`, `sourceSets`, `packaging` 을 모두 +- 🧩 **DSL 블록 하나**: `compileSdk`, 플랫폼, `buildTypes`, `sourceSets`, `packaging` 을 모두 `python { }` 안에. -- 📦 **실제 의존성 설치** — `implementation("pkg")` 와 `integration("pkg")` 가 `pypackpack` 을 거쳐 +- 📦 **실제 의존성 설치**: `implementation("pkg")` 와 `integration("pkg")` 가 `pypackpack` 을 거쳐 실제 `uv add` 가 됩니다. -- 🚀 **변형마다 태스크 하나** — 플랫폼 변형 × 빌드 타입마다 +- 🚀 **변형마다 태스크 하나**: 플랫폼 변형 × 빌드 타입마다 `buildPython` / `packagePython` 가 생기고, 지원되지 않는 변형은 그것만 실패합니다. -- 🔌 **산출물에 실제로 들어감** — 번들이 데스크톱 jar 의 리소스와 APK 의 `assets/` 로 스테이징됩니다. -- 🧪 **조용히 넘어가지 않음** — 알 수 없는 버전 문자열, 매핑되지 않는 플랫폼, 지원되지 않는 컴파일 +- 🔌 **산출물에 실제로 들어감**: 번들이 데스크톱 jar 의 리소스와 APK 의 `assets/` 로 스테이징됩니다. +- 🧪 **조용히 넘어가지 않음**: 알 수 없는 버전 문자열, 매핑되지 않는 플랫폼, 지원되지 않는 컴파일 레벨은 컴파일만 되고 아무 일도 안 하는 대신, 이유를 밝히며 거부됩니다. -- 🐍 **Python 사용자를 위한 `tcl`** — Gradle 프로젝트 없이 `tcl install `. +- 🐍 **Python 사용자를 위한 `tcl`**: Gradle 프로젝트 없이 `tcl install `. ## 🚀 빠른 시작 @@ -55,8 +55,14 @@ Python 을 내장한 Kotlin Multiplatform 앱에는 맞물려 돌아가야 하 ./gradlew :toolchain:publishToMavenLocal ``` +| 좌표 | 무엇 | +|---|---| +| 플러그인 id `org.thisisthepy.python.multiplatform` | Gradle 플러그인; id 로 적용 (변경 없음) | +| `org.thisisthepy.python.multiplatform:toolchain` | 플러그인 구현 아티팩트 | +| PyPI `toolchain-lite` | Python 사용자를 위한 명령줄 도구 `tcl` (`uv tool install toolchain-lite`) | + Kotlin Multiplatform 옆에 플러그인을 적용하고 `pypackpack` 패키지를 가리키게 합니다. 아래는 -`usage-example/build.gradle.kts` 를 줄인 것입니다. +`sample/build.gradle.kts` 를 줄인 것입니다. ```kotlin plugins { @@ -67,20 +73,19 @@ plugins { python { compileSdk = "3.13" - localLibraryPath = "python" // pypackpack 패키지: pyproject.toml + src/main/ + localLibraryPath = "src/commonMain/python" // pypackpack 패키지: pyproject.toml + src/main/ packaging { - fileName = "usage-example" + fileName = "sample" } } ``` ```shell -cd usage-example # 별도 빌드 (python-multiplatform 의 Kotlin 사용) -./gradlew packagePython # 설치 → 번들 → zip -./gradlew stagePythonBundle # android, ios, desktop 용 python/ 스테이징 +./gradlew -p sample packagePython # 설치 → 번들 → zip (sample/ 은 별도 빌드) +./gradlew -p sample stagePythonBundle # android, ios, desktop 용 python/ 스테이징 ``` -> **iOS, 임시:** usage-example 의 Xcode 단계(`usage-example/src/iosMain/install-python-phase.sh`)는 +> **iOS, 임시:** sample 의 Xcode 단계(`sample/src/iosMain/install-python-phase.sh`)는 > python-multiplatform#90 이 published 플러그인으로 그 배선을 제공할 때까지 `Python.xcframework` 와 stdlib 을 위해 > python-multiplatform 체크아웃을 가리키는 `PYTHON_MULTIPLATFORM_DIR` 가 필요합니다. @@ -102,7 +107,7 @@ python { Python 만 쓰나요? Gradle 빌드 없이: ```shell -./gradlew :tcl:run --args="install pythonx-compose" +./gradlew :toolchain:runTcl --args="install pythonx-compose" ``` ## 🧭 한눈에 보는 구조 @@ -122,35 +127,35 @@ flowchart LR ## 📊 현재 상태 -솔직한 요약입니다. 항목별 전체 계약은 가이드의 [상태 페이지](../guide/status.html)에 있습니다. +솔직한 요약입니다. 항목별 전체 계약은 가이드의 [상태 페이지](https://thisisthepy.github.io/toolchain/status.html)에 있습니다. | 영역 | 상태 | |---|---| -| `compileSdk` 파싱 (alpha / rc / normal) | ✅ 구현됨 | -| 플랫폼 → 타깃 트리플, Kotlin 타깃 대조, 최소 SDK | ✅ 구현됨 | -| `debug` / `release` 와 변형별 태스크 그래프 | ✅ 구현됨 | -| `uv` 를 통한 `implementation` / `integration` 의존성, 소스셋별로 변형마다 그 트리플용으로 설치해 번들에 포함 | ✅ 구현됨 | -| `instant` 레벨의 `pypackpack` 번들링 | ✅ 구현됨 | -| `bytecode` 컴파일 레벨 (`.pyc`, `compileSdk` 와 맞는 `.venv` 필요) | ✅ 구현됨 | -| `native` / `mixed` 컴파일 레벨 | ⏳ 계획 — 현재는 명시적으로 거부 | -| 데스크톱 jar 와 APK 로의 스테이징 | 🟡 부분 — iOS 는 스테이징만 되고 연결되지 않음 | -| 핫 리로드 | 🟡 부분 — Android 전용, `adb` 경유 | -| 코드 푸시 | 🟡 부분 — 검증만, 업로드 없음 | -| `buildFeatures { metaclass, compose }` | ✅ 구현됨 — compose 위치는 Gradle 속성 두 개로 지정 | +| `compileSdk` 파싱 (alpha / rc / normal) | ✅ 구현 | +| 플랫폼 → 타깃 트리플, Kotlin 타깃 대조, 최소 SDK | ✅ 구현 | +| `debug` / `release` 와 변형별 태스크 그래프 | ✅ 구현 | +| `uv` 를 통한 `implementation` / `integration` 의존성, 소스셋별로 변형마다 그 트리플용으로 설치해 번들에 포함 | ✅ 구현 | +| `instant` 레벨의 `pypackpack` 번들링 | ✅ 구현 | +| `bytecode` 컴파일 레벨 (`.pyc`, `compileSdk` 와 맞는 `.venv` 필요) | ✅ 구현 | +| `native` / `mixed` 컴파일 레벨 | ⏳ 계획: 현재는 명시적으로 거부 | +| 데스크톱 jar 와 APK 로의 스테이징 | 🟡 부분: iOS 는 스테이징만 되고 연결되지 않음 | +| 핫 리로드 | 🟡 부분: Android 전용, `adb` 경유 | +| 코드 푸시 | 🟡 부분: 검증만, 업로드 없음 | +| `buildFeatures { metaclass, compose }` | ✅ 구현: compose 위치는 Gradle 속성 두 개로 지정 | | `embedLevel`, `projectFlavors`, `pip { }` | ⏳ 계획 | -| `tcl install` | ✅ 구현됨 | +| `tcl install` | ✅ 구현 | ## 📖 문서 -- **[가이드](../guide/index.html)** — 개념, 작업별 가이드, 상태. 영어와 한국어. -- **[English README](../../README.md)** +- **[가이드](https://thisisthepy.github.io/toolchain/index.html)**: 개념, 작업별 가이드, 상태. 영어와 한국어. +- **[English README](https://github.com/thisisthepy/toolchain/blob/develop/README.md)** ## 🤝 기여 이 저장소의 작업은 의도 → 스펙 → 테스트 → 코드 순서로 진행합니다. 동작을 바꾸려면 스펙부터 바꾸고, 그 테스트를 먼저 작성해 실패하는 것을 확인한 뒤 구현합니다. 테스트 실행 방법은 가이드의 -[기여 안내](../guide/status.html#contributing)에 있습니다. +[기여 안내](https://thisisthepy.github.io/toolchain/status.html#contributing)에 있습니다. ## 📄 라이선스 -[MIT](../../LICENSE) © 2024 thisisthepy +[Apache-2.0](https://github.com/thisisthepy/toolchain/blob/develop/LICENSE) © 2024 thisisthepy diff --git a/docs/pypi/README.md b/docs/pypi/README.md new file mode 100644 index 0000000..0b2fe9e --- /dev/null +++ b/docs/pypi/README.md @@ -0,0 +1,43 @@ +# toolchain-lite + +**`tcl`: add Python packages to a project from the command line, no Gradle project needed.** + +toolchain-lite is the command-line side of [toolchain](https://github.com/thisisthepy/toolchain), the +Gradle plugin that declares the Python half of a Kotlin Multiplatform app. `tcl` gives Python users +the same dependency step without a Gradle build. + +## Install + +```shell +uv tool install toolchain-lite # puts tcl on PATH +tcl --help +uvx --from toolchain-lite tcl --version # or run it without installing +``` + +The wheel carries `tcl` as a native binary (GraalVM Native Image), one wheel per platform: macOS 11+ +on Apple silicon, Linux x86_64 and aarch64 (glibc), Windows x86_64. There is no source distribution: +building needs a JDK and GraalVM. + +`uv` is needed at run time. When none is on `PATH`, `tcl` downloads one into `~/.pypackpack/uv`. + +## Use + +```shell +mkdir myapp && cd myapp +tcl install six # creates pyproject.toml (uv init --bare) if there is none, then adds six +``` + +`tcl install ` finds the nearest `pyproject.toml` at or above the current directory, creates +one if there is none, and adds the package with uv. It exits 0 on success and 1 with a message +otherwise. + +## Status + +`tcl install` is implemented and tested. Everything else in the plan for `tcl` +([issue #1](https://github.com/thisisthepy/toolchain/issues/1)) is not built yet. + +## Links + +- [Guide: tcl for Python users](https://thisisthepy.github.io/toolchain/guide-tcl.html) +- [Source](https://github.com/thisisthepy/toolchain/tree/develop/tcl) +- [Licence: Apache-2.0](https://github.com/thisisthepy/toolchain/blob/develop/LICENSE) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0..e2847c8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock deleted file mode 100644 index 8001f2e..0000000 --- a/kotlin-js-store/yarn.lock +++ /dev/null @@ -1,2886 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" - integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/source-map@^0.3.3": - version "0.3.11" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" - integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" - integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== - -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.31" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" - integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@js-joda/core@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" - integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" - integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== - -"@socket.io/component-emitter@~3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" - integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== - -"@types/body-parser@*": - version "1.19.6" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" - integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.13" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" - integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== - dependencies: - "@types/node" "*" - -"@types/connect-history-api-fallback@^1.3.5": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" - integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - -"@types/cors@^2.8.12": - version "2.8.19" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.19.tgz#d93ea2673fd8c9f697367f5eeefc2bbfa94f0342" - integrity sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg== - dependencies: - "@types/node" "*" - -"@types/estree@^1.0.5": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24" - integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": - version "5.1.3" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.1.3.tgz#9d34c88c0c9ee62b9a6e4d9f8ab8d7e29688e6b4" - integrity sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express-serve-static-core@^4.17.33": - version "4.19.9" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.9.tgz#b746a8bb6c389af7a31141397bb539f775b0ae84" - integrity sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@*": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.6.tgz#2d724b2c990dcb8c8444063f3580a903f6d500cc" - integrity sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^5.0.0" - "@types/serve-static" "^2" - -"@types/express@^4.17.13": - version "4.17.25" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b" - integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "^1" - -"@types/http-errors@*": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" - integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== - -"@types/http-proxy@^1.17.8": - version "1.17.17" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.17.tgz#d9e2c4571fe3507343cb210cd41790375e59a533" - integrity sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw== - dependencies: - "@types/node" "*" - -"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/mime@^1": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" - integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== - -"@types/node-forge@^1.3.0": - version "1.3.14" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.14.tgz#006c2616ccd65550560c2757d8472eb6d3ecea0b" - integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw== - dependencies: - "@types/node" "*" - -"@types/node@*", "@types/node@>=10.0.0": - version "26.2.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-26.2.0.tgz#5a4875a862fda8fdc57de8faa579bb81ecba1685" - integrity sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg== - dependencies: - undici-types "~8.3.0" - -"@types/qs@*": - version "6.15.1" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.15.1.tgz#8606884272c63f0db96986bd3548650d8a9388bf" - integrity sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw== - -"@types/range-parser@*": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - -"@types/send@*": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74" - integrity sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ== - dependencies: - "@types/node" "*" - -"@types/send@<1": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25" - integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-index@^1.9.1": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" - integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== - dependencies: - "@types/express" "*" - -"@types/serve-static@^1", "@types/serve-static@^1.13.10": - version "1.15.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" - integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - "@types/send" "<1" - -"@types/serve-static@^2": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-2.2.0.tgz#d4a447503ead0d1671132d1ab6bd58b805d8de6a" - integrity sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.36" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" - integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== - dependencies: - "@types/node" "*" - -"@types/ws@^8.5.12", "@types/ws@^8.5.5": - version "8.18.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" - integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== - dependencies: - "@types/node" "*" - -"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.12.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" - integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== - dependencies: - "@webassemblyjs/helper-numbers" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - -"@webassemblyjs/floating-point-hex-parser@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" - integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== - -"@webassemblyjs/helper-api-error@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" - integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== - -"@webassemblyjs/helper-buffer@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" - integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== - -"@webassemblyjs/helper-numbers@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" - integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.13.2" - "@webassemblyjs/helper-api-error" "1.13.2" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" - integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== - -"@webassemblyjs/helper-wasm-section@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" - integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/wasm-gen" "1.14.1" - -"@webassemblyjs/ieee754@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" - integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" - integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" - integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== - -"@webassemblyjs/wasm-edit@^1.12.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" - integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/helper-wasm-section" "1.14.1" - "@webassemblyjs/wasm-gen" "1.14.1" - "@webassemblyjs/wasm-opt" "1.14.1" - "@webassemblyjs/wasm-parser" "1.14.1" - "@webassemblyjs/wast-printer" "1.14.1" - -"@webassemblyjs/wasm-gen@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" - integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wasm-opt@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" - integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/wasm-gen" "1.14.1" - "@webassemblyjs/wasm-parser" "1.14.1" - -"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.12.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" - integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-api-error" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wast-printer@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" - integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" - integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== - -"@webpack-cli/info@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" - integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== - -"@webpack-cli/serve@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" - integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -accepts@~1.3.4, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-import-attributes@^1.9.5: - version "1.9.5" - resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" - integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== - -acorn@^8.15.0, acorn@^8.7.1: - version "8.18.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.18.0.tgz#4faf01b2d6d326bfeed97aea1f52220b5f4c1940" - integrity sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ== - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.12.5: - version "6.15.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.15.0.tgz#07e982c74626167aa7a2495c53817892d7139492" - integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.9.0: - version "8.20.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.20.0.tgz#304b3636add88ba7d936760dd50ece006dea95f9" - integrity sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -ansi-colors@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64id@2.0.0, base64id@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" - integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== - -baseline-browser-mapping@^2.11.12: - version "2.11.14" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.14.tgz#d51bb92285608b0e6356841a2eea76842a771d52" - integrity sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - -binary-extensions@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" - integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== - -body-parser@^1.19.0, body-parser@~1.20.5: - version "1.20.6" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.6.tgz#60c789c78e0992d906da0a29d71ae01d15c1ed76" - integrity sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g== - dependencies: - bytes "~3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "~1.2.0" - http-errors "~2.0.1" - iconv-lite "~0.4.24" - on-finished "~2.4.1" - qs "~6.15.1" - raw-body "~2.5.3" - type-is "~1.6.18" - unpipe "~1.0.0" - -bonjour-service@^1.0.11: - version "1.4.4" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.4.4.tgz#8ff5b85fa0641e0996bf40bcf61fc0c6727b66d3" - integrity sha512-jCZcVv7eoc4QesRscwEZtSROBen+6LpKAmBIsQYQrsAeVHLyMXWX/t6eIV5KiRZYNUBl8eVqImEEMQ8L5+c/Kw== - dependencies: - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - -brace-expansion@^1.1.7: - version "1.1.18" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.18.tgz#3ce74d89885136be1535341f8c3d4425c29a5cab" - integrity sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1, brace-expansion@^2.0.2: - version "2.1.4" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.4.tgz#589dab11c0018d0366be64cd8bf12c8dbecc8326" - integrity sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@^3.0.3, braces@~3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -browser-stdout@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserslist@^4.21.10: - version "4.28.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.8.tgz#a3c79ceb70028527e5da7dafc887f3200b5168c0" - integrity sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA== - dependencies: - baseline-browser-mapping "^2.11.12" - caniuse-lite "^1.0.30001809" - electron-to-chromium "^1.5.402" - node-releases "^2.0.53" - update-browserslist-db "^1.3.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -bytes@3.1.2, bytes@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" - integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - -call-bound@^1.0.2, call-bound@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" - integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== - dependencies: - call-bind-apply-helpers "^1.0.2" - get-intrinsic "^1.3.0" - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001809: - version "1.0.30001809" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz#e6cf71f14ddfe008f114dd2a846923be3c03a07b" - integrity sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ== - -chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chokidar@^3.5.1, chokidar@^3.5.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" - integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -commander@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -compressible@~2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.8.1" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" - integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== - dependencies: - bytes "3.1.2" - compressible "~2.0.18" - debug "2.6.9" - negotiator "~0.6.4" - on-headers "~1.1.0" - safe-buffer "5.2.1" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - -connect@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" - integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== - dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" - -content-disposition@~0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-signature@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" - integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== - -cookie@~0.7.1, cookie@~0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" - integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cors@~2.8.5: - version "2.8.6" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.6.tgz#ff5dd69bd95e547503820d29aba4f8faf8dfec96" - integrity sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw== - dependencies: - object-assign "^4" - vary "^1" - -cross-spawn@^7.0.3: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -custom-event@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" - integrity sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg== - -date-format@^4.0.14: - version "4.0.14" - resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" - integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.1.0, debug@^4.3.4, debug@^4.3.5, debug@~4.4.1: - version "4.4.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -depd@2.0.0, depd@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -destroy@1.2.0, destroy@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -di@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" - integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== - -diff@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.2.tgz#0a4742797281d09cfa699b79ea32d27723623bad" - integrity sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A== - -dns-packet@^5.2.2: - version "5.6.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" - integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -dom-serialize@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" - integrity sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ== - dependencies: - custom-event "~1.0.0" - ent "~2.2.0" - extend "^3.0.0" - void-elements "^2.0.0" - -dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.5.402: - version "1.5.407" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.407.tgz#c34e509f8644a7375fdaa5ea5cb7ca73eeaf18df" - integrity sha512-4R8XgQOdfxexCd/u63lRm6wCHjECwI45MV9wxAs2ggtfWe2hwlo1ql97jKsju2IcJ+jFSTwBssyYoiWhh7mauQ== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - -engine.io-parser@~5.2.1: - version "5.2.3" - resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f" - integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q== - -engine.io@~6.6.0: - version "6.6.9" - resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.6.9.tgz#fd17e9f4e3a256423592574b60ac262e91af4b82" - integrity sha512-clKkw4C7nJ22mGgoVcCg6V/W/TxdNyIOTr89k2ONZu81qqkddPFDF0LXcbAwhzPD8DjkiRCjzuiO6Y+fkpD4vg== - dependencies: - "@types/cors" "^2.8.12" - "@types/node" ">=10.0.0" - "@types/ws" "^8.5.12" - accepts "~1.3.4" - base64id "2.0.0" - cookie "~0.7.2" - cors "~2.8.5" - debug "~4.4.1" - engine.io-parser "~5.2.1" - ws "~8.21.0" - -enhanced-resolve@^5.17.1: - version "5.24.5" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz#b4dad3255b7545f07ba5535189868e9f85f47573" - integrity sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.3.3" - -ent@~2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.2.tgz#22a5ed2fd7ce0cbcff1d1474cf4909a44bdb6e85" - integrity sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw== - dependencies: - call-bound "^1.0.3" - es-errors "^1.3.0" - punycode "^1.4.1" - safe-regex-test "^1.1.0" - -envinfo@^7.7.3: - version "7.21.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.21.0.tgz#04a251be79f92548541f37d13c8b6f22940c3bae" - integrity sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow== - -es-define-property@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" - integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-module-lexer@^1.2.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" - integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== - -es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz#a2d0b373205724dfa525d23b0c3e1b1ca582c99b" - integrity sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw== - dependencies: - es-errors "^1.3.0" - -escalade@^3.1.1, escalade@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" - integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.3: - version "4.22.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.22.2.tgz#c17ae0981e5efc24b22272f0e041c4662503b700" - integrity sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "~1.20.5" - content-disposition "~0.5.4" - content-type "~1.0.4" - cookie "~0.7.1" - cookie-signature "~1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.3.1" - fresh "~0.5.2" - http-errors "~2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "~2.4.1" - parseurl "~1.3.3" - path-to-regexp "~0.1.12" - proxy-addr "~2.0.7" - qs "~6.15.1" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "~0.19.0" - serve-static "~1.16.2" - setprototypeof "1.2.0" - statuses "~2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-uri@^3.0.1: - version "3.1.5" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.5.tgz#610f37419a030270430cecd68d74e3d4d96725d0" - integrity sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw== - -fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -finalhandler@~1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" - integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== - dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "~2.4.1" - parseurl "~1.3.3" - statuses "~2.0.2" - unpipe "~1.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.2.7: - version "3.4.4" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.4.tgz#aeeca2a506303f0cee61c59e6c9f2a88d2f29fc6" - integrity sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q== - -follow-redirects@^1.0.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.16.0.tgz#28474a159d3b9d11ef62050a14ed60e4df6d61bc" - integrity sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw== - -format-util@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" - integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-monkey@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.1.0.tgz#632aa15a20e71828ed56b24303363fb1414e5997" - integrity sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" - integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== - dependencies: - call-bind-apply-helpers "^1.0.2" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - function-bind "^1.1.2" - get-proto "^1.0.1" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.1.0" - -get-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" - integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== - dependencies: - dunder-proto "^1.0.1" - es-object-atoms "^1.0.0" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@^7.1.3, glob@^7.1.7: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.3, has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - -has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -hasown@^2.0.2, hasown@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.4.tgz#8c62d8cb90beb2aad5d0a5b67581ad9854c3f003" - integrity sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A== - dependencies: - function-bind "^1.1.2" - -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" - integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - -http-errors@~1.8.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -http-errors@~2.0.0, http-errors@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" - integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== - dependencies: - depd "~2.0.0" - inherits "~2.0.4" - setprototypeof "~1.2.0" - statuses "~2.0.2" - toidentifier "~1.0.1" - -http-parser-js@>=0.5.1: - version "0.5.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.10.tgz#b3277bd6d7ed5588e20ea73bf724fcbe44609075" - integrity sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA== - -http-proxy-middleware@^2.0.3: - version "2.0.10" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.10.tgz#b2df7b705203d7a8c269ac8450cf96b00c532f94" - integrity sha512-RKzRWNPxUZqbuk3BC5mGVJbBnWgr+diEnjJexIOytFbBzDy88Fbh/YvBr3DsNrl1jYAfjWfpATEv0NO35FDuPQ== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -iconv-lite@~0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -import-local@^3.0.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" - integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -interpret@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" - integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.5.0.tgz#7d4b6c39f9392fb61cf807de6e425e22c10e061f" - integrity sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-core-module@^2.16.1: - version "2.16.2" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.2.tgz#3e07450a8080ebce3fbf0cac494f4d2ab324e082" - integrity sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA== - dependencies: - hasown "^2.0.3" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-regex@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" - integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== - dependencies: - call-bound "^1.0.2" - gopd "^1.2.0" - has-tostringtag "^1.0.2" - hasown "^2.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isbinaryfile@^4.0.8: - version "4.0.10" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" - integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -js-yaml@^4.1.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848" - integrity sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ== - dependencies: - argparse "^2.0.1" - -json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -karma-chrome-launcher@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz#eb9c95024f2d6dfbb3748d3415ac9b381906b9a9" - integrity sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q== - dependencies: - which "^1.2.1" - -karma-mocha@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/karma-mocha/-/karma-mocha-2.0.1.tgz#4b0254a18dfee71bdbe6188d9a6861bf86b0cd7d" - integrity sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ== - dependencies: - minimist "^1.2.3" - -karma-sourcemap-loader@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/karma-sourcemap-loader/-/karma-sourcemap-loader-0.4.0.tgz#b01d73f8f688f533bcc8f5d273d43458e13b5488" - integrity sha512-xCRL3/pmhAYF3I6qOrcn0uhbQevitc2DERMPH82FMnG+4WReoGcGFZb1pURf2a5apyrOHRdvD+O6K7NljqKHyA== - dependencies: - graceful-fs "^4.2.10" - -karma-webpack@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.1.tgz#4eafd31bbe684a747a6e8f3e4ad373e53979ced4" - integrity sha512-oo38O+P3W2mSPCSUrQdySSPv1LvPpXP+f+bBimNomS5sW+1V4SuhCuW8TfJzV+rDv921w2fDSDw0xJbPe6U+kQ== - dependencies: - glob "^7.1.3" - minimatch "^9.0.3" - webpack-merge "^4.1.5" - -karma@6.4.4: - version "6.4.4" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.4.tgz#dfa5a426cf5a8b53b43cd54ef0d0d09742351492" - integrity sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w== - dependencies: - "@colors/colors" "1.5.0" - body-parser "^1.19.0" - braces "^3.0.2" - chokidar "^3.5.1" - connect "^3.7.0" - di "^0.0.1" - dom-serialize "^2.2.1" - glob "^7.1.7" - graceful-fs "^4.2.6" - http-proxy "^1.18.1" - isbinaryfile "^4.0.8" - lodash "^4.17.21" - log4js "^6.4.1" - mime "^2.5.2" - minimatch "^3.0.4" - mkdirp "^0.5.5" - qjobs "^1.2.0" - range-parser "^1.2.1" - rimraf "^3.0.2" - socket.io "^4.7.2" - source-map "^0.6.1" - tmp "^0.2.1" - ua-parser-js "^0.7.30" - yargs "^16.1.1" - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kotlin-web-helpers@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/kotlin-web-helpers/-/kotlin-web-helpers-2.0.0.tgz#b112096b273c1e733e0b86560998235c09a19286" - integrity sha512-xkVGl60Ygn/zuLkDPx+oHj7jeLR7hCvoNF99nhwXMn8a3ApB4lLiC9pk4ol4NHPjyoCbvQctBqvzUcp8pkqyWw== - dependencies: - format-util "^1.0.5" - -launch-editor@^2.6.0: - version "2.14.1" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.14.1.tgz#f7e0da3f58aaea03fea01074d840b5f739ed7ddc" - integrity sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA== - dependencies: - picocolors "^1.1.1" - shell-quote "^1.8.4" - -loader-runner@^4.2.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.2.tgz#9913d3a15971f8f635915e601fb5c9d495d918e9" - integrity sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash@^4.17.15, lodash@^4.17.21: - version "4.18.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.18.1.tgz#ff2b66c1f6326d59513de2407bf881439812771c" - integrity sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q== - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log4js@^6.4.1: - version "6.9.1" - resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.9.1.tgz#aba5a3ff4e7872ae34f8b4c533706753709e38b6" - integrity sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g== - dependencies: - date-format "^4.0.14" - debug "^4.3.4" - flatted "^3.2.7" - rfdc "^1.3.0" - streamroller "^3.1.5" - -math-intrinsics@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - -merge-descriptors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.2: - version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" - integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== - dependencies: - braces "^3.0.3" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -"mime-db@>= 1.43.0 < 2": - version "1.54.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34, mime-types@~2.1.35: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.5.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@^3.0.4, minimatch@^3.1.1: - version "3.1.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" - integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1, minimatch@^5.1.6: - version "5.1.9" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.9.tgz#1293ef15db0098b394540e8f9f744f9fda8dee4b" - integrity sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.3: - version "9.0.9" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.9.tgz#9b0cb9fcb78087f6fd7eababe2511c4d3d60574e" - integrity sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg== - dependencies: - brace-expansion "^2.0.2" - -minimist@^1.2.3, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp@^0.5.5: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mocha@10.7.3: - version "10.7.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" - integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== - dependencies: - ansi-colors "^4.1.3" - browser-stdout "^1.3.1" - chokidar "^3.5.3" - debug "^4.3.5" - diff "^5.2.0" - escape-string-regexp "^4.0.0" - find-up "^5.0.0" - glob "^8.1.0" - he "^1.2.0" - js-yaml "^4.1.0" - log-symbols "^4.1.0" - minimatch "^5.1.6" - ms "^2.1.3" - serialize-javascript "^6.0.2" - strip-json-comments "^3.1.1" - supports-color "^8.1.1" - workerpool "^6.5.1" - yargs "^16.2.0" - yargs-parser "^20.2.9" - yargs-unparser "^2.0.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.3, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -negotiator@~0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-forge@^1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.4.0.tgz#1c7b7d8bdc2d078739f58287d589d903a11b2fc2" - integrity sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ== - -node-releases@^2.0.53: - version "2.0.53" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.53.tgz#0fe5ad8a7935e075172f574e56f0c20f07fa41af" - integrity sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -object-assign@^4: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.13.3, object-inspect@^1.13.4: - version "1.13.4" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" - integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== - dependencies: - ee-first "1.1.1" - -on-finished@~2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -on-headers@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" - integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@~0.1.12: - version "0.1.13" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.13.tgz#9b22ec16bc3ab88d05a0c7e369869421401ab17d" - integrity sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA== - -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601" - integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -qjobs@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" - integrity sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg== - -qs@~6.15.1: - version "6.15.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.3.tgz#76852132a58ed5c7c0ef67e4441b9bb5d6061b3b" - integrity sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A== - dependencies: - es-define-property "^1.0.1" - side-channel "^1.1.1" - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.3.0.tgz#d7f19be812bb62721472b45d3be219ef09572b47" - integrity sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@~2.5.3: - version "2.5.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" - integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== - dependencies: - bytes "~3.1.2" - http-errors "~2.0.1" - iconv-lite "~0.4.24" - unpipe "~1.0.0" - -readable-stream@^2.0.1: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" - integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== - dependencies: - resolve "^1.20.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@^1.20.0: - version "1.22.12" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f" - integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA== - dependencies: - es-errors "^1.3.0" - is-core-module "^2.16.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -rfdc@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" - integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex-test@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" - integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - is-regex "^1.2.1" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-utils@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0, schema-utils@^4.3.0: - version "4.3.3" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" - integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^2.1.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" - integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== - dependencies: - "@types/node-forge" "^1.3.0" - node-forge "^1" - -send@~0.19.0, send@~0.19.1: - version "0.19.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" - integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "~0.5.2" - http-errors "~2.0.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.4.1" - range-parser "~1.2.1" - statuses "~2.0.2" - -serialize-javascript@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.2" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.2.tgz#2988e3612106d78a5e4849ddff552ce7bd3d9bcb" - integrity sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ== - dependencies: - accepts "~1.3.8" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.8.0" - mime-types "~2.1.35" - parseurl "~1.3.3" - -serve-static@~1.16.2: - version "1.16.3" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" - integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== - dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "~0.19.1" - -setprototypeof@1.2.0, setprototypeof@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.8.4: - version "1.10.0" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.10.0.tgz#482033e192e4f5c07151521ffa03400ec71b1b0f" - integrity sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA== - -side-channel-list@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127" - integrity sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.4" - -side-channel-map@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" - integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - -side-channel-weakmap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" - integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - side-channel-map "^1.0.1" - -side-channel@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.1.tgz#ea02c62e05dc4bea67d4442f0fb71ee192f8e0ab" - integrity sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.4" - side-channel-list "^1.0.1" - side-channel-map "^1.0.1" - side-channel-weakmap "^1.0.2" - -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -socket.io-adapter@~2.5.2: - version "2.5.8" - resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.8.tgz#c9fcabf602dbd5b09258ca98e5ec6a7ae4360698" - integrity sha512-6Oy52pbg+kvdCVvjcN+FnY7BvxZ7cIHNScbvztT/It5d0vbwoJoVZmF2gjJmnV0/4WlXRfG15zc45ySk9Ah8bw== - dependencies: - debug "~4.4.1" - ws "~8.21.0" - -socket.io-parser@~4.2.4: - version "4.2.7" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.7.tgz#679e51fe24d1c81df90fc5f7efe4a5f432fe99c0" - integrity sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg== - dependencies: - "@socket.io/component-emitter" "~3.1.0" - debug "~4.4.1" - -socket.io@^4.7.2: - version "4.8.3" - resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.8.3.tgz#ca6ba1431c69532e1e0a6f496deebeb601dbc4df" - integrity sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A== - dependencies: - accepts "~1.3.4" - base64id "~2.0.0" - cors "~2.8.5" - debug "~4.4.1" - engine.io "~6.6.0" - socket.io-adapter "~2.5.2" - socket.io-parser "~4.2.4" - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-js@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" - integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== - -source-map-loader@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-5.0.0.tgz#f593a916e1cc54471cfc8851b905c8a845fc7e38" - integrity sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA== - dependencies: - iconv-lite "^0.6.3" - source-map-js "^1.0.2" - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -statuses@~2.0.1, statuses@~2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" - integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== - -streamroller@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.1.5.tgz#1263182329a45def1ffaef58d31b15d13d2ee7ff" - integrity sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw== - dependencies: - date-format "^4.0.14" - debug "^4.3.4" - fs-extra "^8.1.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0, supports-color@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -tapable@^2.1.1, tapable@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160" - integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A== - -terser-webpack-plugin@^5.3.10: - version "5.6.1" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz#47bc41bd8b8fab8383b62ec763b7394829097e7b" - integrity sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ== - dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - jest-worker "^27.4.5" - schema-utils "^4.3.0" - terser "^5.31.1" - -terser@^5.31.1: - version "5.50.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.50.0.tgz#4e560a46704f9172f96ba31c3bd6dc108ad2cead" - integrity sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.15.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -tmp@^0.2.1: - version "0.2.7" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.7.tgz#26f4db11d1601ce8012dcb8a798ece1c06a99059" - integrity sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1, toidentifier@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typescript@5.5.4: - version "5.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" - integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== - -ua-parser-js@^0.7.30: - version "0.7.41" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.41.tgz#9f6dee58c389e8afababa62a4a2dc22edb69a452" - integrity sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg== - -undici-types@~8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-8.3.0.tgz#44e9fc9f3244648cdea35e4f9bb2d681e9410809" - integrity sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ== - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -update-browserslist-db@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz#a71c28dd22f505481dbc4689087b18d933e90afd" - integrity sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ== - dependencies: - escalade "^3.2.0" - picocolors "^1.1.1" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -void-elements@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== - -watchpack@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.2.tgz#e12e82d84674266fc1c6dbfe38891b92ff0522ec" - integrity sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg== - dependencies: - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-cli@5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" - integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^2.1.1" - "@webpack-cli/info" "^2.0.2" - "@webpack-cli/serve" "^2.0.5" - colorette "^2.0.14" - commander "^10.0.1" - cross-spawn "^7.0.3" - envinfo "^7.7.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^3.1.1" - rechoir "^0.8.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^5.3.4: - version "5.3.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" - integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@4.15.2: - version "4.15.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz#9e0c70a42a012560860adb186986da1248333173" - integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.5" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.4" - ws "^8.13.0" - -webpack-merge@^4.1.5: - version "4.2.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" - integrity sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g== - dependencies: - lodash "^4.17.15" - -webpack-merge@^5.7.3: - version "5.10.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" - integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== - dependencies: - clone-deep "^4.0.1" - flat "^5.0.2" - wildcard "^2.0.0" - -webpack-sources@^3.2.3: - version "3.5.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.5.1.tgz#76c2418486dcc02b2aa0694c104176c2858fe84a" - integrity sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw== - -webpack@5.94.0: - version "5.94.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" - integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== - dependencies: - "@types/estree" "^1.0.5" - "@webassemblyjs/ast" "^1.12.1" - "@webassemblyjs/wasm-edit" "^1.12.1" - "@webassemblyjs/wasm-parser" "^1.12.1" - acorn "^8.7.1" - acorn-import-attributes "^1.9.5" - browserslist "^4.21.10" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" - es-module-lexer "^1.2.1" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.11" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.10" - watchpack "^2.4.1" - webpack-sources "^3.2.3" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.5" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.5.tgz#569d22764ab21f2de20af0e74b411e8ae5a0fa46" - integrity sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -which@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wildcard@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" - integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== - -workerpool@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" - integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^8.13.0, ws@~8.21.0: - version "8.21.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.3.tgz#660b4faddb6a3e575c86e078126919961f4de4fc" - integrity sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yargs-parser@^20.2.2, yargs-parser@^20.2.9: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-unparser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@^16.1.1, yargs@^16.2.0: - version "16.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.2.tgz#c56731dca0d2788ae0866dd3c83907d6bab85f7d" - integrity sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/pyproject.toml b/pyproject.toml index c0a92ca..f871f0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,65 +1,44 @@ +# toolchain-lite, the PyPI distribution of `tcl`. The wheel carries the native `tcl` command line +# (GraalVM Native Image) and is assembled per platform by .github/scripts/pypi/build_wheel.py in +# publish-pypi.yml, which reads [project] below. Its version must equal toolchain/build.gradle.kts's tclVersion: the +# workflow refuses to publish unless the installed binary prints it. +# +# Installing from source (`uv pip install .`) gives only the Python package, without the binary; +# `python -m toolchain_lite` then says so and exits. [build-system] -requires = ["flit_core>=3.4,<4"] -build-backend = "flit_core.buildapi" +requires = ["setuptools>=77"] +build-backend = "setuptools.build_meta" [project] -name = "toolchain" -version = "0.0.1" -description = "Python Multiplatform Build Plugin/Tool with Kotlin Multiplatform Mobile" -readme = "README.md" -requires-python = ">=3.9, <3.14" -license = {file = "LICENSE"} +name = "toolchain-lite" +version = "0.1.0" +description = "tcl: install Python packages for a Kotlin Multiplatform app's Python half, no Gradle project needed" +readme = "docs/pypi/README.md" +license = "Apache-2.0" +license-files = ["LICENSE"] authors = [ - {name = "THISISTHEPY", email = "thisisthepy@gmail.com"} + { name = "thisisthepy", email = "thisisthepy@gmail.com" }, ] +keywords = ["kotlin-multiplatform", "python", "uv", "packaging"] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", + "Operating System :: MacOS", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", "Topic :: Software Development :: Build Tools", ] -dependencies = [ -] - -[project.optional-dependencies] -dev = [ - "pytest>=7.0.0", - "black>=23.0.0", - "isort>=5.12.0", - "mypy>=1.0.0", -] -docs = [ - "sphinx>=6.0.0", - "sphinx-rtd-theme>=1.2.0", -] +requires-python = ">=3.9" +dependencies = [] [project.urls] -"Homepage" = "https://github.com/thisisthepy/toolchain" -"Bug Tracker" = "https://github.com/thisisthepy/toolchain/issues" -"Documentation" = "https://thisisthepy.github.io/" - -[tool.flit.module] -name = "toolchain" - -[tool.black] -line-length = 88 -target-version = ["py39", "py310", "py311", "py312"] - -[tool.isort] -profile = "black" -line_length = 88 +Homepage = "https://github.com/thisisthepy/toolchain" +Documentation = "https://thisisthepy.github.io/toolchain/guide-tcl.html" +Repository = "https://github.com/thisisthepy/toolchain" +Issues = "https://github.com/thisisthepy/toolchain/issues" -[tool.mypy] -python_version = "3.9" -warn_return_any = true -warn_unused_configs = true -disallow_untyped_defs = true -disallow_incomplete_defs = true +[tool.setuptools] +package-dir = { toolchain_lite = "toolchain/src/cliMain/python" } +packages = ["toolchain_lite"] diff --git a/usage-example/build.gradle.kts b/sample/build.gradle.kts similarity index 89% rename from usage-example/build.gradle.kts rename to sample/build.gradle.kts index b3481d6..34b8c40 100644 --- a/usage-example/build.gradle.kts +++ b/sample/build.gradle.kts @@ -13,14 +13,14 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.compose.multiplatform) alias(libs.plugins.compose.compiler) - // usage-example is its own build (settings.gradle.kts here). The toolchain plugin is resolved by + // sample is its own build (settings.gradle.kts here). The toolchain plugin is resolved by // coordinate from mavenLocal (`./gradlew :toolchain:publishToMavenLocal` in ../), as is // python-multiplatform's bindings plugin, which stages and packages the CPython stdlib (#22). alias(libs.plugins.toolchain) alias(libs.plugins.python.multiplatform.bindings) } -// Exercises the target DSL surface end to end -- until now `usage-example` did not apply the +// Exercises the target DSL surface end to end -- until now `sample` did not apply the // plugin at all, so the DSL in `dsl/` had no executable definition (`docs/ecosystem.md` §2, §4 // item 7). This is deliberately the subset of `(플러그인예시)build.gradle.kts` that today's tasks // (`PythonPlugin.kt`) actually read: `compileSdk`, `packaging`, `buildTypes`, `platforms`, and @@ -33,7 +33,7 @@ python { // -- the zip, and now the staging tasks -- correctly produces nothing, which makes "the artifact // contains Python" unfalsifiable. `example_py` deliberately includes a non-`.py` file, because // `ResourceBundler` carries data files next to modules and staging has to preserve that. - localLibraryPath = "python" + localLibraryPath = "src/commonMain/python" // One real dependency, so a bundle and the packaged desktop app prove that installed packages // arrive (CI's consumer and desktop-e2e jobs; the --python-smoke mode imports it). sourceSets { @@ -56,7 +56,7 @@ python { } } packaging { - fileName = "usage-example" + fileName = "sample" } // `compose = true` is left out: it needs `python.compose.pythonxCompose` and // `python.compose.kotlinModule`, and neither artifact is published yet (docs/SPEC.md §1.16). @@ -180,3 +180,12 @@ compose.desktop { } } } + +// The wasm target's yarn lock lives in this build's gradle/ rather than a kotlin-js-store/ at the root +// (toolchain#62; the same decision as python-multiplatform #110). +plugins.withType { + extensions.getByType().apply { + lockFileDirectoryProperty.set(layout.projectDirectory.dir("gradle")) + lockFileNameProperty.set("wasm-yarn.lock") + } +} diff --git a/usage-example/gradle.properties b/sample/gradle.properties similarity index 100% rename from usage-example/gradle.properties rename to sample/gradle.properties diff --git a/usage-example/gradle/libs.versions.toml b/sample/gradle/libs.versions.toml similarity index 95% rename from usage-example/gradle/libs.versions.toml rename to sample/gradle/libs.versions.toml index 5e4f42c..25d1651 100644 --- a/usage-example/gradle/libs.versions.toml +++ b/sample/gradle/libs.versions.toml @@ -1,4 +1,4 @@ -# usage-example is its own build (toolchain#22): a consumer of python-multiplatform, so it uses +# sample/ is its own build (toolchain#22): a consumer of python-multiplatform, so it uses # python-multiplatform's toolchain (its gradle/libs.versions.toml), not the toolchain plugin's. # The plugin itself (../toolchain) stays on its own Kotlin for its consumers. [versions] diff --git a/usage-example/settings.gradle.kts b/sample/settings.gradle.kts similarity index 67% rename from usage-example/settings.gradle.kts rename to sample/settings.gradle.kts index 9d87156..0a3439c 100644 --- a/usage-example/settings.gradle.kts +++ b/sample/settings.gradle.kts @@ -1,6 +1,7 @@ -// usage-example is its own Gradle build (toolchain#22). It consumes python-multiplatform, which is -// built with Kotlin 2.4, so it uses that toolchain (gradle/libs.versions.toml here); the toolchain -// plugin in ../toolchain stays on its own Kotlin for its consumers. Both plugins and the +// sample/ is its own Gradle build (toolchain#22, #62), run with the repository's wrapper: +// ./gradlew -p sample …. It consumes python-multiplatform, which is built with Kotlin 2.4, so it uses +// that toolchain (gradle/libs.versions.toml here); the plugin in ../toolchain stays on +// its own Kotlin for its consumers. Both plugins and the // python-multiplatform library come from mavenLocal: publish them first (see AGENTS.md §16). pluginManagement { repositories { @@ -31,4 +32,4 @@ dependencyResolutionManagement { } } -rootProject.name = "usage-example" +rootProject.name = "sample" diff --git a/usage-example/src/androidMain/AndroidManifest.xml b/sample/src/androidMain/AndroidManifest.xml similarity index 100% rename from usage-example/src/androidMain/AndroidManifest.xml rename to sample/src/androidMain/AndroidManifest.xml diff --git a/usage-example/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainActivity.kt b/sample/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainActivity.kt similarity index 100% rename from usage-example/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainActivity.kt rename to sample/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainActivity.kt diff --git a/usage-example/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.android.kt b/sample/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.android.kt similarity index 100% rename from usage-example/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.android.kt rename to sample/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.android.kt diff --git a/usage-example/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.android.kt b/sample/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.android.kt similarity index 100% rename from usage-example/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.android.kt rename to sample/src/androidMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.android.kt diff --git a/usage-example/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/sample/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from usage-example/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml rename to sample/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml diff --git a/usage-example/src/androidMain/res/drawable/ic_launcher_background.xml b/sample/src/androidMain/res/drawable/ic_launcher_background.xml similarity index 100% rename from usage-example/src/androidMain/res/drawable/ic_launcher_background.xml rename to sample/src/androidMain/res/drawable/ic_launcher_background.xml diff --git a/usage-example/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/sample/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from usage-example/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml rename to sample/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/usage-example/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/sample/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from usage-example/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to sample/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/usage-example/src/androidMain/res/mipmap-hdpi/ic_launcher.png b/sample/src/androidMain/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-hdpi/ic_launcher.png rename to sample/src/androidMain/res/mipmap-hdpi/ic_launcher.png diff --git a/usage-example/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png b/sample/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png rename to sample/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png diff --git a/usage-example/src/androidMain/res/mipmap-mdpi/ic_launcher.png b/sample/src/androidMain/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-mdpi/ic_launcher.png rename to sample/src/androidMain/res/mipmap-mdpi/ic_launcher.png diff --git a/usage-example/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png b/sample/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png rename to sample/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png diff --git a/usage-example/src/androidMain/res/mipmap-xhdpi/ic_launcher.png b/sample/src/androidMain/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-xhdpi/ic_launcher.png rename to sample/src/androidMain/res/mipmap-xhdpi/ic_launcher.png diff --git a/usage-example/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png b/sample/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png rename to sample/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png diff --git a/usage-example/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png b/sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png rename to sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png diff --git a/usage-example/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png b/sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png rename to sample/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png diff --git a/usage-example/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png b/sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png rename to sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/usage-example/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png b/sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png similarity index 100% rename from usage-example/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png rename to sample/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png diff --git a/usage-example/src/androidMain/res/values/strings.xml b/sample/src/androidMain/res/values/strings.xml similarity index 100% rename from usage-example/src/androidMain/res/values/strings.xml rename to sample/src/androidMain/res/values/strings.xml diff --git a/usage-example/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/App.kt b/sample/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/App.kt similarity index 100% rename from usage-example/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/App.kt rename to sample/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/App.kt diff --git a/usage-example/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Greeting.kt b/sample/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Greeting.kt similarity index 100% rename from usage-example/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Greeting.kt rename to sample/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Greeting.kt diff --git a/usage-example/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.kt b/sample/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.kt similarity index 100% rename from usage-example/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.kt rename to sample/src/commonMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.kt diff --git a/sample/src/commonMain/python/pyproject.toml b/sample/src/commonMain/python/pyproject.toml new file mode 100644 index 0000000..16ef0c6 --- /dev/null +++ b/sample/src/commonMain/python/pyproject.toml @@ -0,0 +1,5 @@ +[project] +name = "sample-python" +version = "0.1.0" +description = "The Python half of the sample app, bundled by pypackpack and staged by the toolchain plugin." +requires-python = ">=3.13" diff --git a/usage-example/python/src/main/example_py/__init__.py b/sample/src/commonMain/python/src/main/example_py/__init__.py similarity index 80% rename from usage-example/python/src/main/example_py/__init__.py rename to sample/src/commonMain/python/src/main/example_py/__init__.py index 330c213..2b57ef6 100644 --- a/usage-example/python/src/main/example_py/__init__.py +++ b/sample/src/commonMain/python/src/main/example_py/__init__.py @@ -8,4 +8,4 @@ def greeting() -> str: - return f"Hello from usage-example's Python payload {VERSION}" + return f"Hello from the sample's Python payload {VERSION}" diff --git a/usage-example/python/src/main/example_py/data/table.json b/sample/src/commonMain/python/src/main/example_py/data/table.json similarity index 100% rename from usage-example/python/src/main/example_py/data/table.json rename to sample/src/commonMain/python/src/main/example_py/data/table.json diff --git a/usage-example/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.jvm.kt b/sample/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.jvm.kt similarity index 100% rename from usage-example/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.jvm.kt rename to sample/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.jvm.kt diff --git a/usage-example/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.kt b/sample/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.kt similarity index 100% rename from usage-example/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.kt rename to sample/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.kt diff --git a/usage-example/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt b/sample/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt similarity index 100% rename from usage-example/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt rename to sample/src/desktopMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt diff --git a/usage-example/src/iosMain/Configuration/Config.xcconfig b/sample/src/iosMain/Configuration/Config.xcconfig similarity index 100% rename from usage-example/src/iosMain/Configuration/Config.xcconfig rename to sample/src/iosMain/Configuration/Config.xcconfig diff --git a/usage-example/src/iosMain/app.xcodeproj/project.pbxproj b/sample/src/iosMain/app.xcodeproj/project.pbxproj similarity index 99% rename from usage-example/src/iosMain/app.xcodeproj/project.pbxproj rename to sample/src/iosMain/app.xcodeproj/project.pbxproj index cd5702a..7217dbf 100644 --- a/usage-example/src/iosMain/app.xcodeproj/project.pbxproj +++ b/sample/src/iosMain/app.xcodeproj/project.pbxproj @@ -176,7 +176,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/../..\"\n./gradlew embedAndSignAppleFrameworkForXcode\n"; + shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/../../..\"\n./gradlew -p sample embedAndSignAppleFrameworkForXcode\n"; }; A7C3F1E20B5D4C6E8F901234 /* Install Python */ = { isa = PBXShellScriptBuildPhase; diff --git a/usage-example/src/iosMain/install-python-phase.sh b/sample/src/iosMain/install-python-phase.sh similarity index 89% rename from usage-example/src/iosMain/install-python-phase.sh rename to sample/src/iosMain/install-python-phase.sh index 38e762a..7772614 100755 --- a/usage-example/src/iosMain/install-python-phase.sh +++ b/sample/src/iosMain/install-python-phase.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash -# Xcode Run Script phase for usage-example's iOS app (toolchain#22): put this app's python/ payload, +# Xcode Run Script phase for the sample's iOS app (toolchain#22): put this app's python/ payload, # CPython's standard library and Python.framework into the .app. # # The payload comes from this build: stagePythonBundleIosForXcode prints PYTHON_PAYLOAD_DIR=, which is # passed to python-multiplatform's install-python.sh as PYTHON_PAYLOAD_DIR (that stays valid after # python-multiplatform#90). install-python.sh is the ONLY phase that copies /python/; do not also -# wire toolchain's tools/xcode/stage-python-payload.sh. +# hand-wire a second phase that copies python/. # # INTERIM, until python-multiplatform#90 gives consumers the iOS wiring through its published plugin: # a python-multiplatform checkout (PYTHON_MULTIPLATFORM_DIR, an Xcode build setting or environment @@ -15,10 +15,10 @@ set -euo pipefail # TODO(python-multiplatform#90): no checkout once the plugin provides these to consumers. : "${PYTHON_MULTIPLATFORM_DIR:?set PYTHON_MULTIPLATFORM_DIR to a python-multiplatform checkout (interim, python-multiplatform#90)}" -# 1. This app's payload, from usage-example's own build. Captured, parsed, then checked, so a failing +# 1. This app's payload, from the sample's own build. Captured, parsed, then checked, so a failing # Gradle can never hand rsync an empty source. -cd "$SRCROOT/../.." -out=$(./gradlew -q stagePythonBundleIosForXcode) +cd "$SRCROOT/../../.." +out=$(./gradlew -q -p sample stagePythonBundleIosForXcode) payload=$(printf '%s\n' "$out" | sed -n 's/^PYTHON_PAYLOAD_DIR=//p') [ -n "$payload" ] && [ -d "$payload" ] || { echo "error: no Python payload dir from stagePythonBundleIosForXcode" >&2; exit 1; } export PYTHON_PAYLOAD_DIR="$payload" diff --git a/usage-example/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainViewController.kt b/sample/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainViewController.kt similarity index 100% rename from usage-example/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainViewController.kt rename to sample/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/MainViewController.kt diff --git a/usage-example/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.ios.kt b/sample/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.ios.kt similarity index 100% rename from usage-example/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.ios.kt rename to sample/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.ios.kt diff --git a/usage-example/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.ios.kt b/sample/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.ios.kt similarity index 100% rename from usage-example/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.ios.kt rename to sample/src/iosMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/PythonSmoke.ios.kt diff --git a/usage-example/src/iosMain/swift/Assets.xcassets/AccentColor.colorset/Contents.json b/sample/src/iosMain/swift/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from usage-example/src/iosMain/swift/Assets.xcassets/AccentColor.colorset/Contents.json rename to sample/src/iosMain/swift/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/usage-example/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/Contents.json b/sample/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from usage-example/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/Contents.json rename to sample/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/usage-example/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png b/sample/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png similarity index 100% rename from usage-example/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png rename to sample/src/iosMain/swift/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png diff --git a/usage-example/src/iosMain/swift/Assets.xcassets/Contents.json b/sample/src/iosMain/swift/Assets.xcassets/Contents.json similarity index 100% rename from usage-example/src/iosMain/swift/Assets.xcassets/Contents.json rename to sample/src/iosMain/swift/Assets.xcassets/Contents.json diff --git a/usage-example/src/iosMain/swift/ContentView.swift b/sample/src/iosMain/swift/ContentView.swift similarity index 100% rename from usage-example/src/iosMain/swift/ContentView.swift rename to sample/src/iosMain/swift/ContentView.swift diff --git a/usage-example/src/iosMain/swift/Info.plist b/sample/src/iosMain/swift/Info.plist similarity index 100% rename from usage-example/src/iosMain/swift/Info.plist rename to sample/src/iosMain/swift/Info.plist diff --git a/usage-example/src/iosMain/swift/Preview Content/Preview Assets.xcassets/Contents.json b/sample/src/iosMain/swift/Preview Content/Preview Assets.xcassets/Contents.json similarity index 100% rename from usage-example/src/iosMain/swift/Preview Content/Preview Assets.xcassets/Contents.json rename to sample/src/iosMain/swift/Preview Content/Preview Assets.xcassets/Contents.json diff --git a/usage-example/src/iosMain/swift/app.swift b/sample/src/iosMain/swift/app.swift similarity index 100% rename from usage-example/src/iosMain/swift/app.swift rename to sample/src/iosMain/swift/app.swift diff --git a/usage-example/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.wasmJs.kt b/sample/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.wasmJs.kt similarity index 100% rename from usage-example/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.wasmJs.kt rename to sample/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/Platform.wasmJs.kt diff --git a/usage-example/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt b/sample/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt similarity index 100% rename from usage-example/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt rename to sample/src/wasmJsMain/kotlin/org/thisisthepy/python/multiplatform/toolchain/example/main.kt diff --git a/usage-example/src/wasmJsMain/resources/index.html b/sample/src/wasmJsMain/resources/index.html similarity index 100% rename from usage-example/src/wasmJsMain/resources/index.html rename to sample/src/wasmJsMain/resources/index.html diff --git a/usage-example/src/wasmJsMain/resources/styles.css b/sample/src/wasmJsMain/resources/styles.css similarity index 100% rename from usage-example/src/wasmJsMain/resources/styles.css rename to sample/src/wasmJsMain/resources/styles.css diff --git a/settings.gradle.kts b/settings.gradle.kts index de25ed4..50894b3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,6 +32,5 @@ dependencyResolutionManagement { rootProject.name = "ToolchainProject" include(":toolchain") -// usage-example is its own build, with its own wrapper: (cd usage-example && ./gradlew …). It uses -// python-multiplatform's Kotlin; the plugin here stays on its own for its consumers (toolchain#22). -include(":tcl") +// sample/ is its own build, run with this wrapper: ./gradlew -p sample …. It uses python-multiplatform's +// Kotlin; the plugin here stays on its own for its consumers (toolchain#22, #62). diff --git a/tcl/build.gradle.kts b/tcl/build.gradle.kts deleted file mode 100644 index 198bbee..0000000 --- a/tcl/build.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -group = rootProject.group -version = rootProject.version - -plugins { - // No explicit version: `org.jetbrains.kotlin.jvm` is already on this settings' shared plugin - // classpath (pulled in transitively by the other subprojects' Kotlin Multiplatform/`kotlin-dsl` - // plugins), and Gradle rejects a second, explicitly-versioned request for a plugin ID it has - // already resolved ("plugin is already on the classpath with an unknown version"). - id("org.jetbrains.kotlin.jvm") - application -} - -dependencies { - implementation(libs.kotlinx.coroutines.core) - - // `tcl` ("toolchain-lite", GitHub issue thisisthepy/toolchain#1) is a thin CLI layer over - // `pypackpack`'s dependency backend -- the same artifact `:toolchain` already resolves through - // `mavenLocal()` (see that module's `build.gradle.kts` for the `publishToMavenLocal` - // prerequisite this also depends on). - implementation("org.thisisthepy.python.multiplatform:packpack:0.1.0") - - testImplementation(libs.kotlin.test) - testImplementation(libs.kotlin.test.junit) -} - -application { - // `main()` lives in `Cli.kt`, so its Kotlin-generated facade class is `CliKt`, not `MainKt`. - mainClass.set("org.thisisthepy.python.multiplatform.tcl.CliKt") -} - -// `packpack` is built with Kotlin 2.3.0 while this module's own `compileKotlin` resolves to -// Kotlin 2.1.0 (whichever Kotlin Gradle Plugin version wins the shared plugin classpath across -// this settings). Same escape hatch `:toolchain/build.gradle.kts` already uses for the same -// mismatch, for the same reason: this only relaxes the metadata-format version gate, not -// language/API level compatibility. -tasks.withType().configureEach { - compilerOptions.freeCompilerArgs.add("-Xskip-metadata-version-check") -} diff --git a/toolchain/build.gradle.kts b/toolchain/build.gradle.kts index 300aeb1..d299eca 100644 --- a/toolchain/build.gradle.kts +++ b/toolchain/build.gradle.kts @@ -6,6 +6,8 @@ plugins { `kotlin-dsl` `maven-publish` `java-gradle-plugin` + // The native `tcl` (toolchain-lite) that the PyPI wheels carry; see the cli source sets below. + id("org.graalvm.buildtools.native") version "0.10.6" } dependencies { @@ -18,8 +20,8 @@ dependencies { // not left as an independent literal. A skewed pin here (previously `2.0.0` against a `2.1.0` // root) put two different `kotlin-gradle-plugin` versions on the plugin classpath any consumer // sees once it applies both this plugin and `org.jetbrains.kotlin.multiplatform` in the same - // `plugins {}` block (as `usage-example/build.gradle.kts` does). Gradle does not merge/conflict - // -resolve those into one: `usage-example/build.gradle.kts` compiled its `KotlinWebpackConfig + // `plugins {}` block (as `sample/build.gradle.kts` does). Gradle does not merge/conflict + // -resolve those into one: `sample/build.gradle.kts` compiled its `KotlinWebpackConfig // .DevServer()` call (browser { commonWebpackConfig { ... } }) against 2.0.0's shape (`proxy: // Map`), while the actually-applied multiplatform plugin (2.1.0, `proxy: // List` as of that release) drove `wasmJsBrowserTest` task creation at runtime -- @@ -49,7 +51,7 @@ dependencies { // Test-only: `PythonPluginAttachmentTest` applies `com.android.application` to a ProjectBuilder // project to check that the staged Android root really lands in `android.sourceSets.main.assets` // (the plugin reaches that object reflectively, so only a real AGP proves the method chain). - // Same version as `usage-example` (`gradle/libs.versions.toml` `agp`); never on the plugin's + // Same version as `sample` (`gradle/libs.versions.toml` `agp`); never on the plugin's // own runtime classpath. testImplementation("com.android.tools.build:gradle:${libs.versions.agp.get()}") } @@ -102,3 +104,105 @@ publishing { mavenLocal() } } + +// --------------------------------------------------------------------------------------------- +// tcl (toolchain-lite): the command line for Python users, `tcl install ` +// +// It lives inside this module, in its own source sets (#78; it was a root `tcl/` module from +// 9560853 until then): `src/cliMain/kotlin`, the PyPI launcher package in `src/cliMain/python`, and +// tests in `src/cliTest/kotlin`. These source sets do not extend `main`'s configurations: through +// `java-gradle-plugin`, `main` carries the Gradle API and the Kotlin Gradle plugin, which tcl +// neither uses nor may drag into its native image. In the other direction, the plugin's +// publication is `main` alone, so it carries no tcl (test.yml checks the jar). +// +// `tclVersion` is tcl's own version, which `tcl --version` prints and the toolchain-lite wheel +// carries; publish-pypi.yml refuses to publish unless it equals pyproject.toml's. The plugin keeps +// rootProject.version. +val tclVersion = "0.1.0" +val tclMainClass = "org.thisisthepy.python.multiplatform.tcl.CliKt" + +val cliMain: SourceSet by sourceSets.creating +val cliTest: SourceSet by sourceSets.creating +cliTest.compileClasspath += cliMain.output +cliTest.runtimeClasspath += cliMain.output +configurations[cliTest.implementationConfigurationName].extendsFrom(configurations[cliMain.implementationConfigurationName]) +configurations[cliTest.runtimeOnlyConfigurationName].extendsFrom(configurations[cliMain.runtimeOnlyConfigurationName]) + +dependencies { + // A thin CLI over pypackpack's dependency backend: the same packpack artifact `main` resolves + // from mavenLocal (see this module's dependencies above). + "cliMainImplementation"(libs.kotlinx.coroutines.core) + "cliMainImplementation"("org.thisisthepy.python.multiplatform:packpack:0.1.0") + "cliTestImplementation"(libs.kotlin.test) + "cliTestImplementation"(libs.kotlin.test.junit) +} + +kotlin.target.compilations.getByName("cliTest").associateWith(kotlin.target.compilations.getByName("cliMain")) + +val cliTestTask = tasks.register("cliTest") { + description = "Runs tcl's tests (src/cliTest). InstallerTest needs uv and network access." + group = "verification" + testClassesDirs = cliTest.output.classesDirs + classpath = cliTest.runtimeClasspath + systemProperty("tcl.expectedVersion", tclVersion) +} +tasks.check { dependsOn(cliTestTask) } + +// `./gradlew :toolchain:runTcl --args="install "` +tasks.register("runTcl") { + description = "Runs tcl from source." + group = "application" + mainClass.set(tclMainClass) + classpath = cliMain.runtimeClasspath + workingDir = rootDir +} + +// `BuildInfo` reads this resource, so the version is not a literal in the source. +val generateBuildInfo by tasks.registering { + val version = tclVersion + val outputDir = layout.buildDirectory.dir("generated/build-info") + inputs.property("version", version) + outputs.dir(outputDir) + doLast { + val file = outputDir.get().file("org/thisisthepy/python/multiplatform/tcl/build-info.properties").asFile + file.parentFile.mkdirs() + file.writeText("version=$version\n") + } +} +cliMain.resources.srcDir(generateBuildInfo) + +val cliJar = tasks.register("cliJar") { + archiveBaseName.set("tcl") + archiveVersion.set(tclVersion) + from(cliMain.output) +} + +// The native `tcl` binary that the toolchain-lite wheel carries (publish-pypi.yml). The same +// settings as pypackpack's CLI, which tcl links: io.ktor reaches org.slf4j (slf4j-nop, no I/O at +// init), which GraalVM 21 otherwise refuses to initialize at build time. +graalvmNative { + binaries { + named("main") { + imageName.set("tcl") + mainClass.set(tclMainClass) + // An executable, not a library: the native plugin defaults to a shared library when + // `java-library` is applied, which `java-gradle-plugin` does for this module. + sharedLibrary.set(false) + classpath.setFrom(cliJar, configurations[cliMain.runtimeClasspathConfigurationName]) + buildArgs.addAll( + "--no-fallback", + "--install-exit-handlers", + "--initialize-at-build-time=kotlin,kotlinx.coroutines,io.ktor,kotlinx.io,org.slf4j", + "-H:+AddAllCharsets", + "--gc=serial", + ) + if (System.getProperty("os.name").lowercase().contains("mac")) { + // Without this the binary's minimum macOS is the build host's. + buildArgs.add("-H:NativeLinkerOption=-mmacosx-version-min=11.0") + } + resources.autodetect() + } + } + // native-image comes from GRAALVM_HOME/JAVA_HOME, not a toolchain Gradle might pick. + toolchainDetection.set(false) +} diff --git a/toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/BuildInfo.kt b/toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/BuildInfo.kt new file mode 100644 index 0000000..1f8d5d6 --- /dev/null +++ b/toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/BuildInfo.kt @@ -0,0 +1,17 @@ +package org.thisisthepy.python.multiplatform.tcl + +import java.util.Properties + +/** + * Facts the build writes into tcl's resources (`generateBuildInfo` in `toolchain/build.gradle.kts`). + * + * [version] is tcl's version, and so the toolchain-lite wheel's: `publish-pypi.yml` refuses to + * publish unless the installed binary prints the version in `pyproject.toml` (docs/SPEC.md 2.2). + */ +internal object BuildInfo { + val version: String by lazy { + BuildInfo::class.java.getResourceAsStream("build-info.properties") + ?.use { stream -> Properties().apply { load(stream) }.getProperty("version") } + ?: error("build-info.properties is missing from tcl's resources") + } +} diff --git a/tcl/src/main/kotlin/org/thisisthepy/python/multiplatform/tcl/Cli.kt b/toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/Cli.kt similarity index 91% rename from tcl/src/main/kotlin/org/thisisthepy/python/multiplatform/tcl/Cli.kt rename to toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/Cli.kt index 393cd6d..f869251 100644 --- a/tcl/src/main/kotlin/org/thisisthepy/python/multiplatform/tcl/Cli.kt +++ b/toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/Cli.kt @@ -26,6 +26,14 @@ fun execute( } return when (args[0]) { + "--help", "-h" -> { + out(USAGE) + 0 + } + "--version" -> { + out("tcl ${BuildInfo.version}") + 0 + } "install" -> { val packageName = args.getOrNull(1) if (packageName.isNullOrBlank()) { diff --git a/tcl/src/main/kotlin/org/thisisthepy/python/multiplatform/tcl/Installer.kt b/toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/Installer.kt similarity index 100% rename from tcl/src/main/kotlin/org/thisisthepy/python/multiplatform/tcl/Installer.kt rename to toolchain/src/cliMain/kotlin/org/thisisthepy/python/multiplatform/tcl/Installer.kt diff --git a/toolchain/src/cliMain/python/__init__.py b/toolchain/src/cliMain/python/__init__.py new file mode 100644 index 0000000..cd7c584 --- /dev/null +++ b/toolchain/src/cliMain/python/__init__.py @@ -0,0 +1,5 @@ +"""toolchain-lite on PyPI. + +The wheel installs the native `tcl` command line (a GraalVM Native Image) as a script. This package +only lets `python -m toolchain_lite` find and run that binary. +""" diff --git a/toolchain/src/cliMain/python/__main__.py b/toolchain/src/cliMain/python/__main__.py new file mode 100644 index 0000000..4880750 --- /dev/null +++ b/toolchain/src/cliMain/python/__main__.py @@ -0,0 +1,41 @@ +"""Run the native `tcl` binary installed beside this interpreter (`python -m toolchain_lite`).""" +import os +import subprocess +import sys +import sysconfig +from pathlib import Path + +_NAME = "tcl.exe" if os.name == "nt" else "tcl" + + +def _candidates(): + yield Path(sysconfig.get_path("scripts")) / _NAME + user_scheme = getattr(sysconfig, "get_preferred_scheme", lambda _: f"{os.name}_user")("user") + try: + yield Path(sysconfig.get_path("scripts", user_scheme)) / _NAME + except KeyError: + pass + + +def _binary() -> Path: + tried = [] + for path in _candidates(): + if path.is_file(): + return path + tried.append(str(path)) + sys.exit( + "tcl: the native binary is not installed beside this Python " + f"(looked for {', '.join(tried)}). Install a platform wheel: uv tool install toolchain-lite" + ) + + +def main() -> None: + exe = _binary() + args = [str(exe), *sys.argv[1:]] + if os.name == "nt": + sys.exit(subprocess.call(args)) + os.execv(str(exe), args) + + +if __name__ == "__main__": + main() diff --git a/tcl/src/test/kotlin/org/thisisthepy/python/multiplatform/tcl/CliArgsTest.kt b/toolchain/src/cliTest/kotlin/org/thisisthepy/python/multiplatform/tcl/CliArgsTest.kt similarity index 69% rename from tcl/src/test/kotlin/org/thisisthepy/python/multiplatform/tcl/CliArgsTest.kt rename to toolchain/src/cliTest/kotlin/org/thisisthepy/python/multiplatform/tcl/CliArgsTest.kt index 9693d0d..f731768 100644 --- a/tcl/src/test/kotlin/org/thisisthepy/python/multiplatform/tcl/CliArgsTest.kt +++ b/toolchain/src/cliTest/kotlin/org/thisisthepy/python/multiplatform/tcl/CliArgsTest.kt @@ -72,4 +72,33 @@ class CliArgsTest { assertEquals(1, code) assertTrue(errors.any { it.contains("network down") }) } + + @Test + fun `--help prints usage on stdout and exits zero`() { + val out = mutableListOf() + + val code = execute(arrayOf("--help"), anyDir, install = mustNotInstall, out = out::add) + + assertEquals(0, code) + assertTrue(out.any { it.contains("Usage: tcl install ") }, out.toString()) + } + + @Test + fun `--version prints the build's version and exits zero`() { + val out = mutableListOf() + + val code = execute(arrayOf("--version"), anyDir, install = mustNotInstall, out = out::add) + + assertEquals(0, code) + assertEquals(listOf("tcl ${BuildInfo.version}"), out) + } + + // toolchain/build.gradle.kts passes `tclVersion` to the test JVM; publish-pypi.yml then checks it + // against pyproject.toml, so it must not be a literal (docs/SPEC.md section 2.2). + @Test + fun `the version is the one the build declares`() { + val expected = System.getProperty("tcl.expectedVersion") + assertTrue(!expected.isNullOrBlank(), "the build passes no tcl.expectedVersion") + assertEquals(expected, BuildInfo.version) + } } diff --git a/tcl/src/test/kotlin/org/thisisthepy/python/multiplatform/tcl/InstallerTest.kt b/toolchain/src/cliTest/kotlin/org/thisisthepy/python/multiplatform/tcl/InstallerTest.kt similarity index 100% rename from tcl/src/test/kotlin/org/thisisthepy/python/multiplatform/tcl/InstallerTest.kt rename to toolchain/src/cliTest/kotlin/org/thisisthepy/python/multiplatform/tcl/InstallerTest.kt diff --git a/toolchain/src/main/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPlugin.kt b/toolchain/src/main/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPlugin.kt index 21365fa..fab36ba 100644 --- a/toolchain/src/main/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPlugin.kt +++ b/toolchain/src/main/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPlugin.kt @@ -107,7 +107,7 @@ class PythonPlugin : Plugin { // destination roots are derived from the build directory alone (`PythonStagingPlatform. // rootIn`): an AGP asset source root has to be declared while the consumer's build script is // still being evaluated, because AGP reads its source sets in its own `afterEvaluate` and - // this plugin -- applied last in a `plugins { }` block, as `usage-example` applies it -- + // this plugin -- applied last in a `plugins { }` block, as `sample` applies it -- // registers its `afterEvaluate` callback after AGP's and therefore runs after it. A // `srcDir` added at that point is added to a source set nothing will look at again. // @@ -266,8 +266,8 @@ class PythonPlugin : Plugin { // second code path doing the same job -- `buildTask` (`BuildPythonArtifactTask`) already // delegates the real work to `pypackpack`'s `ResourceBundler` into `build/pythonBundle` // (this task's own report; `docs/ecosystem.md` §1, §5). Confirmed nothing depended on - // it before deleting: no source under `usage-example/` reads `src/main/assets/python` or - // `build/pythonLibraries`, `usage-example` itself never sets `python.localLibraryPath` + // it before deleting: no source under `sample/` reads `src/main/assets/python` or + // `build/pythonLibraries`, `sample` itself never sets `python.localLibraryPath` // today, and `copyPythonLibrariesToAssets`/`preBuild` wiring existed only inside this // now-removed block, so nothing outside it could have depended on that task by name // either. Wiring the real bundle output into Android assets (or any other platform's @@ -620,7 +620,7 @@ private fun registerStagingTasks(project: Project): Map): ListMain` source set. diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginApplyTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginApplyTest.kt index a6af961..c43ee56 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginApplyTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginApplyTest.kt @@ -21,7 +21,7 @@ import kotlin.test.assertTrue * docs/SPEC.md §1.1: applying the plugin id to a real Gradle `Project` creates the `python` * extension and registers the tasks of §1.10–§1.15, all in group `python`. * - * Before this file the only thing that applied the plugin was a `usage-example` build, which needs + * Before this file the only thing that applied the plugin was a `sample` build, which needs * `publishToMavenLocal` first and an Android SDK; a ProjectBuilder project needs neither. */ class PythonPluginApplyTest { diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginAttachmentTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginAttachmentTest.kt index 96f76d9..5cf38f2 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginAttachmentTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginAttachmentTest.kt @@ -18,7 +18,7 @@ import kotlin.test.assertTrue * - Android: the staged Android root is an asset source directory of `android.sourceSets.main`, * registered at apply time (AGENTS.md §15: AGP reads source sets in its own `afterEvaluate`). * `PythonPlugin` reaches that object reflectively, so the test applies the real Android Gradle - * plugin (the version `usage-example` uses) rather than a fake, to prove the method chain exists. + * plugin (the version `sample` uses) rather than a fake, to prove the method chain exists. */ class PythonPluginAttachmentTest { private fun newProject(): Project = diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginBuildLevelTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginBuildLevelTest.kt index fa74654..2b3b2c5 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginBuildLevelTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginBuildLevelTest.kt @@ -14,7 +14,7 @@ import kotlin.test.assertTrue * variant, inside that variant's task action (AGENTS.md §14), with a message naming that slot. * * Blank resolves to `"instant"`: both `DebugBuildType` and `ReleaseBuildType` default `compileLevel` - * to `""`, and `usage-example` never sets it. + * to `""`, and `sample` never sets it. */ class PythonPluginBuildLevelTest { @Test diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginSourceSetTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginSourceSetTest.kt index e5df5e3..91721f4 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginSourceSetTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginSourceSetTest.kt @@ -22,7 +22,7 @@ import kotlin.test.assertNull * * `localLibraryPath` stays the explicit override it always was -- declaring both `localLibraryPath` * and `commonMain.srcDirs` is not a conflict, `localLibraryPath` simply wins, so every existing - * consumer (`usage-example` sets `localLibraryPath` and no `sourceSets` block) keeps resolving + * consumer (`sample` sets `localLibraryPath` and no `sourceSets` block) keeps resolving * exactly as before. * * Before [resolvePackageDir] exists, this file fails to compile rather than failing an assertion -- diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginVariantGraphTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginVariantGraphTest.kt index 0c69029..6bf453f 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginVariantGraphTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/PythonPluginVariantGraphTest.kt @@ -49,7 +49,7 @@ import kotlin.test.assertTrue * * [resolveVariants] returns an empty list when `python { }` platform declares nothing, and * `PythonPlugin` then leaves `buildPython`/`packagePython` doing exactly what they do today: one - * host-target bundle, one `.zip`. `usage-example` declares no platforms, so the only + * host-target bundle, one `.zip`. `sample` declares no platforms, so the only * chain that currently runs end to end is unaffected by any of this. The platform block is what * creates more than one target; without it there is exactly one, and one build type chosen by * `-Ppython.buildType` as before. diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonBundleTaskTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonBundleTaskTest.kt index 56c2ba9..384cdc1 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonBundleTaskTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonBundleTaskTest.kt @@ -121,7 +121,7 @@ class StagePythonBundleTaskTest { // A regression guard for a defect this task actually had. With the bundle declared nowhere, // Gradle had nothing to compare and reported `stagePythonBundleDesktop UP-TO-DATE` on every // run after the first, so the staged tree -- and the jar built from it -- kept a payload - // from an earlier revision of the Python package. Found by building `:usage-example: + // from an earlier revision of the Python package. Found by building `:sample: // desktopJar`, deleting a module, and building again: the module was still in the archive. // // Asserted on the annotation rather than through a Gradle run because up-to-date checking diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonPayloadScriptTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonPayloadScriptTest.kt deleted file mode 100644 index 654d9aa..0000000 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/bundle/StagePythonPayloadScriptTest.kt +++ /dev/null @@ -1,82 +0,0 @@ -package org.thisisthepy.python.multiplatform.toolchain.bundle - -import java.io.File -import java.util.concurrent.TimeUnit -import kotlin.io.path.createTempDirectory -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals -import kotlin.test.assertTrue - -/** Runs `tools/xcode/stage-python-payload.sh` with a fake gradlew and a fake rsync that records calls. */ -class StagePythonPayloadScriptTest { - private val bash: String? = listOf("/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash", "/opt/homebrew/bin/bash") - .firstOrNull { File(it).canExecute() } - - private fun script(): File { - var dir: File? = File("").absoluteFile - while (dir != null) { - val candidate = File(dir, "tools/xcode/stage-python-payload.sh") - if (candidate.isFile) return candidate - dir = dir.parentFile - } - error("tools/xcode/stage-python-payload.sh not found above ${File("").absolutePath}") - } - - private class Run(val exit: Int, val rsyncCalls: List) - - private fun run(gradlewBody: String): Pair { - val work = createTempDirectory("xcode-script").toFile() - val gradlew = File(work, "fake-gradlew").apply { writeText("#!/bin/sh\n$gradlewBody\n"); setExecutable(true) } - val bin = File(work, "bin").apply { mkdirs() } - val log = File(work, "rsync.log") - File(bin, "rsync").apply { - writeText("#!/bin/sh\necho \"\$*\" >> '${log.path}'\n") - setExecutable(true) - } - val pb = ProcessBuilder(bash, script().path).redirectErrorStream(true) - pb.environment().apply { - put("PATH", "${bin.path}:${get("PATH")}") - put("GRADLEW", gradlew.path) - put("TARGET_BUILD_DIR", "/tb") - put("UNLOCALIZED_RESOURCES_FOLDER_PATH", "App.app") - } - val p = pb.start() - p.inputStream.readBytes() - assertTrue(p.waitFor(30, TimeUnit.SECONDS)) - return Run(p.exitValue(), if (log.exists()) log.readLines() else emptyList()) to work - } - - @Test - fun `a failing gradle exits non-zero and never calls rsync`() { - if (bash == null) return - val (r, _) = run("exit 1") - assertNotEquals(0, r.exit) - assertTrue(r.rsyncCalls.isEmpty()) - } - - @Test - fun `no PYTHON_PAYLOAD_DIR line exits non-zero and never calls rsync`() { - if (bash == null) return - val (r, _) = run("echo hello") - assertNotEquals(0, r.exit) - assertTrue(r.rsyncCalls.isEmpty()) - } - - @Test - fun `a payload dir that does not exist exits non-zero and never calls rsync`() { - if (bash == null) return - val (r, _) = run("echo PYTHON_PAYLOAD_DIR=/nonexistent/xyz/python") - assertNotEquals(0, r.exit) - assertTrue(r.rsyncCalls.isEmpty()) - } - - @Test - fun `a valid payload dir calls rsync once with the dir and the app destination`() { - if (bash == null) return - val payload = createTempDirectory("payload").toFile() - val (r, _) = run("echo noise; echo PYTHON_PAYLOAD_DIR=${payload.path}") - assertEquals(0, r.exit) - assertEquals(listOf("-a --delete ${payload.path}/ /tb/App.app/python/"), r.rsyncCalls) - } -} diff --git a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/typedpython/TypedpythonCheckTaskTest.kt b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/typedpython/TypedpythonCheckTaskTest.kt index 7e40e2b..94944ae 100644 --- a/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/typedpython/TypedpythonCheckTaskTest.kt +++ b/toolchain/src/test/kotlin/org/thisisthepy/python/multiplatform/toolchain/typedpython/TypedpythonCheckTaskTest.kt @@ -26,10 +26,10 @@ import kotlin.test.BeforeTest * The build scripts are Kotlin DSL (`build.gradle.kts`), as a consumer's are. What these tests * **cannot** see: `withPluginClasspath()` injects the plugin's classes instead of resolving them, so * the Kotlin DSL's pin of the buildscript `kotlin-stdlib` to Gradle's embedded version - * (`{strictly 1.9.23}` on Gradle 8.9, see `:usage-example:buildEnvironment`) does not apply here. A + * (`{strictly 1.9.23}` on Gradle 8.9, see `:sample:buildEnvironment`) does not apply here. A * gate install through `pypackpack`'s suspend backend passed every test below and still died in - * `usage-example` with `NoClassDefFoundError: kotlin/coroutines/jvm/internal/SpillingKt` -- see - * [TypedpythonCheckTask]. Classpath problems show up in `usage-example`, not here. + * `sample` with `NoClassDefFoundError: kotlin/coroutines/jvm/internal/SpillingKt` -- see + * [TypedpythonCheckTask]. Classpath problems show up in `sample`, not here. * * Before `typedpythonCheck` exists, these fail with "Task 'typedpythonCheck' not found" or with * `buildPython` succeeding over an `Any` leak -- the pre-implementation failure, not a regression. diff --git a/tools/release/protect-main.sh b/tools/release/protect-main.sh deleted file mode 100755 index 5d3588f..0000000 --- a/tools/release/protect-main.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash -# Print (default) or apply (--apply) branch protection for main. -# Usage: protect-main.sh [--apply] [--repo OWNER/NAME] [--branch main] -set -eu -APPLY=0; REPO=""; BRANCH=main -while [ $# -gt 0 ]; do - case "$1" in - --apply) APPLY=1; shift ;; - --repo) REPO="$2"; shift 2 ;; - --branch) BRANCH="$2"; shift 2 ;; - *) echo "unknown argument: $1" >&2; exit 2 ;; - esac -done -[ -n "$REPO" ] || REPO="{owner}/{repo}" # gh expands these placeholders from the current repo - -BODY='{ - "required_status_checks": {"strict": true, "contexts": ["only-release-into-main"]}, - "enforce_admins": true, - "required_pull_request_reviews": {"required_approving_review_count": 0}, - "restrictions": null, - "allow_force_pushes": false, - "allow_deletions": false -}' -CMD="gh api --method PUT repos/$REPO/branches/$BRANCH/protection --input -" - -if [ "$APPLY" -eq 1 ]; then - printf '%s' "$BODY" | gh api --method PUT "repos/$REPO/branches/$BRANCH/protection" --input - - echo "applied protection to $BRANCH" -else - echo "[dry run] would run: $CMD" - echo "$BODY" - echo "Re-run with --apply to apply. The check 'only-release-into-main' comes from .github/workflows/main-source-guard.yml;" - echo "it must have run once before GitHub accepts it as a required check." -fi diff --git a/tools/xcode/stage-python-payload.sh b/tools/xcode/stage-python-payload.sh deleted file mode 100755 index b25306e..0000000 --- a/tools/xcode/stage-python-payload.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# Xcode build-phase helper: stage the iOS Python payload with Gradle and copy it into the .app. -# Usage: stage-python-payload.sh [:app:stagePythonBundleIosForXcode] -# Env: GRADLEW (default ./gradlew); TARGET_BUILD_DIR and UNLOCALIZED_RESOURCES_FOLDER_PATH (Xcode sets both). -# Use it only WITHOUT python-multiplatform. With python-multiplatform, its tools/xcode/install-python.sh is -# the one phase that copies python/ (and the stdlib): give it PYTHON_PAYLOAD_TASK=:app:stagePythonBundleIosForXcode -# and do not add this script too -- both rsync --delete into the same /python/. -set -euo pipefail -: "${TARGET_BUILD_DIR:?Xcode must set TARGET_BUILD_DIR}" "${UNLOCALIZED_RESOURCES_FOLDER_PATH:?Xcode must set UNLOCALIZED_RESOURCES_FOLDER_PATH}" -task="${1:-:app:stagePythonBundleIosForXcode}" -out=$("${GRADLEW:-./gradlew}" -q "$task") -dir=$(printf '%s\n' "$out" | sed -n 's/^PYTHON_PAYLOAD_DIR=//p') -[ -n "$dir" ] && [ -d "$dir" ] || { echo "error: no Python payload dir from Gradle" >&2; exit 1; } -rsync -a --delete "$dir/" "$TARGET_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/python/" diff --git a/usage-example/gradle/wrapper/gradle-wrapper.jar b/usage-example/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 2c35211..0000000 Binary files a/usage-example/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/usage-example/gradle/wrapper/gradle-wrapper.properties b/usage-example/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e2847c8..0000000 --- a/usage-example/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/usage-example/gradlew b/usage-example/gradlew deleted file mode 100755 index f5feea6..0000000 --- a/usage-example/gradlew +++ /dev/null @@ -1,252 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/usage-example/gradlew.bat b/usage-example/gradlew.bat deleted file mode 100644 index 9d21a21..0000000 --- a/usage-example/gradlew.bat +++ /dev/null @@ -1,94 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/usage-example/python/pyproject.toml b/usage-example/python/pyproject.toml deleted file mode 100644 index 7650695..0000000 --- a/usage-example/python/pyproject.toml +++ /dev/null @@ -1,5 +0,0 @@ -[project] -name = "usage-example-python" -version = "0.1.0" -description = "The Python half of usage-example, bundled by pypackpack and staged by the toolchain plugin." -requires-python = ">=3.13"