Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2026-06-11 10:58:19 +02:00
commit 12e7ea038f
28 changed files with 2650 additions and 3146 deletions

View File

@ -39,8 +39,8 @@ Identify:
| Field | Source | Rule | | Field | Source | Rule |
|-------|--------|------| |-------|--------|------|
| **Title** | PR title | Rewrite from user perspective. Strip leading emoji prefixes (`:bug:`, `:sparkles:`, `:tada:`). Focus on observable behavior. Use imperative mood. | | **Title** | PR title | Rewrite from user perspective. Strip leading emoji prefixes (`:bug:`, `:sparkles:`, `:tada:`). Focus on observable behavior. Use imperative mood. Use the `issue-title` skill to generate this. |
| **Labels** | PR labels | Copy user-facing labels (`bug`, `enhancement`, `community contribution`). Skip workflow labels (`backport candidate`, `team-qa`). | | **Labels** | PR labels | Copy `community contribution` if present. Skip `bug` and `enhancement` (redundant with Issue Type). Skip workflow labels (`backport candidate`, `team-qa`). |
| **Milestone** | PR milestone | **Always copy what's on the PR.** Fetch with: `gh pr view <PR_NUMBER> --json milestone --jq '.milestone.title'` If the PR has no milestone, create the issue without one. | | **Milestone** | PR milestone | **Always copy what's on the PR.** Fetch with: `gh pr view <PR_NUMBER> --json milestone --jq '.milestone.title'` If the PR has no milestone, create the issue without one. |
| **Project** | Always `Main` | Penpot uses the `Main` project (number 8) for all issues. | | **Project** | Always `Main` | Penpot uses the `Main` project (number 8) for all issues. |
| **Body** | PR's user-facing section | Extract steps to reproduce or feature description. Omit internal details. Use templates below. | | **Body** | PR's user-facing section | Extract steps to reproduce or feature description. Omit internal details. Use templates below. |
@ -101,8 +101,7 @@ Create:
gh issue create \ gh issue create \
--repo penpot/penpot \ --repo penpot/penpot \
--title "<Title>" \ --title "<Title>" \
--label "<label1>" \ --label "community contribution" \ # only if PR has this label
--label "<label2>" \
--milestone "<milestone>" \ --milestone "<milestone>" \
--project "Main" \ --project "Main" \
--body-file /tmp/issue-body.md --body-file /tmp/issue-body.md
@ -198,12 +197,10 @@ rm -f /tmp/issue-body.md /tmp/pr-body.md
| PR has | Issue gets | | PR has | Issue gets |
|--------|-----------| |--------|-----------|
| `bug` | `bug` |
| `enhancement` | `enhancement` |
| `community contribution` | `community contribution` | | `community contribution` | `community contribution` |
| `bug`, `enhancement` | *(skip — redundant with Issue Type)* |
| `backport candidate` | *(skip — workflow label)* | | `backport candidate` | *(skip — workflow label)* |
| `team-qa` | *(skip — workflow label)* | | `team-qa` | *(skip — workflow label)* |
| No user-facing label | Infer from title: `:bug:``bug`, `:sparkles:``enhancement` |
## Issue Type mapping ## Issue Type mapping

View File

@ -48,7 +48,7 @@ python3 tools/gh.py issues "2.16.0" --exclude "release blocker,no changelog"
**Exclusion rules (issue-level):** **Exclusion rules (issue-level):**
- `no changelog` label — Chore/refactor work that doesn't need a changelog entry - `no changelog` label — Chore/refactor work that doesn't need a changelog entry
- `release blocker` label — Blocked issues not yet ready for changelog - `release blocker` label — Blocked issues not yet ready for changelog
- `Task` issue type — Internal chores are not user-facing; filter these out after fetching - `Task` issue type — Internal chores are not user-facing; automatically excluded by `gh.py`. Use `--include-tasks` to override.
- **Rejected project status** — Issues with a "Rejected" status in the "Main" project board are automatically excluded by `gh.py`. This project-level status (independent of the GitHub issue `state`) indicates the issue was rejected from the release. Use `--include-rejected` to override. - **Rejected project status** — Issues with a "Rejected" status in the "Main" project board are automatically excluded by `gh.py`. This project-level status (independent of the GitHub issue `state`) indicates the issue was rejected from the release. Use `--include-rejected` to override.
**Exclusion rules (PR-level):** **Exclusion rules (PR-level):**
@ -347,71 +347,233 @@ if closed:
- <fix description> (by @contributor) [#<ISSUE>](https://github.com/penpot/penpot/issues/<ISSUE>) (PR: [#<PR>](https://github.com/penpot/penpot/pull/<PR>)) - <fix description> (by @contributor) [#<ISSUE>](https://github.com/penpot/penpot/issues/<ISSUE>) (PR: [#<PR>](https://github.com/penpot/penpot/pull/<PR>))
``` ```
### 10. Cross-reference milestone PRs against the changelog ### 11. Generate anomaly report and save to CHANGES-ISSUES.md
Issues can be fixed by PRs that aren't in the milestone, and merged PRs in After all edits and cross-referencing are complete, generate a structured
the milestone may not close any tracked issue. After writing, run a full anomaly report and save it to `CHANGES-ISSUES.md` (overwriting if exists).
cross-reference to catch gaps: This provides a persistent record of any discrepancies between the milestone
and the changelog.
Run this self-contained script:
```bash ```bash
# List all merged PRs in the milestone python3 << 'PYEOF'
python3 tools/gh.py prs --milestone "<MILESTONE>" --state merged > /tmp/milestone-prs.json import json, re, subprocess, sys
# Extract PR numbers from the changelog section MILESTONE = "<MILESTONE>"
python3 -c " CHANGES_MD = "CHANGES.md"
import json, re OUTPUT = "CHANGES-ISSUES.md"
with open('CHANGES.md') as f: # Fetch milestone issues (all states)
result = subprocess.run(
["python3", "tools/gh.py", "issues", MILESTONE, "--state", "all"],
capture_output=True, text=True)
all_issues = json.loads(result.stdout)
issue_by_num = {i['number']: i for i in all_issues}
# Fetch milestone PRs (all states)
result = subprocess.run(
["python3", "tools/gh.py", "prs", "--milestone", MILESTONE, "--state", "all"],
capture_output=True, text=True)
all_prs = json.loads(result.stdout)
pr_by_num = {p['number']: p for p in all_prs}
# Read changelog
with open(CHANGES_MD) as f:
content = f.read() content = f.read()
# Extract the version section (adjust regex to match the actual version) m = re.search(rf'## {MILESTONE} \(Unreleased\)\n(.*?)(?:\n## |\Z)', content, re.DOTALL)
match = re.search(r'## <MILESTONE> \(Unreleased\)\n(.*?)(?:\n## |\Z)', content, re.DOTALL) section = m.group(1) if m else ""
section = match.group(1)
# Collect issue and PR references from the changelog section
changelog_issues = set()
for num in re.findall(r'\[#(\d+)\]\(https://github\.com/penpot/penpot/issues/\d+\)', section):
changelog_issues.add(int(num))
for num in re.findall(r'\[Github #(\d+)\]', section):
changelog_issues.add(int(num))
# Collect all PR numbers referenced
changelog_prs = set() changelog_prs = set()
for m in re.findall(r'\[#(\d+)\]\(https://github\.com/penpot/penpot/pull/\d+\)', section): for num in re.findall(r'\[#(\d+)\]\(https://github\.com/penpot/penpot/pull/\d+\)', section):
changelog_prs.add(int(m)) changelog_prs.add(int(num))
for num in re.findall(r'PR:\[(\d+)\]', section):
changelog_prs.add(int(num))
# Collect all milestone PRs (filtered) # Determine valid (non-excluded) milestone issues
with open('/tmp/milestone-prs.json') as f: EXCLUDED_LABELS = {'release blocker', 'no changelog'}
milestone_prs = json.load(f) EXCLUDED_ISSUE_TYPES = {'Task'}
EXCLUDED_PROJECT_STATUS = {'Rejected'}
milestone_merged = {pr['number'] for pr in milestone_prs} valid_issues = []
for issue in all_issues:
labels = set(issue.get('labels', []))
if issue.get('state') != 'CLOSED': continue
if issue.get('issue_type') in EXCLUDED_ISSUE_TYPES: continue
if issue.get('project_status') in EXCLUDED_PROJECT_STATUS: continue
if EXCLUDED_LABELS & labels: continue
valid_issues.append(issue)
valid_nums = {i['number'] for i in valid_issues}
# PRs in milestone but not in changelog # --- Gather anomalies ---
missing = sorted(milestone_merged - changelog_prs) anomalies = []
print(f'Milestone merged PRs: {len(milestone_merged)}')
print(f'Changelog referenced PRs: {len(changelog_prs)}') # Type 1: Entries in changelog that should be excluded
print(f'PRs in milestone but NOT in changelog: {len(missing)}') for num in sorted(changelog_issues):
for num in missing: issue = issue_by_num.get(num)
pr = next(p for p in milestone_prs if p['number'] == num) if issue is None:
print(f' #{num} {pr[\"title\"][:80]}') anomalies.append({
" 'type': 'should_remove',
'severity': 'HIGH',
'number': num,
'title': '',
'reason': 'Issue not found in milestone (deleted or moved)'
})
continue
labels = set(issue.get('labels', []))
reasons = []
if issue.get('state') != 'CLOSED':
reasons.append(f'state is "{issue["state"]}" (should be CLOSED)')
if 'release blocker' in labels:
reasons.append('has "release blocker" label')
if 'no changelog' in labels:
reasons.append('has "no changelog" label')
if issue.get('issue_type') == 'Task':
reasons.append(f'issue_type is Task (internal chore)')
if issue.get('project_status') == 'Rejected':
reasons.append('project_status is Rejected')
if reasons:
anomalies.append({
'type': 'should_remove',
'severity': 'MEDIUM' if issue.get('issue_type') == 'Task' else 'HIGH',
'number': num,
'title': issue.get('title', '')[:80],
'reason': '; '.join(reasons)
})
# Type 2: Valid issues not in changelog
for num in sorted(valid_nums - changelog_issues):
issue = issue_by_num[num]
info = {
'type': 'missing',
'severity': 'MEDIUM',
'number': num,
'title': issue['title'][:80],
'issue_type': issue['issue_type'],
'closing_prs': issue.get('closing_prs', []),
'note': ''
}
# Check for duplicate (same PR as existing entry)
existing = []
for pr_num in issue.get('closing_prs', []):
for cl_num in changelog_issues:
cl_issue = issue_by_num.get(cl_num)
if cl_issue and pr_num in cl_issue.get('closing_prs', []):
existing.append(f'#{cl_num}')
if existing:
info['note'] = f'DUPLICATE: same PR as existing entry(ies): {", ".join(existing)}'
# Check closing PRs not merged
unmerged = []
for pr_num in issue.get('closing_prs', []):
pr = pr_by_num.get(pr_num)
if pr is None:
unmerged.append(f'#{pr_num} (unknown)')
elif pr.get('state') != 'MERGED':
unmerged.append(f'#{pr_num} (state={pr["state"]})')
if unmerged:
info['note'] = (info['note'] + '; ' if info['note'] else '') + f'Closing PRs not merged: {", ".join(unmerged)}'
anomalies.append(info)
# Type 3: PRs in changelog that are not merged
for pr_num in sorted(changelog_prs):
pr = pr_by_num.get(pr_num)
if pr is None:
anomalies.append({
'type': 'unmerged_pr',
'severity': 'HIGH',
'number': pr_num,
'title': '',
'reason': 'PR not found in milestone PR list'
})
elif pr.get('state') != 'MERGED':
anomalies.append({
'type': 'unmerged_pr',
'severity': 'HIGH',
'number': pr_num,
'title': pr.get('title', '')[:80],
'reason': f'state={pr["state"]} (should be MERGED)'
})
# --- Write report to CHANGES-ISSUES.md ---
with open(OUTPUT, 'w') as f:
f.write(f'# Changelog Anomaly Report — {MILESTONE}\n\n')
f.write(f'Generated: {__import__("datetime").datetime.now().strftime("%Y-%m-%d %H:%M UTC")}\n\n')
f.write('---\n\n')
# Summary
n_remove = sum(1 for a in anomalies if a['type'] == 'should_remove')
n_missing = sum(1 for a in anomalies if a['type'] == 'missing')
n_pr = sum(1 for a in anomalies if a['type'] == 'unmerged_pr')
f.write(f'## Summary\n\n')
f.write(f'- **Issues to remove from changelog:** {n_remove}\n')
f.write(f'- **Valid issues missing from changelog:** {n_missing}\n')
f.write(f'- **Unmerged PRs referenced:** {n_pr}\n')
f.write(f'- **Total anomalies:** {len(anomalies)}\n\n')
if not anomalies:
f.write('✅ No anomalies found. The changelog is fully consistent with the milestone.\n\n')
else:
# Type 1
if n_remove:
f.write(f'## Issues to Remove\n\n')
f.write('These entries are in the changelog but should be excluded based on current issue metadata.\n\n')
for a in anomalies:
if a['type'] != 'should_remove': continue
badge = '🔴' if a['severity'] == 'HIGH' else '🟡'
f.write(f'{badge} **#{a["number"]}**')
if a.get('title'): f.write(f' — {a["title"]}')
f.write(f'\n - Reason: {a["reason"]}\n\n')
# Type 2
if n_missing:
f.write(f'## Valid Issues Not in Changelog\n\n')
f.write('These issues are closed, non-excluded milestone items that lack a changelog entry.\n\n')
for a in anomalies:
if a['type'] != 'missing': continue
f.write(f'❓ **#{a["number"]}** — {a["title"]}\n')
f.write(f' - Type: {a["issue_type"]}, Closing PRs: {a["closing_prs"]}\n')
if a.get('note'): f.write(f' - Note: {a["note"]}\n')
f.write('\n')
# Type 3
if n_pr:
f.write(f'## Unmerged PRs Referenced in Changelog\n\n')
f.write('These PR numbers appear in the changelog but are not merged.\n\n')
for a in anomalies:
if a['type'] != 'unmerged_pr': continue
f.write(f'🔴 **#{a["number"]}**')
if a.get('title'): f.write(f' — {a["title"]}')
f.write(f'\n - {a["reason"]}\n\n')
# Appendix: counts
f.write('---\n\n')
f.write(f'## Context\n\n')
f.write(f'- Milestone total issues (all states): {len(all_issues)}\n')
f.write(f'- Valid issues after exclusions: {len(valid_issues)}\n')
f.write(f'- Issues referenced in changelog: {len(changelog_issues)}\n')
f.write(f'- PRs referenced in changelog: {len(changelog_prs)}\n')
print(f"Anomaly report written to {OUTPUT}")
PYEOF
``` ```
For each missing PR found, decide whether it should be added to the This generates `CHANGES-ISSUES.md` with three sections:
changelog or is legitimately excluded (check its labels). 1. **Issues to Remove** — Entries in the changelog that should be excluded based
on current issue metadata (labels, type, project status, or deletion).
2. **Valid Issues Not in Changelog** — Closed, non-excluded milestone issues
that lack a changelog entry (with notes on duplicates and unmerged closing PRs).
3. **Unmerged PRs Referenced** — PRs in the changelog that are not merged.
Also verify that no closed-unmerged PRs remain in the changelog: The report is overwritten each time it's generated, reflecting the current
state of the milestone and changelog.
```bash
python3 tools/gh.py prs --milestone "<MILESTONE>" --state all | python3 -c "
import json, sys
data = json.load(sys.stdin)
closed = [p for p in data if p['state'] == 'CLOSED']
if closed:
print('WARNING: CLOSED (unmerged) PRs in milestone:')
for p in closed:
print(f' #{p[\"number\"]} {p[\"title\"][:80]}')
"
```
**Post-edit audit checklist:**
- ✅ All referenced PRs are merged (no closed-unmerged artifacts)
- ✅ Every merged milestone PR is either in the changelog or excluded by label
- ✅ PR and issue counts are internally consistent
- ✅ No false-positive PR-to-issue associations
## Key Principles ## Key Principles

View File

@ -138,7 +138,6 @@
- Duplicate token group [#9638](https://github.com/penpot/penpot/issues/9638) (PR: [#8886](https://github.com/penpot/penpot/pull/8886)) - Duplicate token group [#9638](https://github.com/penpot/penpot/issues/9638) (PR: [#8886](https://github.com/penpot/penpot/pull/8886))
- Copy token name from contextual menu [#9639](https://github.com/penpot/penpot/issues/9639) (PR: [#8566](https://github.com/penpot/penpot/pull/8566)) - Copy token name from contextual menu [#9639](https://github.com/penpot/penpot/issues/9639) (PR: [#8566](https://github.com/penpot/penpot/pull/8566))
- Add drag-to-change for numeric inputs in workspace sidebar (by @RenzoMXD) [#2466](https://github.com/penpot/penpot/issues/2466) (PR: [#8536](https://github.com/penpot/penpot/pull/8536)) - Add drag-to-change for numeric inputs in workspace sidebar (by @RenzoMXD) [#2466](https://github.com/penpot/penpot/issues/2466) (PR: [#8536](https://github.com/penpot/penpot/pull/8536))
- Add CSS linter [#9636](https://github.com/penpot/penpot/issues/9636) (PR: [#8592](https://github.com/penpot/penpot/pull/8592))
- Add per-group add button for typographies (by @eureka0928) [#5275](https://github.com/penpot/penpot/issues/5275) (PR: [#8895](https://github.com/penpot/penpot/pull/8895)) - Add per-group add button for typographies (by @eureka0928) [#5275](https://github.com/penpot/penpot/issues/5275) (PR: [#8895](https://github.com/penpot/penpot/pull/8895))
- Add Find & Replace for text content and layer names (by @statxc) [#7108](https://github.com/penpot/penpot/issues/7108) (PR: [#8899](https://github.com/penpot/penpot/pull/8899), [#9687](https://github.com/penpot/penpot/pull/9687)) - Add Find & Replace for text content and layer names (by @statxc) [#7108](https://github.com/penpot/penpot/issues/7108) (PR: [#8899](https://github.com/penpot/penpot/pull/8899), [#9687](https://github.com/penpot/penpot/pull/9687))
- Use page name for multi-export ZIP/PDF downloads (by @Dexterity104) [#8773](https://github.com/penpot/penpot/issues/8773) (PR: [#8874](https://github.com/penpot/penpot/pull/8874)) - Use page name for multi-export ZIP/PDF downloads (by @Dexterity104) [#8773](https://github.com/penpot/penpot/issues/8773) (PR: [#8874](https://github.com/penpot/penpot/pull/8874))
@ -169,10 +168,9 @@
- Preserve Inkscape labels when pasting SVGs (by @jeffrey701) [#7869](https://github.com/penpot/penpot/issues/7869) (PR: [#9252](https://github.com/penpot/penpot/pull/9252)) - Preserve Inkscape labels when pasting SVGs (by @jeffrey701) [#7869](https://github.com/penpot/penpot/issues/7869) (PR: [#9252](https://github.com/penpot/penpot/pull/9252))
- Add Alt+click to expand layer subtree (by @MilosM348) [#7736](https://github.com/penpot/penpot/issues/7736) (PR: [#9179](https://github.com/penpot/penpot/pull/9179)) - Add Alt+click to expand layer subtree (by @MilosM348) [#7736](https://github.com/penpot/penpot/issues/7736) (PR: [#9179](https://github.com/penpot/penpot/pull/9179))
- Allow deleting the profile avatar after uploading (by @moorsecopers99) [#9067](https://github.com/penpot/penpot/issues/9067) (PR: [#9068](https://github.com/penpot/penpot/pull/9068)) - Allow deleting the profile avatar after uploading (by @moorsecopers99) [#9067](https://github.com/penpot/penpot/issues/9067) (PR: [#9068](https://github.com/penpot/penpot/pull/9068))
- Clarify self-hosted OIDC configuration for containerized (by @sancfc) [#9764](https://github.com/penpot/penpot/issues/9764) (PR: [#9758](https://github.com/penpot/penpot/pull/9758))
- Update User Guide with 2.16 features (by @myfunnyandy) [#9767](https://github.com/penpot/penpot/issues/9767) (PR: [#9768](https://github.com/penpot/penpot/pull/9768))
- Improve file validation performance and fix orphan shape detection [#9790](https://github.com/penpot/penpot/issues/9790) (PR: [#9789](https://github.com/penpot/penpot/pull/9789)) - Improve file validation performance and fix orphan shape detection [#9790](https://github.com/penpot/penpot/issues/9790) (PR: [#9789](https://github.com/penpot/penpot/pull/9789))
- Add v2.16 release notes (What's new modal) [#9945](https://github.com/penpot/penpot/issues/9945) (PR: [#9940](https://github.com/penpot/penpot/pull/9940)) - Add v2.16 release notes (What's new modal) [#9945](https://github.com/penpot/penpot/issues/9945) (PR: [#9940](https://github.com/penpot/penpot/pull/9940))
- Enable multi-instance horizontal scaling for MCP server [#10000](https://github.com/penpot/penpot/issues/10000) (PR: [#10013](https://github.com/penpot/penpot/pull/10013))
### :bug: Bugs fixed ### :bug: Bugs fixed
@ -234,7 +232,6 @@
- Fix `:heigth` typo in clipboard frame-same-size? (by @iot2edge) [#9249](https://github.com/penpot/penpot/issues/9249) (PR: [#9250](https://github.com/penpot/penpot/pull/9250)) - Fix `:heigth` typo in clipboard frame-same-size? (by @iot2edge) [#9249](https://github.com/penpot/penpot/issues/9249) (PR: [#9250](https://github.com/penpot/penpot/pull/9250))
- Fix Settings Update button enabled state (by @moorsecopers99) [#9090](https://github.com/penpot/penpot/issues/9090) (PR: [#9091](https://github.com/penpot/penpot/pull/9091)) - Fix Settings Update button enabled state (by @moorsecopers99) [#9090](https://github.com/penpot/penpot/issues/9090) (PR: [#9091](https://github.com/penpot/penpot/pull/9091))
- Fix library updates reappearing after reload [#9326](https://github.com/penpot/penpot/issues/9326) (PR: [#9563](https://github.com/penpot/penpot/pull/9563)) - Fix library updates reappearing after reload [#9326](https://github.com/penpot/penpot/issues/9326) (PR: [#9563](https://github.com/penpot/penpot/pull/9563))
- Fix dependency libraries visible after unlinking main library [#9331](https://github.com/penpot/penpot/issues/9331) (PR: [#9511](https://github.com/penpot/penpot/pull/9511))
- Fix internal error on margins [#9309](https://github.com/penpot/penpot/issues/9309) (PR: [#9311](https://github.com/penpot/penpot/pull/9311)) - Fix internal error on margins [#9309](https://github.com/penpot/penpot/issues/9309) (PR: [#9311](https://github.com/penpot/penpot/pull/9311))
- Remove drag-to-change when token applied on numeric input [#9313](https://github.com/penpot/penpot/issues/9313) (PR: [#9314](https://github.com/penpot/penpot/pull/9314)) - Remove drag-to-change when token applied on numeric input [#9313](https://github.com/penpot/penpot/issues/9313) (PR: [#9314](https://github.com/penpot/penpot/pull/9314))
- Fix extra input on canvas background [#9359](https://github.com/penpot/penpot/issues/9359) (PR: [#9360](https://github.com/penpot/penpot/pull/9360)) - Fix extra input on canvas background [#9359](https://github.com/penpot/penpot/issues/9359) (PR: [#9360](https://github.com/penpot/penpot/pull/9360))
@ -242,20 +239,16 @@
- Fix several color picker issues [#9556](https://github.com/penpot/penpot/issues/9556) (PR: [#9558](https://github.com/penpot/penpot/pull/9558)) - Fix several color picker issues [#9556](https://github.com/penpot/penpot/issues/9556) (PR: [#9558](https://github.com/penpot/penpot/pull/9558))
- Fix asset icon broken on Asset tab [#9587](https://github.com/penpot/penpot/issues/9587) (PR: [#9612](https://github.com/penpot/penpot/pull/9612)) - Fix asset icon broken on Asset tab [#9587](https://github.com/penpot/penpot/issues/9587) (PR: [#9612](https://github.com/penpot/penpot/pull/9612))
- Fix text fill color stops updating in multiselect with texts [#9608](https://github.com/penpot/penpot/issues/9608) (PR: [#9549](https://github.com/penpot/penpot/pull/9549)) - Fix text fill color stops updating in multiselect with texts [#9608](https://github.com/penpot/penpot/issues/9608) (PR: [#9549](https://github.com/penpot/penpot/pull/9549))
- Fix editing a legacy text element silently detaches its color token [#9255](https://github.com/penpot/penpot/issues/9255) (PR: [#9525](https://github.com/penpot/penpot/pull/9525))
- Fix token application to grid paddings [#9494](https://github.com/penpot/penpot/issues/9494) (PR: [#9630](https://github.com/penpot/penpot/pull/9630))
- Fix file crashing when switching a variant [#9259](https://github.com/penpot/penpot/issues/9259) (PR: [#9147](https://github.com/penpot/penpot/pull/9147))
- Fix set activation after renaming [#9329](https://github.com/penpot/penpot/issues/9329) (PR: [#9545](https://github.com/penpot/penpot/pull/9545))
- Fix font selection position hiding available fonts [#9489](https://github.com/penpot/penpot/issues/9489) (PR: [#9499](https://github.com/penpot/penpot/pull/9499))
- Fix numeric input changes not saved when clicking on viewport [#9491](https://github.com/penpot/penpot/issues/9491) (PR: [#9548](https://github.com/penpot/penpot/pull/9548))
- Fix resize cursor appearing on login and register buttons [#9505](https://github.com/penpot/penpot/issues/9505) (PR: [#9590](https://github.com/penpot/penpot/pull/9590))
- Fix version restore restoring first previewed version instead of selected one [#9588](https://github.com/penpot/penpot/issues/9588) (PR: [#9626](https://github.com/penpot/penpot/pull/9626))
- Fix incorrect error message when applying tokens while editing text [#9620](https://github.com/penpot/penpot/issues/9620) (PR: [#9708](https://github.com/penpot/penpot/pull/9708))
- Fix standalone tokens ordering separated from token groups [#9733](https://github.com/penpot/penpot/issues/9733) (PR: [#9736](https://github.com/penpot/penpot/pull/9736)) - Fix standalone tokens ordering separated from token groups [#9733](https://github.com/penpot/penpot/issues/9733) (PR: [#9736](https://github.com/penpot/penpot/pull/9736))
- Fix delete invitation modal readability in light theme [#9737](https://github.com/penpot/penpot/issues/9737) (PR: [#9747](https://github.com/penpot/penpot/pull/9747)) - Fix delete invitation modal readability in light theme [#9737](https://github.com/penpot/penpot/issues/9737) (PR: [#9747](https://github.com/penpot/penpot/pull/9747))
- Fix team invitation not automatically accepted after account validation [#9776](https://github.com/penpot/penpot/issues/9776) (PR: [#9782](https://github.com/penpot/penpot/pull/9782)) - Fix team invitation not automatically accepted after account validation [#9776](https://github.com/penpot/penpot/issues/9776) (PR: [#9782](https://github.com/penpot/penpot/pull/9782))
- Fix design tokens vanishing from the sidebar when a token name collides with a token-group prefix from another active set (e.g. `a` in one set and `a.b` in another); the colliding token is now kept and rendered as a broken pill [Github #9584](https://github.com/penpot/penpot/issues/9584)
- Fix Plugin API addRulerGuide creating guides on page instead of board (by @girafic) [#8225](https://github.com/penpot/penpot/issues/8225) (PR: [#8632](https://github.com/penpot/penpot/pull/8632)) - Fix Plugin API addRulerGuide creating guides on page instead of board (by @girafic) [#8225](https://github.com/penpot/penpot/issues/8225) (PR: [#8632](https://github.com/penpot/penpot/pull/8632))
- Fix text editor not swapping correctly when enabling/disabling WebGL [#10015](https://github.com/penpot/penpot/issues/10015)
- Fix WebGL renderer focus mode leaving artefacts [#10061](https://github.com/penpot/penpot/issues/10061) (PR: [#10091](https://github.com/penpot/penpot/pull/10091))
- Fix double click on text selecting underlying element when WebGL render is enabled [#10080](https://github.com/penpot/penpot/issues/10080) (PR: [#10123](https://github.com/penpot/penpot/pull/10123))
- Fix publishing or unpublishing file as library failing with unexpected state found error [#10094](https://github.com/penpot/penpot/issues/10094) (PR: [#10093](https://github.com/penpot/penpot/pull/10093))
- Fix team invitation failing when email address contains consecutive dots in domain [#10097](https://github.com/penpot/penpot/issues/10097) (PR: [#10096](https://github.com/penpot/penpot/pull/10096))
- Add detailed error messages for unspecified import errors [#9759](https://github.com/penpot/penpot/issues/9759) (PR: [#9886](https://github.com/penpot/penpot/pull/9886))
## 2.15.4 ## 2.15.4

View File

@ -4,9 +4,9 @@
:deps :deps
{penpot/common {:local/root "../common"} {penpot/common {:local/root "../common"}
org.clojure/clojure {:mvn/version "1.12.5"} org.clojure/clojure {:mvn/version "1.12.5"}
org.clojure/tools.namespace {:mvn/version "1.5.0"} org.clojure/tools.namespace {:mvn/version "1.5.1"}
com.github.luben/zstd-jni {:mvn/version "1.5.7-4"} com.github.luben/zstd-jni {:mvn/version "1.5.7-10"}
io.prometheus/simpleclient {:mvn/version "0.16.0"} io.prometheus/simpleclient {:mvn/version "0.16.0"}
io.prometheus/simpleclient_hotspot {:mvn/version "0.16.0"} io.prometheus/simpleclient_hotspot {:mvn/version "0.16.0"}
@ -17,7 +17,7 @@
io.prometheus/simpleclient_httpserver {:mvn/version "0.16.0"} io.prometheus/simpleclient_httpserver {:mvn/version "0.16.0"}
io.lettuce/lettuce-core {:mvn/version "7.5.1.RELEASE"} io.lettuce/lettuce-core {:mvn/version "7.6.0.RELEASE"}
;; Minimal dependencies required by lettuce, we need to include them ;; Minimal dependencies required by lettuce, we need to include them
;; explicitly because clojure dependency management does not support ;; explicitly because clojure dependency management does not support
;; yet the BOM format. ;; yet the BOM format.
@ -25,7 +25,7 @@
io.micrometer/micrometer-observation {:mvn/version "1.14.2"} io.micrometer/micrometer-observation {:mvn/version "1.14.2"}
java-http-clj/java-http-clj {:mvn/version "0.4.3"} java-http-clj/java-http-clj {:mvn/version "0.4.3"}
com.google.guava/guava {:mvn/version "33.4.8-jre"} com.google.guava/guava {:mvn/version "33.6.0-jre"}
funcool/yetti funcool/yetti
{:git/tag "v11.10" {:git/tag "v11.10"
@ -34,13 +34,13 @@
:exclusions [org.slf4j/slf4j-api]} :exclusions [org.slf4j/slf4j-api]}
com.github.seancorfield/next.jdbc com.github.seancorfield/next.jdbc
{:mvn/version "1.3.1093"} {:mvn/version "1.3.1108"}
metosin/reitit-core {:mvn/version "0.9.1"} metosin/reitit-core {:mvn/version "0.10.1"}
nrepl/nrepl {:mvn/version "1.7.0"} nrepl/nrepl {:mvn/version "1.7.0"}
org.postgresql/postgresql {:mvn/version "42.7.11"} org.postgresql/postgresql {:mvn/version "42.7.11"}
org.xerial/sqlite-jdbc {:mvn/version "3.50.3.0"} org.xerial/sqlite-jdbc {:mvn/version "3.53.2.0"}
com.zaxxer/HikariCP {:mvn/version "7.0.2"} com.zaxxer/HikariCP {:mvn/version "7.0.2"}
@ -51,7 +51,7 @@
com.github.ben-manes.caffeine/caffeine {:mvn/version "3.2.4"} com.github.ben-manes.caffeine/caffeine {:mvn/version "3.2.4"}
org.jsoup/jsoup {:mvn/version "1.21.2"} org.jsoup/jsoup {:mvn/version "1.22.2"}
org.im4java/im4java org.im4java/im4java
{:git/tag "1.4.0-penpot-2" {:git/tag "1.4.0-penpot-2"
:git/sha "e2b3e16" :git/sha "e2b3e16"
@ -63,18 +63,18 @@
org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"} org.clojars.pntblnk/clj-ldap {:mvn/version "0.0.17"}
dawran6/emoji {:mvn/version "0.2.0"} dawran6/emoji {:mvn/version "0.2.0"}
markdown-clj/markdown-clj {:mvn/version "1.12.4"} markdown-clj/markdown-clj {:mvn/version "1.12.8"}
;; Pretty Print specs ;; Pretty Print specs
pretty-spec/pretty-spec {:mvn/version "0.1.4"} pretty-spec/pretty-spec {:mvn/version "0.1.4"}
software.amazon.awssdk/s3 {:mvn/version "2.44.4"} software.amazon.awssdk/s3 {:mvn/version "2.46.7"}
software.amazon.awssdk/sts {:mvn/version "2.44.4"}} software.amazon.awssdk/sts {:mvn/version "2.46.7"}}
:paths ["src" "resources" "target/classes"] :paths ["src" "resources" "target/classes"]
:aliases :aliases
{:dev {:dev
{:extra-deps {:extra-deps
{com.bhauman/rebel-readline {:mvn/version "0.1.5"} {com.bhauman/rebel-readline {:mvn/version "0.1.7"}
clojure-humanize/clojure-humanize {:mvn/version "0.2.2"} clojure-humanize/clojure-humanize {:mvn/version "0.2.2"}
org.clojure/data.csv {:mvn/version "1.1.1"} org.clojure/data.csv {:mvn/version "1.1.1"}
com.clojure-goes-fast/clj-async-profiler {:mvn/version "2.0.0-beta1"} com.clojure-goes-fast/clj-async-profiler {:mvn/version "2.0.0-beta1"}
@ -83,7 +83,7 @@
:build :build
{:extra-deps {:extra-deps
{io.github.clojure/tools.build {:mvn/version "0.10.10"}} {io.github.clojure/tools.build {:mvn/version "0.10.14"}}
:ns-default build} :ns-default build}
:test :test

View File

@ -62,7 +62,7 @@
(def default (def default
{:database-uri "postgresql://postgres/penpot_test" {:database-uri "postgresql://postgres/penpot_test"
:redis-uri "redis://redis/1" :redis-uri "redis://valkey/1"
:auto-file-snapshot-every 1 :auto-file-snapshot-every 1
:file-data-backend "db"}) :file-data-backend "db"})

View File

@ -6,7 +6,7 @@
org.clojure/data.fressian {:mvn/version "1.1.1"} org.clojure/data.fressian {:mvn/version "1.1.1"}
org.clojure/clojurescript {:mvn/version "1.12.42"} org.clojure/clojurescript {:mvn/version "1.12.42"}
org.apache.commons/commons-pool2 {:mvn/version "2.12.1"} org.apache.commons/commons-pool2 {:mvn/version "2.13.1"}
;; Logging ;; Logging
org.apache.logging.log4j/log4j-api {:mvn/version "2.26.0"} org.apache.logging.log4j/log4j-api {:mvn/version "2.26.0"}
@ -15,12 +15,12 @@
org.apache.logging.log4j/log4j-jul {:mvn/version "2.26.0"} org.apache.logging.log4j/log4j-jul {:mvn/version "2.26.0"}
org.apache.logging.log4j/log4j-slf4j2-impl {:mvn/version "2.26.0"} org.apache.logging.log4j/log4j-slf4j2-impl {:mvn/version "2.26.0"}
org.slf4j/slf4j-api {:mvn/version "2.0.18"} org.slf4j/slf4j-api {:mvn/version "2.0.18"}
pl.tkowalcz.tjahzi/log4j2-appender {:mvn/version "0.9.41"} pl.tkowalcz.tjahzi/log4j2-appender {:mvn/version "0.9.42"}
selmer/selmer {:mvn/version "1.13.1"} selmer/selmer {:mvn/version "1.13.4"}
criterium/criterium {:mvn/version "0.4.6"} criterium/criterium {:mvn/version "0.4.6"}
metosin/jsonista {:mvn/version "0.3.13"} metosin/jsonista {:mvn/version "1.0.0"}
metosin/malli {:mvn/version "0.19.1"} metosin/malli {:mvn/version "0.19.1"}
expound/expound {:mvn/version "0.9.0"} expound/expound {:mvn/version "0.9.0"}
@ -55,7 +55,7 @@
:aliases :aliases
{:dev {:dev
{:extra-deps {:extra-deps
{org.clojure/tools.namespace {:mvn/version "1.5.0"} {org.clojure/tools.namespace {:mvn/version "1.5.1"}
thheller/shadow-cljs {:mvn/version "3.2.0"} thheller/shadow-cljs {:mvn/version "3.2.0"}
com.clojure-goes-fast/clj-async-profiler {:mvn/version "2.0.0-beta1"} com.clojure-goes-fast/clj-async-profiler {:mvn/version "2.0.0-beta1"}
com.bhauman/rebel-readline {:mvn/version "0.1.5"} com.bhauman/rebel-readline {:mvn/version "0.1.5"}
@ -65,7 +65,7 @@
:build :build
{:extra-deps {:extra-deps
{io.github.clojure/tools.build {:mvn/version "0.10.10"}} {io.github.clojure/tools.build {:mvn/version "0.10.14"}}
:ns-default build} :ns-default build}
:test :test

View File

@ -4,21 +4,21 @@
"license": "MPL-2.0", "license": "MPL-2.0",
"author": "Kaleidos INC Sucursal en España SL", "author": "Kaleidos INC Sucursal en España SL",
"private": true, "private": true,
"packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268", "packageManager": "pnpm@11.5.3+sha512.7ac1c919341c213a34dc0d02afb7143c5c26ac26ee8c4782deea821b8ac64d2134a081fd8941dae6e29bbb48f58dfc2b7fbceeccc07cb2f09d219d342a4969ed",
"type": "module", "type": "module",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/penpot/penpot" "url": "https://github.com/penpot/penpot"
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^9.1.2", "concurrently": "^10.0.3",
"nodemon": "^3.1.10", "nodemon": "^3.1.14",
"prettier": "3.5.3", "prettier": "3.8.4",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"ws": "^8.18.2" "ws": "^8.21.0"
}, },
"dependencies": { "dependencies": {
"date-fns": "^4.1.0" "date-fns": "^4.4.0"
}, },
"scripts": { "scripts": {
"lint:clj": "clj-kondo --parallel=true --lint src/", "lint:clj": "clj-kondo --parallel=true --lint src/",

288
common/pnpm-lock.yaml generated
View File

@ -9,48 +9,50 @@ importers:
.: .:
dependencies: dependencies:
date-fns: date-fns:
specifier: ^4.1.0 specifier: ^4.4.0
version: 4.1.0 version: 4.4.0
devDependencies: devDependencies:
concurrently: concurrently:
specifier: ^9.1.2 specifier: ^10.0.3
version: 9.2.1 version: 10.0.3
nodemon: nodemon:
specifier: ^3.1.10 specifier: ^3.1.14
version: 3.1.11 version: 3.1.14
prettier: prettier:
specifier: 3.5.3 specifier: 3.8.4
version: 3.5.3 version: 3.8.4
source-map-support: source-map-support:
specifier: ^0.5.21 specifier: ^0.5.21
version: 0.5.21 version: 0.5.21
ws: ws:
specifier: ^8.18.2 specifier: ^8.21.0
version: 8.18.3 version: 8.21.0
packages: packages:
ansi-regex@5.0.1: ansi-regex@6.2.2:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=8'} engines: {node: '>=12'}
ansi-styles@4.3.0: ansi-styles@6.2.3:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=8'} engines: {node: '>=12'}
anymatch@3.1.3: anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
balanced-match@1.0.2: balanced-match@4.0.4:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
binary-extensions@2.3.0: binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'} engines: {node: '>=8'}
brace-expansion@1.1.12: brace-expansion@5.0.6:
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
engines: {node: 18 || 20 || >=22}
braces@3.0.3: braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
@ -59,35 +61,25 @@ packages:
buffer-from@1.1.2: buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
chalk@4.1.2: chalk@5.6.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
engines: {node: '>=10'} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
chokidar@3.6.0: chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'} engines: {node: '>= 8.10.0'}
cliui@8.0.1: cliui@9.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==}
engines: {node: '>=12'} engines: {node: '>=20'}
color-convert@2.0.1: concurrently@10.0.3:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} resolution: {integrity: sha512-hc3LH4UaKWd/bbyDK/IGVa4RB6PtQ3CUYwtrkzqHn+wIG3Hr5fhpRlk0L/gCa8ZE1L/Ufj50Zho69cI5w8SQBA==}
engines: {node: '>=7.0.0'} engines: {node: '>=22'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
concurrently@9.2.1:
resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==}
engines: {node: '>=18'}
hasBin: true hasBin: true
date-fns@4.1.0: date-fns@4.4.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==}
debug@4.4.3: debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
@ -98,8 +90,8 @@ packages:
supports-color: supports-color:
optional: true optional: true
emoji-regex@8.0.0: emoji-regex@10.6.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==}
escalade@3.2.0: escalade@3.2.0:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
@ -118,6 +110,10 @@ packages:
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
engines: {node: 6.* || 8.* || >= 10.*} engines: {node: 6.* || 8.* || >= 10.*}
get-east-asian-width@1.6.0:
resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==}
engines: {node: '>=18'}
glob-parent@5.1.2: glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -126,10 +122,6 @@ packages:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'} engines: {node: '>=4'}
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
ignore-by-default@1.0.1: ignore-by-default@1.0.1:
resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
@ -141,10 +133,6 @@ packages:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
is-glob@4.0.3: is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -153,14 +141,15 @@ packages:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'} engines: {node: '>=0.12.0'}
minimatch@3.1.2: minimatch@10.2.5:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
engines: {node: 18 || 20 || >=22}
ms@2.1.3: ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
nodemon@3.1.11: nodemon@3.1.14:
resolution: {integrity: sha512-is96t8F/1//UHAjNPHpbsNY46ELPpftGUoSVNXwUfMk/qdjSylYrWSu1XavVTBOn526kFiOR733ATgNBCQyH0g==} resolution: {integrity: sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==}
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
@ -168,12 +157,12 @@ packages:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
picomatch@2.3.1: picomatch@2.3.2:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
prettier@3.5.3: prettier@3.8.4:
resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==}
engines: {node: '>=14'} engines: {node: '>=14'}
hasBin: true hasBin: true
@ -184,20 +173,16 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
require-directory@2.1.1:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
rxjs@7.8.2: rxjs@7.8.2:
resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
semver@7.7.3: semver@7.8.4:
resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==}
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
shell-quote@1.8.3: shell-quote@1.8.4:
resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
simple-update-notifier@2.0.0: simple-update-notifier@2.0.0:
@ -211,26 +196,22 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
string-width@4.2.3: string-width@7.2.0:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=8'} engines: {node: '>=18'}
strip-ansi@6.0.1: strip-ansi@7.2.0:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
engines: {node: '>=8'} engines: {node: '>=12'}
supports-color@10.2.2:
resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==}
engines: {node: '>=18'}
supports-color@5.5.0: supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'} engines: {node: '>=4'}
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
supports-color@8.1.1:
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
engines: {node: '>=10'}
to-regex-range@5.0.1: to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
@ -249,12 +230,12 @@ packages:
undefsafe@2.0.5: undefsafe@2.0.5:
resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
wrap-ansi@7.0.0: wrap-ansi@9.0.2:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=10'} engines: {node: '>=18'}
ws@8.18.3: ws@8.21.0:
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
peerDependencies: peerDependencies:
bufferutil: ^4.0.1 bufferutil: ^4.0.1
@ -269,35 +250,32 @@ packages:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'} engines: {node: '>=10'}
yargs-parser@21.1.1: yargs-parser@22.0.0:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
engines: {node: '>=12'} engines: {node: ^20.19.0 || ^22.12.0 || >=23}
yargs@17.7.2: yargs@18.0.0:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==}
engines: {node: '>=12'} engines: {node: ^20.19.0 || ^22.12.0 || >=23}
snapshots: snapshots:
ansi-regex@5.0.1: {} ansi-regex@6.2.2: {}
ansi-styles@4.3.0: ansi-styles@6.2.3: {}
dependencies:
color-convert: 2.0.1
anymatch@3.1.3: anymatch@3.1.3:
dependencies: dependencies:
normalize-path: 3.0.0 normalize-path: 3.0.0
picomatch: 2.3.1 picomatch: 2.3.2
balanced-match@1.0.2: {} balanced-match@4.0.4: {}
binary-extensions@2.3.0: {} binary-extensions@2.3.0: {}
brace-expansion@1.1.12: brace-expansion@5.0.6:
dependencies: dependencies:
balanced-match: 1.0.2 balanced-match: 4.0.4
concat-map: 0.0.1
braces@3.0.3: braces@3.0.3:
dependencies: dependencies:
@ -305,10 +283,7 @@ snapshots:
buffer-from@1.1.2: {} buffer-from@1.1.2: {}
chalk@4.1.2: chalk@5.6.2: {}
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
chokidar@3.6.0: chokidar@3.6.0:
dependencies: dependencies:
@ -322,30 +297,22 @@ snapshots:
optionalDependencies: optionalDependencies:
fsevents: 2.3.3 fsevents: 2.3.3
cliui@8.0.1: cliui@9.0.1:
dependencies: dependencies:
string-width: 4.2.3 string-width: 7.2.0
strip-ansi: 6.0.1 strip-ansi: 7.2.0
wrap-ansi: 7.0.0 wrap-ansi: 9.0.2
color-convert@2.0.1: concurrently@10.0.3:
dependencies: dependencies:
color-name: 1.1.4 chalk: 5.6.2
color-name@1.1.4: {}
concat-map@0.0.1: {}
concurrently@9.2.1:
dependencies:
chalk: 4.1.2
rxjs: 7.8.2 rxjs: 7.8.2
shell-quote: 1.8.3 shell-quote: 1.8.4
supports-color: 8.1.1 supports-color: 10.2.2
tree-kill: 1.2.2 tree-kill: 1.2.2
yargs: 17.7.2 yargs: 18.0.0
date-fns@4.1.0: {} date-fns@4.4.0: {}
debug@4.4.3(supports-color@5.5.0): debug@4.4.3(supports-color@5.5.0):
dependencies: dependencies:
@ -353,7 +320,7 @@ snapshots:
optionalDependencies: optionalDependencies:
supports-color: 5.5.0 supports-color: 5.5.0
emoji-regex@8.0.0: {} emoji-regex@10.6.0: {}
escalade@3.2.0: {} escalade@3.2.0: {}
@ -366,14 +333,14 @@ snapshots:
get-caller-file@2.0.5: {} get-caller-file@2.0.5: {}
get-east-asian-width@1.6.0: {}
glob-parent@5.1.2: glob-parent@5.1.2:
dependencies: dependencies:
is-glob: 4.0.3 is-glob: 4.0.3
has-flag@3.0.0: {} has-flag@3.0.0: {}
has-flag@4.0.0: {}
ignore-by-default@1.0.1: {} ignore-by-default@1.0.1: {}
is-binary-path@2.1.0: is-binary-path@2.1.0:
@ -382,28 +349,26 @@ snapshots:
is-extglob@2.1.1: {} is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
is-glob@4.0.3: is-glob@4.0.3:
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
is-number@7.0.0: {} is-number@7.0.0: {}
minimatch@3.1.2: minimatch@10.2.5:
dependencies: dependencies:
brace-expansion: 1.1.12 brace-expansion: 5.0.6
ms@2.1.3: {} ms@2.1.3: {}
nodemon@3.1.11: nodemon@3.1.14:
dependencies: dependencies:
chokidar: 3.6.0 chokidar: 3.6.0
debug: 4.4.3(supports-color@5.5.0) debug: 4.4.3(supports-color@5.5.0)
ignore-by-default: 1.0.1 ignore-by-default: 1.0.1
minimatch: 3.1.2 minimatch: 10.2.5
pstree.remy: 1.1.8 pstree.remy: 1.1.8
semver: 7.7.3 semver: 7.8.4
simple-update-notifier: 2.0.0 simple-update-notifier: 2.0.0
supports-color: 5.5.0 supports-color: 5.5.0
touch: 3.1.1 touch: 3.1.1
@ -411,29 +376,27 @@ snapshots:
normalize-path@3.0.0: {} normalize-path@3.0.0: {}
picomatch@2.3.1: {} picomatch@2.3.2: {}
prettier@3.5.3: {} prettier@3.8.4: {}
pstree.remy@1.1.8: {} pstree.remy@1.1.8: {}
readdirp@3.6.0: readdirp@3.6.0:
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.2
require-directory@2.1.1: {}
rxjs@7.8.2: rxjs@7.8.2:
dependencies: dependencies:
tslib: 2.8.1 tslib: 2.8.1
semver@7.7.3: {} semver@7.8.4: {}
shell-quote@1.8.3: {} shell-quote@1.8.4: {}
simple-update-notifier@2.0.0: simple-update-notifier@2.0.0:
dependencies: dependencies:
semver: 7.7.3 semver: 7.8.4
source-map-support@0.5.21: source-map-support@0.5.21:
dependencies: dependencies:
@ -442,28 +405,22 @@ snapshots:
source-map@0.6.1: {} source-map@0.6.1: {}
string-width@4.2.3: string-width@7.2.0:
dependencies: dependencies:
emoji-regex: 8.0.0 emoji-regex: 10.6.0
is-fullwidth-code-point: 3.0.0 get-east-asian-width: 1.6.0
strip-ansi: 6.0.1 strip-ansi: 7.2.0
strip-ansi@6.0.1: strip-ansi@7.2.0:
dependencies: dependencies:
ansi-regex: 5.0.1 ansi-regex: 6.2.2
supports-color@10.2.2: {}
supports-color@5.5.0: supports-color@5.5.0:
dependencies: dependencies:
has-flag: 3.0.0 has-flag: 3.0.0
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
supports-color@8.1.1:
dependencies:
has-flag: 4.0.0
to-regex-range@5.0.1: to-regex-range@5.0.1:
dependencies: dependencies:
is-number: 7.0.0 is-number: 7.0.0
@ -476,24 +433,23 @@ snapshots:
undefsafe@2.0.5: {} undefsafe@2.0.5: {}
wrap-ansi@7.0.0: wrap-ansi@9.0.2:
dependencies: dependencies:
ansi-styles: 4.3.0 ansi-styles: 6.2.3
string-width: 4.2.3 string-width: 7.2.0
strip-ansi: 6.0.1 strip-ansi: 7.2.0
ws@8.18.3: {} ws@8.21.0: {}
y18n@5.0.8: {} y18n@5.0.8: {}
yargs-parser@21.1.1: {} yargs-parser@22.0.0: {}
yargs@17.7.2: yargs@18.0.0:
dependencies: dependencies:
cliui: 8.0.1 cliui: 9.0.1
escalade: 3.2.0 escalade: 3.2.0
get-caller-file: 2.0.5 get-caller-file: 2.0.5
require-directory: 2.1.1 string-width: 7.2.0
string-width: 4.2.3
y18n: 5.0.8 y18n: 5.0.8
yargs-parser: 21.1.1 yargs-parser: 22.0.0

View File

@ -0,0 +1 @@
minimumReleaseAge: 0

View File

@ -159,7 +159,7 @@ goog.scope(function () {
it1--, i++ it1--, i++
) { ) {
carry += (256 * b58[it1]) >>> 0; carry += (256 * b58[it1]) >>> 0;
b58[it1] = carry % BASE >>> 0; b58[it1] = (carry % BASE) >>> 0;
carry = (carry / BASE) >>> 0; carry = (carry / BASE) >>> 0;
} }
if (carry !== 0) { if (carry !== 0) {
@ -214,7 +214,7 @@ goog.scope(function () {
it3--, i++ it3--, i++
) { ) {
carry += (BASE * b256[it3]) >>> 0; carry += (BASE * b256[it3]) >>> 0;
b256[it3] = carry % 256 >>> 0; b256[it3] = (carry % 256) >>> 0;
carry = (carry / 256) >>> 0; carry = (carry / 256) >>> 0;
} }
if (carry !== 0) { if (carry !== 0) {

View File

@ -448,18 +448,22 @@
::oapi/type "string" ::oapi/type "string"
::oapi/format "uuid"}}) ::oapi/format "uuid"}})
(def email-re #"[a-zA-Z0-9_.+-\\\\]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+") ;; Strict email regex aligned with app.common.spec/email-re.
;; Local part: valid RFC chars, no leading/trailing dot, no consecutive dots.
;; Domain: labels can't start/end with hyphen, no empty labels.
;; TLD: at least 2 alphabetic chars.
(def email-re
#"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,63}")
(defn parse-email (defn parse-email
[s] [s]
(if (string? s) (when (and (string? s) (re-matches email-re s))
(first (re-seq email-re s)) s))
nil))
(defn email-string? (defn email-string?
[s] [s]
(and (string? s) (and (string? s)
(re-seq email-re s))) (some? (re-matches email-re s))))
(register! (register!
{:type ::email {:type ::email

View File

@ -217,11 +217,11 @@ goog.scope(function () {
// Parse ........-....-....-####-............ // Parse ........-....-....-####-............
int8[8] = (rest = parseInt(uuid.slice(19, 23), 16)) >>> 8; int8[8] = (rest = parseInt(uuid.slice(19, 23), 16)) >>> 8;
(int8[9] = rest & 0xff), ((int8[9] = rest & 0xff),
// Parse ........-....-....-....-############ // Parse ........-....-....-....-############
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
(int8[10] = (int8[10] =
((rest = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff); ((rest = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff));
int8[11] = (rest / 0x100000000) & 0xff; int8[11] = (rest / 0x100000000) & 0xff;
int8[12] = (rest >>> 24) & 0xff; int8[12] = (rest >>> 24) & 0xff;
int8[13] = (rest >>> 16) & 0xff; int8[13] = (rest >>> 16) & 0xff;

View File

@ -188,3 +188,60 @@
(t/is (= false (decode-s "f"))) (t/is (= false (decode-s "f")))
(t/is (= true (decode-s "1"))) (t/is (= true (decode-s "1")))
(t/is (= false (decode-s "0"))))) (t/is (= false (decode-s "0")))))
(t/deftest test-email-validation
(t/testing "accepts well-formed email addresses"
(doseq [email ["user@domain.com"
"user.name@domain.com"
"user+tag@domain.com"
"user-name@domain.com"
"user_name@domain.com"
"user123@domain.com"
"USER@DOMAIN.COM"
"u@domain.io"
"user@sub.domain.com"
"user@domain.co.uk"
"user@domain.dev"
"a@bc.co"]]
(t/is (sm/validate ::sm/email email) (str "should accept: " email))
(t/is (= email (sm/decode ::sm/email email sm/json-transformer)))))
(t/testing "rejects domain with consecutive dots (dot-dot)"
(t/is (false? (sm/validate ::sm/email "user@gmail.com..")))
(t/is (false? (sm/validate ::sm/email "user@sub..domain.com")))
(t/is (false? (sm/validate ::sm/email "eissaalbothigi@gmail.com..")))
(t/is (nil? (sm/parse-email "user@gmail.com..")))
(t/is (nil? (sm/parse-email "eissaalbothigi@gmail.com.."))))
(t/testing "rejects domain ending with a dot"
(t/is (false? (sm/validate ::sm/email "user@domain.")))
(t/is (nil? (sm/parse-email "user@domain."))))
(t/testing "rejects domain starting with a dot"
(t/is (false? (sm/validate ::sm/email "user@.domain.com")))
(t/is (nil? (sm/parse-email "user@.domain.com"))))
(t/testing "rejects local part with consecutive dots"
(t/is (false? (sm/validate ::sm/email "user..name@domain.com")))
(t/is (nil? (sm/parse-email "user..name@domain.com"))))
(t/testing "rejects local part starting with a dot"
(t/is (false? (sm/validate ::sm/email ".user@domain.com")))
(t/is (nil? (sm/parse-email ".user@domain.com"))))
(t/testing "rejects label starting or ending with hyphen"
(t/is (false? (sm/validate ::sm/email "user@-domain.com")))
(t/is (false? (sm/validate ::sm/email "user@domain-.com"))))
(t/testing "rejects TLD shorter than 2 chars"
(t/is (false? (sm/validate ::sm/email "user@domain.c"))))
(t/testing "rejects domain without a dot"
(t/is (false? (sm/validate ::sm/email "user@domain"))))
(t/testing "rejects empty or malformed emails"
(t/is (false? (sm/validate ::sm/email "")))
(t/is (false? (sm/validate ::sm/email "@domain.com")))
(t/is (false? (sm/validate ::sm/email "user@")))
(t/is (false? (sm/validate ::sm/email "userdomain.com")))
(t/is (false? (sm/validate ::sm/email "user@@domain.com")))))

View File

@ -4,29 +4,29 @@
"license": "MPL-2.0", "license": "MPL-2.0",
"author": "Kaleidos INC Sucursal en España SL", "author": "Kaleidos INC Sucursal en España SL",
"private": true, "private": true,
"packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268", "packageManager": "pnpm@11.5.3+sha512.7ac1c919341c213a34dc0d02afb7143c5c26ac26ee8c4782deea821b8ac64d2134a081fd8941dae6e29bbb48f58dfc2b7fbceeccc07cb2f09d219d342a4969ed",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/penpot/penpot" "url": "https://github.com/penpot/penpot"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"archiver": "7.0.1", "archiver": "8.0.0",
"cookies": "^0.9.1", "cookies": "^0.9.1",
"date-fns": "^4.1.0", "date-fns": "^4.4.0",
"generic-pool": "^3.9.0", "generic-pool": "^3.9.0",
"inflation": "^2.1.0", "inflation": "^2.1.0",
"ioredis": "^5.10.1", "ioredis": "^5.11.1",
"playwright": "^1.60.0", "playwright": "^1.60.0",
"raw-body": "^3.0.2", "raw-body": "^3.0.2",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"svgo": "penpot/svgo#v3.1", "svgo": "penpot/svgo#v3.1",
"undici": "^8.2.0", "undici": "^8.4.1",
"xml-js": "^1.6.11", "xml-js": "^1.6.11",
"xregexp": "^5.1.2" "xregexp": "^5.1.2"
}, },
"devDependencies": { "devDependencies": {
"ws": "^8.20.1" "ws": "^8.21.0"
}, },
"scripts": { "scripts": {
"clear:shadow-cache": "rm -rf .shadow-cljs && rm -rf target", "clear:shadow-cache": "rm -rf .shadow-cljs && rm -rf target",

489
exporter/pnpm-lock.yaml generated
View File

@ -9,14 +9,14 @@ importers:
.: .:
dependencies: dependencies:
archiver: archiver:
specifier: 7.0.1 specifier: 8.0.0
version: 7.0.1 version: 8.0.0
cookies: cookies:
specifier: ^0.9.1 specifier: ^0.9.1
version: 0.9.1 version: 0.9.1
date-fns: date-fns:
specifier: ^4.1.0 specifier: ^4.4.0
version: 4.1.0 version: 4.4.0
generic-pool: generic-pool:
specifier: ^3.9.0 specifier: ^3.9.0
version: 3.9.0 version: 3.9.0
@ -24,8 +24,8 @@ importers:
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.1.0 version: 2.1.0
ioredis: ioredis:
specifier: ^5.10.1 specifier: ^5.11.1
version: 5.10.1 version: 5.11.1
playwright: playwright:
specifier: ^1.60.0 specifier: ^1.60.0
version: 1.60.0 version: 1.60.0
@ -39,8 +39,8 @@ importers:
specifier: penpot/svgo#v3.1 specifier: penpot/svgo#v3.1
version: https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180 version: https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180
undici: undici:
specifier: ^8.2.0 specifier: ^8.4.1
version: 8.2.0 version: 8.4.1
xml-js: xml-js:
specifier: ^1.6.11 specifier: ^1.6.11
version: 1.6.11 version: 1.6.11
@ -49,8 +49,8 @@ importers:
version: 5.1.2 version: 5.1.2
devDependencies: devDependencies:
ws: ws:
specifier: ^8.20.1 specifier: ^8.21.0
version: 8.20.1 version: 8.21.0
packages: packages:
@ -58,16 +58,8 @@ packages:
resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==} resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@ioredis/commands@1.5.1': '@ioredis/commands@1.10.0':
resolution: {integrity: sha512-JH8ZL/ywcJyR9MmJ5BNqZllXNZQqQbnVZOqpPQqE1vHiFgAw4NHbvE0FOduNU8IX9babitBT46571OnPTT0Zcw==} resolution: {integrity: sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q==}
'@isaacs/cliui@8.0.2':
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@trysound/sax@0.2.0': '@trysound/sax@0.2.0':
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
@ -77,29 +69,9 @@ packages:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'} engines: {node: '>=6.5'}
ansi-regex@5.0.1: archiver@8.0.0:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} resolution: {integrity: sha512-fV1orZfsnPn9BaSByR/qE67rJCLJEy2Ox5bq7nJh+jquWaNh6Sfec75kJ2T6PtdGUbPQlrVoSVCEOa5SdiTQ1g==}
engines: {node: '>=8'} engines: {node: '>=18'}
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
engines: {node: '>=12'}
ansi-styles@4.3.0:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
ansi-styles@6.2.3:
resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==}
engines: {node: '>=12'}
archiver-utils@5.0.2:
resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==}
engines: {node: '>= 14'}
archiver@7.0.1:
resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==}
engines: {node: '>= 14'}
async@3.2.6: async@3.2.6:
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
@ -112,19 +84,20 @@ packages:
react-native-b4a: react-native-b4a:
optional: true optional: true
balanced-match@1.0.2: balanced-match@4.0.4:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
bare-events@2.8.2: bare-events@2.9.1:
resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==}
peerDependencies: peerDependencies:
bare-abort-controller: '*' bare-abort-controller: '*'
peerDependenciesMeta: peerDependenciesMeta:
bare-abort-controller: bare-abort-controller:
optional: true optional: true
bare-fs@4.7.1: bare-fs@4.7.2:
resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==} resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==}
engines: {bare: '>=1.16.0'} engines: {bare: '>=1.16.0'}
peerDependencies: peerDependencies:
bare-buffer: '*' bare-buffer: '*'
@ -136,8 +109,8 @@ packages:
resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==}
engines: {bare: '>=1.14.0'} engines: {bare: '>=1.14.0'}
bare-path@3.0.0: bare-path@3.0.1:
resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==}
bare-stream@2.13.1: bare-stream@2.13.1:
resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==}
@ -153,8 +126,8 @@ packages:
bare-events: bare-events:
optional: true optional: true
bare-url@2.4.3: bare-url@2.4.5:
resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==} resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==}
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@ -162,8 +135,9 @@ packages:
boolbase@1.0.0: boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
brace-expansion@2.1.0: brace-expansion@5.0.6:
resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
engines: {node: 18 || 20 || >=22}
buffer-crc32@1.0.0: buffer-crc32@1.0.0:
resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==}
@ -179,20 +153,13 @@ packages:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
cluster-key-slot@1.1.2: cluster-key-slot@1.1.1:
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
color-convert@2.0.1: compress-commons@7.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} resolution: {integrity: sha512-g0S8KAD8qf4+V//pr3BfB1aBnARLXNz2Gx+jmHU0LEriUuoQUOPOulVquHKTJ8+EAIIO7fhseNDr9wK5Q9FKBQ==}
engines: {node: '>=7.0.0'} engines: {node: '>=18'}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
compress-commons@6.0.2:
resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==}
engines: {node: '>= 14'}
cookies@0.9.1: cookies@0.9.1:
resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==}
@ -209,13 +176,9 @@ packages:
engines: {node: '>=0.8'} engines: {node: '>=0.8'}
hasBin: true hasBin: true
crc32-stream@6.0.0: crc32-stream@7.0.1:
resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} resolution: {integrity: sha512-IBWsY8xznyQrcHn8h4bC8/4ErNke5elzgG8GcqF4RFPw6aHkWWRc7Tgw6upjaTX/CT/yQgqYENkxYsTYN+hW2g==}
engines: {node: '>= 14'} engines: {node: '>=18'}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
css-select@5.2.2: css-select@5.2.2:
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
@ -236,8 +199,8 @@ packages:
resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
date-fns@4.1.0: date-fns@4.4.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} resolution: {integrity: sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==}
debug@4.4.3: debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
@ -269,15 +232,6 @@ packages:
domutils@3.2.2: domutils@3.2.2:
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
emoji-regex@9.2.2:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
entities@4.5.0: entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
@ -296,10 +250,6 @@ packages:
fast-fifo@1.3.2: fast-fifo@1.3.2:
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
foreground-child@3.3.1:
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
engines: {node: '>=14'}
fsevents@2.3.2: fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -309,14 +259,6 @@ packages:
resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
glob@10.5.0:
resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
http-errors@2.0.1: http-errors@2.0.1:
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@ -335,27 +277,17 @@ packages:
inherits@2.0.4: inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
ioredis@5.10.1: ioredis@5.11.1:
resolution: {integrity: sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==} resolution: {integrity: sha512-ehuGcf94bQXhfagULNXrJdfnWO38v070jxSx/qE87Kjzmu2fU7ro5EFAb+OPituLqgfyuQaym5DlrNydW2sJ9A==}
engines: {node: '>=12.22.0'} engines: {node: '>=12.22.0'}
is-fullwidth-code-point@3.0.0: is-stream@4.0.1:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
engines: {node: '>=8'} engines: {node: '>=18'}
is-stream@2.0.1:
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
engines: {node: '>=8'}
isarray@1.0.0: isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
keygrip@1.1.0: keygrip@1.1.0:
resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
@ -365,35 +297,18 @@ packages:
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
engines: {node: '>= 0.6.3'} engines: {node: '>= 0.6.3'}
lodash.defaults@4.2.0:
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
lodash.isarguments@3.1.0:
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
lodash@4.17.21: lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
mdn-data@2.0.28: mdn-data@2.0.28:
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
mdn-data@2.12.2: mdn-data@2.12.2:
resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==}
minimatch@5.1.9: minimatch@10.2.5:
resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
engines: {node: '>=10'} engines: {node: 18 || 20 || >=22}
minimatch@9.0.9:
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
engines: {node: '>=16 || 14 >=14.17'}
minipass@7.1.3:
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
engines: {node: '>=16 || 14 >=14.17'}
ms@2.1.3: ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@ -405,17 +320,6 @@ packages:
nth-check@2.1.1: nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
path-key@3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
path-scurry@1.11.1:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
playwright-core@1.60.0: playwright-core@1.60.0:
resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -444,8 +348,9 @@ packages:
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
readdir-glob@1.1.3: readdir-glob@3.0.0:
resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} resolution: {integrity: sha512-AhNB2KgKeVJr16nK9LLZbJNWnYoT23ZrumNKFDebHBdkC8KHSqWo871JAUhoWC/RtjEVdqNMFpM6qrwRbaUqpw==}
engines: {node: '>=18'}
redis-errors@1.2.0: redis-errors@1.2.0:
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==}
@ -470,18 +375,6 @@ packages:
setprototypeof@1.2.0: setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
shebang-regex@3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
source-map-js@1.2.1: source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -500,16 +393,8 @@ packages:
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
streamx@2.25.0: streamx@2.27.0:
resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} resolution: {integrity: sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
string-width@5.1.2:
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
engines: {node: '>=12'}
string_decoder@1.1.1: string_decoder@1.1.1:
resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
@ -517,16 +402,8 @@ packages:
string_decoder@1.3.0: string_decoder@1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
strip-ansi@7.2.0:
resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
engines: {node: '>=12'}
svgo@https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180: svgo@https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180:
resolution: {tarball: https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180} resolution: {gitHosted: true, tarball: https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180}
version: 4.0.0 version: 4.0.0
engines: {node: '>=16.0.0'} engines: {node: '>=16.0.0'}
@ -547,8 +424,8 @@ packages:
resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==}
engines: {node: '>=0.6.x'} engines: {node: '>=0.6.x'}
undici@8.2.0: undici@8.4.1:
resolution: {integrity: sha512-Z+4Hx9GE26Lh9Upwfnc8C7SsrpBPGaM/Gm6kMFtiG7c+5IvQKlXi/t+9x9DrrCh29cww5TSP9YdVaBcnLDs5fQ==} resolution: {integrity: sha512-RNHlB4fxZK0IrkhBsxhlbx7s8kFWwr7rzzOqj5nvZugw3ig3RsB7KW3zVlV0eu8POl+rx5d1hmL7rRg0z1owow==}
engines: {node: '>=22.19.0'} engines: {node: '>=22.19.0'}
unpipe@1.0.0: unpipe@1.0.0:
@ -558,21 +435,8 @@ packages:
util-deprecate@1.0.2: util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
which@2.0.2: ws@8.21.0:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
engines: {node: '>= 8'}
hasBin: true
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
wrap-ansi@8.1.0:
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
engines: {node: '>=12'}
ws@8.20.1:
resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
peerDependencies: peerDependencies:
bufferutil: ^4.0.1 bufferutil: ^4.0.1
@ -590,9 +454,9 @@ packages:
xregexp@5.1.2: xregexp@5.1.2:
resolution: {integrity: sha512-6hGgEMCGhqCTFEJbqmWrNIPqfpdirdGWkqshu7fFZddmTSfgv5Sn9D2SaKloR79s5VUiUlpwzg3CM3G6D3VIlw==} resolution: {integrity: sha512-6hGgEMCGhqCTFEJbqmWrNIPqfpdirdGWkqshu7fFZddmTSfgv5Sn9D2SaKloR79s5VUiUlpwzg3CM3G6D3VIlw==}
zip-stream@6.0.1: zip-stream@7.0.5:
resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} resolution: {integrity: sha512-dSvYKdvLsAHCDqPOhIwk/q5CvuWtTB3Dgpoe0uVEFjTzIOAmsQpprX25InCvrvJsirEbu1OHyy67n/kAj1Sw/w==}
engines: {node: '>= 14'} engines: {node: '>=18'}
snapshots: snapshots:
@ -600,19 +464,7 @@ snapshots:
dependencies: dependencies:
core-js-pure: 3.47.0 core-js-pure: 3.47.0
'@ioredis/commands@1.5.1': {} '@ioredis/commands@1.10.0': {}
'@isaacs/cliui@8.0.2':
dependencies:
string-width: 5.1.2
string-width-cjs: string-width@4.2.3
strip-ansi: 7.2.0
strip-ansi-cjs: strip-ansi@6.0.1
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
'@pkgjs/parseargs@0.11.0':
optional: true
'@trysound/sax@0.2.0': {} '@trysound/sax@0.2.0': {}
@ -620,35 +472,17 @@ snapshots:
dependencies: dependencies:
event-target-shim: 5.0.1 event-target-shim: 5.0.1
ansi-regex@5.0.1: {} archiver@8.0.0:
ansi-regex@6.2.2: {}
ansi-styles@4.3.0:
dependencies: dependencies:
color-convert: 2.0.1
ansi-styles@6.2.3: {}
archiver-utils@5.0.2:
dependencies:
glob: 10.5.0
graceful-fs: 4.2.11
is-stream: 2.0.1
lazystream: 1.0.1
lodash: 4.17.21
normalize-path: 3.0.0
readable-stream: 4.7.0
archiver@7.0.1:
dependencies:
archiver-utils: 5.0.2
async: 3.2.6 async: 3.2.6
buffer-crc32: 1.0.0 buffer-crc32: 1.0.0
is-stream: 4.0.1
lazystream: 1.0.1
normalize-path: 3.0.0
readable-stream: 4.7.0 readable-stream: 4.7.0
readdir-glob: 1.1.3 readdir-glob: 3.0.0
tar-stream: 3.2.0 tar-stream: 3.2.0
zip-stream: 6.0.1 zip-stream: 7.0.5
transitivePeerDependencies: transitivePeerDependencies:
- bare-abort-controller - bare-abort-controller
- bare-buffer - bare-buffer
@ -658,16 +492,16 @@ snapshots:
b4a@1.8.1: {} b4a@1.8.1: {}
balanced-match@1.0.2: {} balanced-match@4.0.4: {}
bare-events@2.8.2: {} bare-events@2.9.1: {}
bare-fs@4.7.1: bare-fs@4.7.2:
dependencies: dependencies:
bare-events: 2.8.2 bare-events: 2.9.1
bare-path: 3.0.0 bare-path: 3.0.1
bare-stream: 2.13.1(bare-events@2.8.2) bare-stream: 2.13.1(bare-events@2.9.1)
bare-url: 2.4.3 bare-url: 2.4.5
fast-fifo: 1.3.2 fast-fifo: 1.3.2
transitivePeerDependencies: transitivePeerDependencies:
- bare-abort-controller - bare-abort-controller
@ -675,30 +509,30 @@ snapshots:
bare-os@3.9.1: {} bare-os@3.9.1: {}
bare-path@3.0.0: bare-path@3.0.1:
dependencies: dependencies:
bare-os: 3.9.1 bare-os: 3.9.1
bare-stream@2.13.1(bare-events@2.8.2): bare-stream@2.13.1(bare-events@2.9.1):
dependencies: dependencies:
streamx: 2.25.0 streamx: 2.27.0
teex: 1.0.1 teex: 1.0.1
optionalDependencies: optionalDependencies:
bare-events: 2.8.2 bare-events: 2.9.1
transitivePeerDependencies: transitivePeerDependencies:
- react-native-b4a - react-native-b4a
bare-url@2.4.3: bare-url@2.4.5:
dependencies: dependencies:
bare-path: 3.0.0 bare-path: 3.0.1
base64-js@1.5.1: {} base64-js@1.5.1: {}
boolbase@1.0.0: {} boolbase@1.0.0: {}
brace-expansion@2.1.0: brace-expansion@5.0.6:
dependencies: dependencies:
balanced-match: 1.0.2 balanced-match: 4.0.4
buffer-crc32@1.0.0: {} buffer-crc32@1.0.0: {}
@ -711,19 +545,13 @@ snapshots:
bytes@3.1.2: {} bytes@3.1.2: {}
cluster-key-slot@1.1.2: {} cluster-key-slot@1.1.1: {}
color-convert@2.0.1: compress-commons@7.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.4: {}
compress-commons@6.0.2:
dependencies: dependencies:
crc-32: 1.2.2 crc-32: 1.2.2
crc32-stream: 6.0.0 crc32-stream: 7.0.1
is-stream: 2.0.1 is-stream: 4.0.1
normalize-path: 3.0.0 normalize-path: 3.0.0
readable-stream: 4.7.0 readable-stream: 4.7.0
@ -738,17 +566,11 @@ snapshots:
crc-32@1.2.2: {} crc-32@1.2.2: {}
crc32-stream@6.0.0: crc32-stream@7.0.1:
dependencies: dependencies:
crc-32: 1.2.2 crc-32: 1.2.2
readable-stream: 4.7.0 readable-stream: 4.7.0
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
css-select@5.2.2: css-select@5.2.2:
dependencies: dependencies:
boolbase: 1.0.0 boolbase: 1.0.0
@ -773,7 +595,7 @@ snapshots:
dependencies: dependencies:
css-tree: 2.2.1 css-tree: 2.2.1
date-fns@4.1.0: {} date-fns@4.4.0: {}
debug@4.4.3: debug@4.4.3:
dependencies: dependencies:
@ -801,19 +623,13 @@ snapshots:
domelementtype: 2.3.0 domelementtype: 2.3.0
domhandler: 5.0.3 domhandler: 5.0.3
eastasianwidth@0.2.0: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
entities@4.5.0: {} entities@4.5.0: {}
event-target-shim@5.0.1: {} event-target-shim@5.0.1: {}
events-universal@1.0.1: events-universal@1.0.1:
dependencies: dependencies:
bare-events: 2.8.2 bare-events: 2.9.1
transitivePeerDependencies: transitivePeerDependencies:
- bare-abort-controller - bare-abort-controller
@ -821,27 +637,11 @@ snapshots:
fast-fifo@1.3.2: {} fast-fifo@1.3.2: {}
foreground-child@3.3.1:
dependencies:
cross-spawn: 7.0.6
signal-exit: 4.1.0
fsevents@2.3.2: fsevents@2.3.2:
optional: true optional: true
generic-pool@3.9.0: {} generic-pool@3.9.0: {}
glob@10.5.0:
dependencies:
foreground-child: 3.3.1
jackspeak: 3.4.3
minimatch: 9.0.9
minipass: 7.1.3
package-json-from-dist: 1.0.1
path-scurry: 1.11.1
graceful-fs@4.2.11: {}
http-errors@2.0.1: http-errors@2.0.1:
dependencies: dependencies:
depd: 2.0.0 depd: 2.0.0
@ -860,34 +660,22 @@ snapshots:
inherits@2.0.4: {} inherits@2.0.4: {}
ioredis@5.10.1: ioredis@5.11.1:
dependencies: dependencies:
'@ioredis/commands': 1.5.1 '@ioredis/commands': 1.10.0
cluster-key-slot: 1.1.2 cluster-key-slot: 1.1.1
debug: 4.4.3 debug: 4.4.3
denque: 2.1.0 denque: 2.1.0
lodash.defaults: 4.2.0
lodash.isarguments: 3.1.0
redis-errors: 1.2.0 redis-errors: 1.2.0
redis-parser: 3.0.0 redis-parser: 3.0.0
standard-as-callback: 2.1.0 standard-as-callback: 2.1.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
is-fullwidth-code-point@3.0.0: {} is-stream@4.0.1: {}
is-stream@2.0.1: {}
isarray@1.0.0: {} isarray@1.0.0: {}
isexe@2.0.0: {}
jackspeak@3.4.3:
dependencies:
'@isaacs/cliui': 8.0.2
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
keygrip@1.1.0: keygrip@1.1.0:
dependencies: dependencies:
tsscmp: 1.0.6 tsscmp: 1.0.6
@ -896,27 +684,15 @@ snapshots:
dependencies: dependencies:
readable-stream: 2.3.8 readable-stream: 2.3.8
lodash.defaults@4.2.0: {}
lodash.isarguments@3.1.0: {}
lodash@4.17.21: {} lodash@4.17.21: {}
lru-cache@10.4.3: {}
mdn-data@2.0.28: {} mdn-data@2.0.28: {}
mdn-data@2.12.2: {} mdn-data@2.12.2: {}
minimatch@5.1.9: minimatch@10.2.5:
dependencies: dependencies:
brace-expansion: 2.1.0 brace-expansion: 5.0.6
minimatch@9.0.9:
dependencies:
brace-expansion: 2.1.0
minipass@7.1.3: {}
ms@2.1.3: {} ms@2.1.3: {}
@ -926,15 +702,6 @@ snapshots:
dependencies: dependencies:
boolbase: 1.0.0 boolbase: 1.0.0
package-json-from-dist@1.0.1: {}
path-key@3.1.1: {}
path-scurry@1.11.1:
dependencies:
lru-cache: 10.4.3
minipass: 7.1.3
playwright-core@1.60.0: {} playwright-core@1.60.0: {}
playwright@1.60.0: playwright@1.60.0:
@ -972,9 +739,9 @@ snapshots:
process: 0.11.10 process: 0.11.10
string_decoder: 1.3.0 string_decoder: 1.3.0
readdir-glob@1.1.3: readdir-glob@3.0.0:
dependencies: dependencies:
minimatch: 5.1.9 minimatch: 10.2.5
redis-errors@1.2.0: {} redis-errors@1.2.0: {}
@ -992,14 +759,6 @@ snapshots:
setprototypeof@1.2.0: {} setprototypeof@1.2.0: {}
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
shebang-regex@3.0.0: {}
signal-exit@4.1.0: {}
source-map-js@1.2.1: {} source-map-js@1.2.1: {}
source-map-support@0.5.21: source-map-support@0.5.21:
@ -1013,7 +772,7 @@ snapshots:
statuses@2.0.2: {} statuses@2.0.2: {}
streamx@2.25.0: streamx@2.27.0:
dependencies: dependencies:
events-universal: 1.0.1 events-universal: 1.0.1
fast-fifo: 1.3.2 fast-fifo: 1.3.2
@ -1022,18 +781,6 @@ snapshots:
- bare-abort-controller - bare-abort-controller
- react-native-b4a - react-native-b4a
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
string-width@5.1.2:
dependencies:
eastasianwidth: 0.2.0
emoji-regex: 9.2.2
strip-ansi: 7.2.0
string_decoder@1.1.1: string_decoder@1.1.1:
dependencies: dependencies:
safe-buffer: 5.1.2 safe-buffer: 5.1.2
@ -1042,14 +789,6 @@ snapshots:
dependencies: dependencies:
safe-buffer: 5.2.1 safe-buffer: 5.2.1
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
strip-ansi@7.2.0:
dependencies:
ansi-regex: 6.2.2
svgo@https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180: svgo@https://codeload.github.com/penpot/svgo/tar.gz/a46262c12c0d967708395972c374eb2adead4180:
dependencies: dependencies:
'@trysound/sax': 0.2.0 '@trysound/sax': 0.2.0
@ -1061,9 +800,9 @@ snapshots:
tar-stream@3.2.0: tar-stream@3.2.0:
dependencies: dependencies:
b4a: 1.8.1 b4a: 1.8.1
bare-fs: 4.7.1 bare-fs: 4.7.2
fast-fifo: 1.3.2 fast-fifo: 1.3.2
streamx: 2.25.0 streamx: 2.27.0
transitivePeerDependencies: transitivePeerDependencies:
- bare-abort-controller - bare-abort-controller
- bare-buffer - bare-buffer
@ -1071,7 +810,7 @@ snapshots:
teex@1.0.1: teex@1.0.1:
dependencies: dependencies:
streamx: 2.25.0 streamx: 2.27.0
transitivePeerDependencies: transitivePeerDependencies:
- bare-abort-controller - bare-abort-controller
- react-native-b4a - react-native-b4a
@ -1086,29 +825,13 @@ snapshots:
tsscmp@1.0.6: {} tsscmp@1.0.6: {}
undici@8.2.0: {} undici@8.4.1: {}
unpipe@1.0.0: {} unpipe@1.0.0: {}
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
which@2.0.2: ws@8.21.0: {}
dependencies:
isexe: 2.0.0
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@8.1.0:
dependencies:
ansi-styles: 6.2.3
string-width: 5.1.2
strip-ansi: 7.2.0
ws@8.20.1: {}
xml-js@1.6.11: xml-js@1.6.11:
dependencies: dependencies:
@ -1118,8 +841,8 @@ snapshots:
dependencies: dependencies:
'@babel/runtime-corejs3': 7.28.4 '@babel/runtime-corejs3': 7.28.4
zip-stream@6.0.1: zip-stream@7.0.5:
dependencies: dependencies:
archiver-utils: 5.0.2 compress-commons: 7.0.1
compress-commons: 6.0.2 normalize-path: 3.0.0
readable-stream: 4.7.0 readable-stream: 4.7.0

View File

@ -0,0 +1,2 @@
allowBuilds:
core-js-pure: false

View File

@ -7,7 +7,7 @@
(ns app.handlers.resources (ns app.handlers.resources
"Temporal resources management." "Temporal resources management."
(:require (:require
["archiver$default" :as arc] ["archiver" :as arc]
["node:fs" :as fs] ["node:fs" :as fs]
["node:fs/promises" :as fsp] ["node:fs/promises" :as fsp]
["node:path" :as path] ["node:path" :as path]
@ -41,7 +41,7 @@
(defn create-zip (defn create-zip
[& {:keys [resource on-complete on-progress on-error]}] [& {:keys [resource on-complete on-progress on-error]}]
(let [^js zip (arc/create "zip") (let [^js zip (new arc/ZipArchive)
^js out (fs/createWriteStream (:path resource)) ^js out (fs/createWriteStream (:path resource))
on-complete (or on-complete (constantly nil)) on-complete (or on-complete (constantly nil))
progress (atom 0)] progress (atom 0)]

View File

@ -4,7 +4,7 @@
"license": "MPL-2.0", "license": "MPL-2.0",
"author": "Kaleidos INC Sucursal en España SL", "author": "Kaleidos INC Sucursal en España SL",
"private": true, "private": true,
"packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268", "packageManager": "pnpm@11.5.3+sha512.7ac1c919341c213a34dc0d02afb7143c5c26ac26ee8c4782deea821b8ac64d2134a081fd8941dae6e29bbb48f58dfc2b7fbceeccc07cb2f09d219d342a4969ed",
"browserslist": [ "browserslist": [
"defaults" "defaults"
], ],
@ -17,8 +17,8 @@
"build:app:assets": "node ./scripts/build-app-assets.js", "build:app:assets": "node ./scripts/build-app-assets.js",
"build:storybook": "pnpm run build:storybook:assets && pnpm run build:storybook:cljs && storybook build", "build:storybook": "pnpm run build:storybook:assets && pnpm run build:storybook:cljs && storybook build",
"build:storybook:assets": "node ./scripts/build-storybook-assets.js", "build:storybook:assets": "node ./scripts/build-storybook-assets.js",
"build:wasm": "../render-wasm/build",
"build:storybook:cljs": "clojure -M:dev:shadow-cljs compile storybook", "build:storybook:cljs": "clojure -M:dev:shadow-cljs compile storybook",
"build:wasm": "../render-wasm/build",
"build:app:libs": "node ./scripts/build-libs.js", "build:app:libs": "node ./scripts/build-libs.js",
"build:app:main": "clojure -M:dev:shadow-cljs release main worker", "build:app:main": "clojure -M:dev:shadow-cljs release main worker",
"build:app:worker": "clojure -M:dev:shadow-cljs release worker", "build:app:worker": "clojure -M:dev:shadow-cljs release worker",
@ -46,34 +46,34 @@
"clear:wasm": "cargo clean --manifest-path ../render-wasm/Cargo.toml", "clear:wasm": "cargo clean --manifest-path ../render-wasm/Cargo.toml",
"watch": "exit 0", "watch": "exit 0",
"watch:app": "pnpm run clear:shadow-cache && pnpm run clear:wasm && pnpm run build:wasm && concurrently --kill-others-on-fail \"pnpm run watch:app:assets\" \"pnpm run watch:app:main\" \"pnpm run watch:app:libs\"", "watch:app": "pnpm run clear:shadow-cache && pnpm run clear:wasm && pnpm run build:wasm && concurrently --kill-others-on-fail \"pnpm run watch:app:assets\" \"pnpm run watch:app:main\" \"pnpm run watch:app:libs\"",
"watch:storybook": "pnpm run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 --no-open\" \"node ./scripts/watch-storybook.js\"", "watch:storybook": "pnpm run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 -h 0.0.0.0 --no-open\" \"node ./scripts/watch-storybook.js\"",
"postinstall": "(cd ../plugins/libs/plugins-runtime; pnpm install; pnpm run build)" "postinstall": "(cd ../plugins/libs/plugins-runtime; pnpm install; pnpm run build)"
}, },
"devDependencies": { "devDependencies": {
"@penpot/draft-js": "workspace:./packages/draft-js", "@penpot/draft-js": "link:packages/draft-js",
"@penpot/mousetrap": "workspace:./packages/mousetrap", "@penpot/mousetrap": "link:packages/mousetrap",
"@penpot/plugins-runtime": "link:../plugins/libs/plugins-runtime", "@penpot/plugins-runtime": "link:../plugins/libs/plugins-runtime",
"@penpot/svgo": "penpot/svgo#v3.2", "@penpot/svgo": "github:penpot/svgo#v3.2",
"@penpot/text-editor": "workspace:./text-editor", "@penpot/text-editor": "link:text-editor",
"@penpot/tokenscript": "workspace:./packages/tokenscript", "@penpot/tokenscript": "link:packages/tokenscript",
"@penpot/ui": "workspace:./packages/ui", "@penpot/ui": "link:packages/ui",
"@playwright/test": "1.60.0", "@playwright/test": "1.60.0",
"@storybook/addon-docs": "10.3.5", "@storybook/addon-docs": "10.4.3",
"@storybook/addon-themes": "10.3.5", "@storybook/addon-themes": "10.4.3",
"@storybook/addon-vitest": "10.3.5", "@storybook/addon-vitest": "10.4.3",
"@storybook/react-vite": "10.3.5", "@storybook/react-vite": "10.4.3",
"@tokens-studio/sd-transforms": "1.2.11", "@tokens-studio/sd-transforms": "2.0.3",
"@types/node": "^25.5.2", "@types/node": "^25.9.2",
"@vitest/browser": "4.1.3", "@vitest/browser": "4.1.8",
"@vitest/browser-playwright": "^4.1.3", "@vitest/browser-playwright": "^4.1.8",
"@vitest/coverage-v8": "4.1.3", "@vitest/coverage-v8": "4.1.8",
"@zip.js/zip.js": "2.8.26", "@zip.js/zip.js": "2.8.26",
"autoprefixer": "^10.4.27", "autoprefixer": "^10.4.27",
"compression": "^1.8.1", "compression": "^1.8.1",
"concurrently": "^9.2.1", "concurrently": "^10.0.3",
"date-fns": "^4.1.0", "date-fns": "^4.4.0",
"esbuild": "^0.28.0", "esbuild": "^0.28.0",
"eventsource-parser": "^3.0.8", "eventsource-parser": "^3.1.0",
"express": "^5.1.0", "express": "^5.1.0",
"fancy-log": "^2.0.0", "fancy-log": "^2.0.0",
"getopts": "^2.3.0", "getopts": "^2.3.0",
@ -84,48 +84,47 @@
"lodash": "^4.18.1", "lodash": "^4.18.1",
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"map-stream": "0.0.7", "map-stream": "0.0.7",
"marked": "^17.0.5", "marked": "^18.0.5",
"mkdirp": "^3.0.1", "mkdirp": "^3.0.1",
"mustache": "^4.2.0", "mustache": "^4.2.0",
"nodemon": "^3.1.14", "nodemon": "^3.1.14",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"opentype.js": "^1.3.4", "opentype.js": "^2.0.0",
"p-limit": "^7.3.0", "p-limit": "^7.3.0",
"playwright": "1.60.0", "playwright": "1.60.0",
"postcss": "^8.5.8", "postcss": "^8.5.15",
"postcss-clean": "^1.2.2", "postcss-clean": "^1.2.2",
"postcss-modules": "^6.0.1", "postcss-modules": "^6.0.1",
"postcss-scss": "^4.0.9", "postcss-scss": "^4.0.9",
"prettier": "3.8.1", "prettier": "3.8.4",
"pretty-time": "^1.1.0", "pretty-time": "^1.1.0",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"randomcolor": "^0.6.2", "randomcolor": "^0.6.2",
"react": "19.2.4", "react": "19.2.7",
"react-dom": "19.2.4", "react-dom": "19.2.7",
"react-error-boundary": "^6.1.1", "react-error-boundary": "^6.1.2",
"react-virtualized": "^9.22.6", "react-virtualized": "^9.22.6",
"rimraf": "^6.1.3", "rimraf": "^6.1.3",
"rxjs": "8.0.0-alpha.14", "rxjs": "8.0.0-alpha.14",
"sass": "^1.98.0", "sass": "^1.100.0",
"sass-embedded": "^1.98.0", "sass-embedded": "^1.100.0",
"sax": "^1.4.1", "sax": "^1.6.0",
"scheduler": "^0.27.0", "scheduler": "^0.27.0",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"storybook": "10.3.5", "storybook": "10.4.3",
"style-dictionary": "5.0.0-rc.1", "style-dictionary": "5.4.4",
"stylelint": "^17.4.0", "stylelint": "^17.13.0",
"stylelint-config-standard-scss": "^17.0.0", "stylelint-config-standard-scss": "^17.0.0",
"stylelint-scss": "^7.0.0", "stylelint-scss": "^7.2.0",
"stylelint-use-logical-spec": "^5.0.1", "stylelint-use-logical-spec": "^5.0.1",
"svg-sprite": "^2.0.4", "svg-sprite": "^2.0.4",
"tdigest": "^0.1.2", "tdigest": "^0.1.2",
"tinycolor2": "^1.6.0", "tinycolor2": "^1.6.0",
"typescript": "^6.0.2", "typescript": "^6.0.2",
"ua-parser-js": "2.0.9", "ua-parser-js": "2.0.10",
"vite": "^8.0.7", "vite": "^8.0.16",
"vitest": "^4.1.3", "vitest": "^4.1.8",
"wait-on": "^9.0.4", "wait-on": "^9.0.4",
"wasm-pack": "^0.13.1",
"watcher": "^2.3.1", "watcher": "^2.3.1",
"workerpool": "^10.0.1", "workerpool": "^10.0.1",
"xregexp": "^5.1.2" "xregexp": "^5.1.2"

View File

@ -9,7 +9,7 @@
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"draft-js": "penpot/draft-js.git#4a99b2a6020b2af97f6dc5fa1b4275ec16b559a0", "draft-js": "penpot/draft-js.git#4a99b2a6020b2af97f6dc5fa1b4275ec16b559a0",
"immutable": "^5.1.4" "immutable": "^5.1.6"
}, },
"peerDependencies": { "peerDependencies": {
"react": ">=0.17.0", "react": ">=0.17.0",

4401
frontend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -9,3 +9,11 @@ patchedDependencies:
'@zip.js/zip.js@2.8.26': patches/@zip.js__zip.js@2.8.26.patch '@zip.js/zip.js@2.8.26': patches/@zip.js__zip.js@2.8.26.patch
shamefullyHoist: true shamefullyHoist: true
minimumReleaseAge: 0
allowBuilds:
'@parcel/watcher': true
canvas: true
core-js-pure: true
esbuild: true

View File

@ -37,7 +37,7 @@
} }
.main-toolbar-hidden { .main-toolbar-hidden {
--toolbar-offset-y: -#{deprecated.$s-4}; --toolbar-offset-y: calc(-1 * #{deprecated.$s-4});
height: deprecated.$s-16; height: deprecated.$s-16;
z-index: deprecated.$z-index-1; z-index: deprecated.$z-index-1;

View File

@ -321,8 +321,16 @@
(filter #(or (root-frame-with-data? %) (filter #(or (root-frame-with-data? %)
(and (cfh/group-shape? objects %) (and (cfh/group-shape? objects %)
(not (contains? child-parent? %))) (not (contains? child-parent? %)))
;; WASM only: drop text from @hover unless the
;; cursor is over rendered glyphs, so clicks
;; pass through empty areas of the text box.
;; Skip this for shapes already in `selected`:
;; @hover drives on-click, and the first click
;; of a double-click would otherwise reselect
;; a parent/container after the pointer moves.
(and (features/active-feature? @st/state "render-wasm/v1") (and (features/active-feature? @st/state "render-wasm/v1")
(cfh/text-shape? (get objects %)) (cfh/text-shape? (get objects %))
(not (contains? selected %))
(not (wasm.api/intersect-position-in-shape % @last-point-ref))))))) (not (wasm.api/intersect-position-in-shape % @last-point-ref)))))))
remove-measure-xf remove-measure-xf

View File

@ -100,6 +100,7 @@
matching-font (some (fn [[_ font]] matching-font (some (fn [[_ font]]
(and (= (:font-id font) font-uuid) (and (= (:font-id font) font-uuid)
(= (str (:font-weight font)) (str font-weight)) (= (str (:font-weight font)) (str font-weight))
(= (:font-style font) font-style)
font)) font))
(seq @fonts))] (seq @fonts))]
(when matching-font (when matching-font

View File

@ -15,18 +15,18 @@
"test:watch:e2e": "vitest --browser" "test:watch:e2e": "vitest --browser"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.45.1", "@playwright/test": "^1.60.0",
"@types/node": "^25.0.3", "@types/node": "^25.9.2",
"@vitest/browser": "^1.6.0", "@vitest/browser": "^4.1.8",
"@vitest/coverage-v8": "^1.6.0", "@vitest/coverage-v8": "^4.1.8",
"@vitest/ui": "^1.6.0", "@vitest/ui": "^4.1.8",
"esbuild": "^0.27.2", "canvas": "^3.2.3",
"jsdom": "^27.4.0", "esbuild": "^0.28.0",
"canvas": "^3.2.1", "jsdom": "^29.1.1",
"playwright": "^1.45.1", "playwright": "^1.60.0",
"prettier": "^3.7.4", "prettier": "^3.8.4",
"vite": "^5.3.1", "vite": "^8.0.16",
"vitest": "^1.6.0" "vitest": "^4.1.8"
}, },
"packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268" "packageManager": "pnpm@11.5.3+sha512.7ac1c919341c213a34dc0d02afb7143c5c26ac26ee8c4782deea821b8ac64d2134a081fd8941dae6e29bbb48f58dfc2b7fbceeccc07cb2f09d219d342a4969ed"
} }

View File

@ -17,14 +17,22 @@ describe("Style", () => {
test("setStyles should apply multiple styles to an element using an Object", () => { test("setStyles should apply multiple styles to an element using an Object", () => {
const element = document.createElement("div"); const element = document.createElement("div");
setStyles(element, [["display"]], { setStyles(
"text-decoration": "none", element,
"font-size": "32px", [
display: "none", ["display"],
}); ["font-size", "px"],
expect(element.style.display).toBe(""); ["text-decoration"],
expect(element.style.fontSize).toBe(""); ],
expect(element.style.textDecoration).toBe(""); {
"text-decoration": "none",
"font-size": "32",
display: "none",
},
);
expect(element.style.display).toBe("none");
expect(element.style.fontSize).toBe("32px");
expect(element.style.textDecoration).toBe("none");
}); });
test("setStyles should apply multiple styles to an element using a CSSStyleDeclaration", () => { test("setStyles should apply multiple styles to an element using a CSSStyleDeclaration", () => {
@ -32,13 +40,13 @@ describe("Style", () => {
setStyles(a, [["display"]], { setStyles(a, [["display"]], {
display: "none", display: "none",
}); });
expect(a.style.display).toBe(""); expect(a.style.display).toBe("none");
expect(a.style.fontSize).toBe(""); expect(a.style.fontSize).toBe("");
expect(a.style.textDecoration).toBe(""); expect(a.style.textDecoration).toBe("");
const b = document.createElement("div"); const b = document.createElement("div");
setStyles(b, [["display"]], a.style); setStyles(b, [["display"]], a.style);
expect(b.style.display).toBe(""); expect(b.style.display).toBe("none");
expect(b.style.fontSize).toBe(""); expect(b.style.fontSize).toBe("");
expect(b.style.textDecoration).toBe(""); expect(b.style.textDecoration).toBe("");
}); });

View File

@ -2,6 +2,7 @@ import path from "node:path";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import { coverageConfigDefaults } from "vitest/config"; import { coverageConfigDefaults } from "vitest/config";
import { playwright } from "@vitest/browser-playwright";
async function waitFor(timeInMillis) { async function waitFor(timeInMillis) {
return new Promise((resolve) => setTimeout((_) => resolve(), timeInMillis)); return new Promise((resolve) => setTimeout((_) => resolve(), timeInMillis));
@ -69,11 +70,7 @@ export default defineConfig({
enabled: true, enabled: true,
exclude: ["main.js", "**/scripts/**", ...coverageConfigDefaults.exclude], exclude: ["main.js", "**/scripts/**", ...coverageConfigDefaults.exclude],
}, },
poolOptions: { singleThread: true,
threads: {
singleThread: true,
},
},
environmentOptions: { environmentOptions: {
jsdom: { jsdom: {
resources: "usable", resources: "usable",
@ -81,7 +78,7 @@ export default defineConfig({
}, },
browser: { browser: {
name: "chromium", name: "chromium",
provider: "playwright", provider: playwright(),
}, },
exclude: ["main.js", "**/scripts/**", "**/node_modules/**", "**/dist/**"], exclude: ["main.js", "**/scripts/**", "**/node_modules/**", "**/dist/**"],
}, },

View File

@ -343,6 +343,13 @@ def cmd_issues(args: argparse.Namespace) -> None:
print(f"After excluding labels: {len(filtered)} issues", file=sys.stderr) print(f"After excluding labels: {len(filtered)} issues", file=sys.stderr)
issues = filtered issues = filtered
# Exclude issues with type "Task" (internal chores) — opt out with --include-tasks
if not args.include_tasks:
tasks = [iss for iss in issues if iss.get("issue_type") == "Task"]
if tasks:
issues = [iss for iss in issues if iss.get("issue_type") != "Task"]
print(f"After excluding Task issues: {len(issues)} issues (removed {len(tasks)}: {[t['number'] for t in tasks]})", file=sys.stderr)
# Filter by included labels (--label) — issue must have ALL specified labels # Filter by included labels (--label) — issue must have ALL specified labels
if args.label: if args.label:
inclusions = set(label.strip() for label in args.label.split(",")) inclusions = set(label.strip() for label in args.label.split(","))
@ -608,6 +615,10 @@ def main() -> None:
"--include-rejected", action="store_true", "--include-rejected", action="store_true",
help="Include issues with 'Rejected' project status (excluded by default)" help="Include issues with 'Rejected' project status (excluded by default)"
) )
p_issues.add_argument(
"--include-tasks", action="store_true",
help="Include issues with type 'Task' (excluded by default, they are internal chores)"
)
p_issues.set_defaults(func=cmd_issues) p_issues.set_defaults(func=cmd_issues)
# --- prs --- # --- prs ---